Jack Crook tweeted last month about a memory analysis challenge he put together:
Here's a memory dump related to a webserver compromise I put together a few months ago. Enjoy. #DFIR https://t.co/EfwTiJriLT
— Jack Crook (@jackcr) September 26, 2015
I had prior access to this image and originally put all my analysis findings in a Word document. I finally got around to transferring it to my blog. I apologize for any formatting errors - it's a pain to transfer well-formatted word processing documents to a blog post.Introduction
The investigation of this host was initiated based on a Windows
batch file being created in the C:\Windows directory. This host was at IP address 192.168.56.30; any IP addresses not on the 192.168.56.x
network are considered external to this host.
Summary
On 6/11/2015, an attacker at IP address 58.64.141.245 connected to the Apache Tomcat server on this host and logged in
with default Tomcat credentials. The attacker then uploaded a web shell to the
server that gave him the ability to execute system commands and upload
additional files with Tomcat’s SYSTEM level access. The attacker uploaded the Windows Credential
Editor (WCE) tool and a Windows batch file, then created a Windows scheduled
task to execute the batch file, which in turn executed WCE. Credentials for a
single administrator account were dumped to a file on the server in a web-accessible
directory, and the attacker retrieved this file via an HTTP GET request. No
lateral movement to other internal machines was identified, so it is believed
this web server was the only machine compromised in this attack. All attacker
activity took place on 6/11/2015.
Technical Details
Image
md5 hash
$ md5sum
WIN-CEKM08E74HR-20150611-222930.raw
17754bc58dffa7d2887af8ddfae40698
Volatility imageinfo output
$ vol.py –f WIN-CEKM08E74HR-20150611-222930.raw
imaginfo
Determining profile based on
KDBG search...
Suggested Profile(s) : VistaSP1x86,
Win2008SP1x86, Win2008SP2x86, VistaSP2x86
AS Layer1 :
IA32PagedMemory (Kernel AS)
AS Layer2 :
FileAddressSpace (/lr/users/mgregory/WIN-CEKM08E74HR-20150611-222930.raw)
PAE type : No PAE
DTB : 0x122000L
KDBG : 0x8190ac98
Number of Processors : 1
Image Type (Service Pack) : 2
KPCR for CPU 0 : 0x8190b800
KUSER_SHARED_DATA : 0xffdf0000
Image date and time : 2015-06-11
22:29:32 UTC+0000
Image local date and time : 2015-06-11
18:29:32 -0400
Attacker Activity
Initial access.
Based on Apache access logs found in memory strings, the
attacker first accessed the web server on June 8th at 18:08:45 and last
accessed it on June 11th at 18:27:51:
$ grep -C10
"58\.64\.141\.245" strings
<…snip…>
346077722 58.64.141.245 - - [08/Jun/2015:19:38:12 -0400]
"GET /webfiles/ HTTP/1.1" 404 969
<…snip…>
210019860 58.64.141.245 - - [11/Jun/2015:18:27:51 -0400]
"GET /webfiles/?sort=1&downfile=C%3A%5Cinetpub%5Cwwwroot%5Csm.gif
HTTP/1.1" 200 97
<…snip…>
However, the attacker still may have accessed the web server
before or after these times since these logs were resident in memory and may
not reflect all logs or system activity.
It appears the attacker obtained initial access by logging into
a web-facing Apache Tomcat portal with default Tomcat credentials:
525512804 Accept: */*
525512817 Referer:
http://192.168.56.30:8080/webfiles/?sort=1&dir=C%3A%5C
525512882 Accept-Language:
en-us
525512906 User-Agent:
Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)
525512983 Accept-Encoding:
gzip, deflate
525513015 Host:
192.168.56.30:8080
525513041 Connection:
Keep-Alive
525513065 Cookie:
JSESSIONID=D4BB0A17D08FE321DF87835231D79824
525513123 \nection:
Keep-Alive
525513145 Cookie:
JSESSIONID=9E2D9B938AD0C27816C03A5CA54F9515
525513198 Authorization:
Basic dG9tY2F0OnRvbWNhdA==
The highlighted base64 encoded data in the above HTTP header
decodes to the default Tomcat credentials of tomcat:tomcat:
$ echo
"dG9tY2F0OnRvbWNhdA==" | base64 -d
tomcat:tomcat
Web shell uploaded.
Next, the
attacker uploaded a web shell called “jsp File Browser version 1.2”, likely via
the Tomcat interface. Fragments of the web shell are resident in memory as seen
below, where you can identify specific commands being executed, such as "dir" and "sort":
$ egrep -i -C20 "jsp
file browser" strings.sorted
<…snip…>
196513988 out.write("\t\t<input
type=\"hidden\" name=\"sort\" value=\"");
196514130 out.print(sortMode);
196514186 out.write("\">\n");
196514240 out.write("\t\t<input
type=\"hidden\" name=\"command\"
value=\"\">\n");
196514398
out.write("\t\t<input title=\"Launch command in current
directory\" type=\"Submit\" class=\"button\"
id=\"but_Lau\" name=\"Submit\" value=\"");
196514700
out.print(LAUNCH_COMMAND);
<…snip…>
196515250
out.write("\t\t<small>jsp File Browser version ");
196515366 out.print(
VERSION_NR);
196515428 out.write("
by <a
href=\"http://www.vonloesch.de\">www.vonloesch.de</a></small>\n");
196515612
out.write("\t</center>\n");
196515682 out.write("</body>\n");
196515744 out.write("</html>");
<…snip…>
--
<…snip…>
517899879
<body><center>
517899894 <h2>(L)aunch external program</h2><br />
517899935 <form action="/webfiles/"
method="Post">
517899976 <textarea
name="text" wrap="off" cols="85"
rows="30" readonly>
517900040 06:25 PM
517900052 </textarea>
517900064 <input
type="hidden" name="dir"
value="C:\inetpub\wwwroot">
517900125 <br /><br />
517900139 <table class="formular">
517900165 <tr><td
title="Enter your command">
517900202 Command: <input size="80"
type="text" name="command" value="">
517900266 </td></tr>
517900278 <tr><td><input
class="button" type="Submit" name="Submit"
value="Launch">
517900353 <input type="hidden"
name="sort" value="1">
517900398 <input type="Submit"
class="button" name="Submit"
value="Cancel"></td></tr>
517900475 </table>
517900485 </form>
517900494 <br />
517900502 <hr>
517900508 <center>
517900518 <small>jsp
File Browser version 1.2 by <a
href="http://www.vonloesch.de">www.vonloesch.de</a></small>
517900622 </center>
517900633 </center>
517900644 </body>
517900652 </html>
517900660 /html>
517900670 <input
type="file" class="textfield"
onKeypress="event.cancelBubble=true;" name="myFile">
517900762 <input
title="Upload selected file to the current working directory"
type="Submit" class="button" name="Submit"
value="Upload"
517900891 onClick="javascript:popUp('/webfiles/')">
517900935 </form>
517900948 <form
class="formular2" action="/webfiles/"
method="POST">
517901011 <input
type="hidden" name="dir" value="C:\Windows">
517901065 <input
type="hidden" name="sort" value="1">
517901111 <input
type="hidden" name="command" value="">
517901159 <input
title="Launch command in current directory" type="Submit"
class="button" id="but_Lau" name="Submit"
value="(L)aunch external program">
517901303 </form>
517901312 </div>
This web shell is available at http://www.vonloesch.de/node/31 and has a default file name of
“Browser.jsp”; however, the Volatility filescan plugin did not detect this
file, and it was not located in the MFT. As seen below, this file name was
resident in memory as a string that is also found in the web shell downloaded
from the above link, but only in reference to code within the JSP file itself
and not actually designating a file:
$ grep –i
“browser\.jsp” strings.sorted
61628190 *
@param browserLink web-path to Browser.jsp
63058164 //If this dir
also do also not exist, go back to browser.jsp root path
<…snip…>
Strings output and the MFT listing show a number of other JSP files in
the Program Files\Apache Software Foundation\Tomcat
7.0\webapps\webfiles\ directory; however, none of these files were
resident in memory so they could not be dumped to see if the attacker simply
renamed the web shell. Later HTTP access from the attacker’s IP address to the webfiles directory further indicates this is the
location of his web shell. Pivoting off this directory in strings output and
the MFT identified a Java Web Application Archive (.war) being deployed on the server at
approximately 18:07 (22:07 UTC):
$ grep -i "webfiles" strings.sorted
<…snip…>
99623387 INFO: Deploying web application archive C:\Program Files\Apache
Software Foundation\Tomcat 7.0\webapps\webfiles.war
99623578 INFO: Deployment of web application archive C:\Program
Files\Apache Software Foundation\Tomcat 7.0\webapps\webfiles.war has finished
in 190 ms
<…snip…>
$ grep -i "webfiles" mactimeline.csv
<…snip…>
Thu Jun 11 2015 22:07:04,368,macb,---a-----------,0,0,48015,"[MFT
FILE_NAME] Program Files\Apache Software Foundation\Tomcat
7.0\webapps\webfiles.war (Offset: 0x286c00)"
Thu Jun 11 2015 22:07:04,368,macb,---a-----------,0,0,48015,"[MFT
STD_INFO] Program Files\Apache Software Foundation\Tomcat
7.0\webapps\webfiles.war (Offset: 0x286c00)"
<…snip…>
Based on this information, it is possible, if not likely, the attacker
deployed the web shell via webfiles.war, which in turn was probably uploaded via the Apache Tomcat interface.
Batch file created.
A file
named 12.bat was created in C:\Windows on 20150611 at 18:12 (22:12 UTC):
$ grep "12.bat"
mactimeline.csv
Thu Jun 11 2015
22:12:16,288,macb,---a-----------,0,0,47995,"[MFT FILE_NAME]
Windows\12.bat (Offset: 0x11089650)"
Thu Jun 11 2015
22:12:16,360,macb,---a-----------,0,0,47995,"[MFT FILE_NAME]
Windows\12.bat (Offset: 0x11d06c00)"
Thu Jun 11 2015
22:12:16,288,macb,---a-----------,0,0,47995,"[MFT STD_INFO] Windows\12.bat
(Offset: 0x11089650)"
Thu Jun 11 2015
22:12:16,360,macb,---a-----------,0,0,47995,"[MFT STD_INFO] Windows\12.bat
(Offset: 0x11d06c00)"
The file 12.bat was located in memory and executes a command line utility when
executed:
# Find 12.bat physical offset
with filescan plugin
$ vol.py –f WIN-CEKM08E74HR-20150611-222930.raw
filescan | grep "12.bat"
<…snip…>
0x1ee373f8 8
0 -W-rw- \Device\HarddiskVolume1\Windows\12.bat
# Dump 12.bat with dumpfiles
plugin using physical offset
$ vol.py -f
WIN-CEKM08E74HR-20150611-222930.raw dumpfiles -Q 0x1ee373f8 -D .
Volatility Foundation
Volatility Framework 2.3.1
DataSectionObject
0x1ee373f8 None \Device\HarddiskVolume1\Windows\12.bat
# get 12.bat hash
$ md5sum
file.None.0x8362e730.dat
38f76497a613a14a7600695300e12ce1 file.None.0x8362e730.dat
# View contents of 12.bat
$ cat
file.None.0x8362e730.dat
@echo off
c:\inetpub\wwwroot\bg.jpg -e
-o c:\inetpub\wwwroot\sm.gif
As seen above, the 12.bat batch file
executes a file located in the web server’s web-accessible directory named bg.jpg, followed by command line parameters –e and –o, and finally a path to a file named sm.gif in the same
directory. At one point it looks like the attacker checked for the presence of
this file before later possibly uploading it via a POST:
$ egrep -i -C20
"12\.bat" strings.sorted
9901378 58.64.141.245 - -
[11/Jun/2015:18:12:16 -0400] "GET
/webfiles/?first&uplMonitor=C%3A%5Cfakepath%5C12.bat HTTP/1.1" 200 865
Scheduled task created.
The fact
that bg.jpg was launched as a scheduled task is further indicated by the
fact bg.jpg is a child process of cmd.exe, which in
turn is a child process of taskeng.exe (see pstree output
above). The scheduled task (At job) was resident in memory:
# the highlighted “0” exit
code indicates the command was successful
$ vol.py -f
WIN-CEKM08E74HR-20150611-222930.raw filescan | grep -i "At1.job"
Volatility Foundation
Volatility Framework 2.3.1
0x1f297ad8 8
0 -W-r-d
\Device\HarddiskVolume1\Windows\Tasks\At1.job
$ vol.py -f
WIN-CEKM08E74HR-20150611-222930.raw dumpfiles -Q 0x1f297ad8 -D .
Volatility Foundation
Volatility Framework 2.3.1
DataSectionObject
0x1f297ad8 None
\Device\HarddiskVolume1\Windows\Tasks\At1.job
$ strings -el
file.None.0x8363fd10.dat
c:\windows\12.bat
SYSTEM
Created by NetScheduleJobAdd.
Strings ouput of At1.job (file.None.0x8363fd10.dat) shows that this scheduled task is set to execute the 12.bat file with SYSTEM credentials, which in turn executes bg.jpg (WCE). Windows Task Scheduler errored out when trying to open
this At job to view the actual time the job was scheduled to run, although
further metadata could possibly be parsed with a script written to interpret
the file format (I tried Harlan Carvey’s jobparse.pl script, but
that too had errors and was unsuccessful). This shows how the attacker was able
to execute bg.jpg. It’s not entirely clear how the attacker was able to run
tasking.exe or at.exe to create the At job in the first place, but it was likely
via system command execution either via the Tomcat interface or the attacker’s
web shell. There were no at.exe command line arguments found.
The Windows Task Scheduler log (Schedlgu.txt) was also resident in memory; however, it
contained no record of executing 12.bat or bg.jpg:
$ vol.py -f
WIN-CEKM08E74HR-20150611-222930.raw filescan | grep -i "schedlgu.txt"
Volatility Foundation
Volatility Framework 2.3.1
0x1f22da78 10
1 RW-r-- \Device\HarddiskVolume1\Windows\Tasks\SCHEDLGU.TXT
$ vol.py -f
WIN-CEKM08E74HR-20150611-222930.raw dumpfiles -Q 0x1f22da78 -D .
Volatility Foundation
Volatility Framework 2.3.1
DataSectionObject
0x1f22da78 None \Device\HarddiskVolume1\Windows\Tasks\SCHEDLGU.TXT
SharedCacheMap
0x1f22da78 None
\Device\HarddiskVolume1\Windows\Tasks\SCHEDLGU.TXT
$ cat
file.None.0x8322d7e0.dat | grep -i "bg\.jpg|12\.bat"
<no_output>
Credentials dumped.
The file bg.jpg is a running process based on pstree output. It
was executed with the same command line arguments found in 12.bat:
$ vol.py -f
WIN-CEKM08E74HR-20150611-222930.raw pstree -v | grep -C10 bg\.jpg
<---snip--->
..... 0x8362fca0:bg.jpg 3580 3572
1 61 2015-06-11 22:25:00
UTC+0000
audit:
\Device\HarddiskVolume1\inetpub\wwwroot\bg.jpg
cmd: c:\inetpub\wwwroot\bg.jpg -e -o c:\inetpub\wwwroot\sm.gif
path: c:\inetpub\wwwroot\bg.jpg
bg.jpg was also located in memory and is actually the Windows
Credential Editor (WCE) tool:
# find bg.jpg physical offset
$ vol.py -f
WIN-CEKM08E74HR-20150611-222930.raw filescan | grep "bg.jpg"
Volatility Foundation
Volatility Framework 2.3.1
0x1ede1ba0 8
0 -W-rw- \Device\HarddiskVolume1\inetpub\wwwroot\bg.jpg
0x1f2dc170 7
0 R--r-d \Device\HarddiskVolume1\inetpub\wwwroot\bg.jpg
# dump bg.jpg using physical
offset
$ vol.py -f
WIN-CEKM08E74HR-20150611-222930.raw dumpfiles -Q 0x1f2dc170 -D .
Volatility Foundation
Volatility Framework 2.3.1
ImageSectionObject
0x1f2dc170 None
\Device\HarddiskVolume1\inetpub\wwwroot\bg.jpg
DataSectionObject
0x1f2dc170 None
\Device\HarddiskVolume1\inetpub\wwwroot\bg.jpg
# verify file type
$ file file.None.0x8362fb20.img
file.None.0x8362fb20.img:
PE32 executable (console) Intel 80386, for MS Windows
# get md5 hash of file
$ md5sum
file.None.0x8362fb20.img
0bfb070177356c0905f013416aba1af1 file.None.0x8362fb20.img
# strings in file indicate
this is the WCE tool
$ strings file.None.0x8362fb20.img
<…snip…>
%.2X
something terrible happened!
could not allocate memory for new list!
WCE %s (Windows Credentials Editor) - (c) 2010,2011,2012 Amplia
Security - by Hernan Ochoa (hernan@ampliasecurity.com)
Use -h for help.
Options:
-l
List logon sessions and NTLM credentials (default).
Optional: -r<refresh
interval>.
-s Changes NTLM credentials of
current logon session.
Parameters:
<UserName>:<DomainName>:<LMHash>:<NTHash>.
-o
saves all output to a file.
bg.jpg can also be seen in the running processes:
$ vol.py –f WIN-CEKM08E74HR-20150611-222930.raw
pstree
.
0x83139650:services.exe
596 520
6 234 2015-06-11 22:05:29
UTC+0000
<---snip--->
..
0x831bb8b8:svchost.exe 876 596
7 244 2015-06-11 22:05:39 UTC+0000
..
0x831e5820:svchost.exe 1012 596
30 781 2015-06-11 22:05:40
UTC+0000
...
0x82a3f530:taskeng.exe
2448 1012 9
226 2015-06-11 22:27:17 UTC+0000
...
0x83116ad8:wuauclt.exe
3360 1012 2
142 2015-06-11 22:27:32 UTC+0000
... 0x835913b8:taskeng.exe 2032 1012
6 141 2015-06-11 22:05:59
UTC+0000
.... 0x830e9d90:cmd.exe 3572 2032
1 17 2015-06-11 22:25:00 UTC+0000
..... 0x8362fca0:bg.jpg 3580
3572 1 61 2015-06-11 22:25:00 UTC+0000
Although it is apparent based on strings and command line
parameters that the file bg.jpg is the WCE tool, the file’s md5 hash was not found in
VirusTotal or via a Google search. Based on the WCE documentation, the command
line options used to execute bg.jpg were to continuously dump NTLM credentials
(-e option) and to save the dump file to c:\inetpub\wwwroot\sm.gif (-o option).
Dumped credentials retrieved.
The
attacker connected to the web server from IP address 58.64.141.245 and retrieved the dumped credentials (sm.gif) via a GET request, as shown in the below Apache log:
210018644 58.64.141.245 - -
[11/Jun/2015:18:27:51 -0400] "GET /webfiles/?sort=1&downfile=C%3A%5Cinetpub%5Cwwwroot%5Csm.gif
HTTP/1.1" 200
Based on the MFT, the first and only access of the file bg.jpg occurred on 20150611 at 18:09 (22:09 UTC):
$ vol.py egrep -i -C10
"bg.jpg" mactimeline.csv
<…snip…>
Thu Jun 11 2015
22:09:26,360,macb,---a-----------,0,0,48038,"[MFT FILE_NAME]
inetpub\wwwroot\bg.jpg (Offset: 0x136fa800)"
Thu Jun 11 2015
22:09:26,360,macb,---a-----------,0,0,48038,"[MFT FILE_NAME]
inetpub\wwwroot\bg.jpg (Offset: 0x1ef2d800)"
Thu Jun 11 2015
22:09:26,360,macb,---a-----------,0,0,48038,"[MFT STD_INFO]
inetpub\wwwroot\bg.jpg (Offset: 0x136fa800)"
Thu Jun 11 2015 22:09:26,360,macb,---a-----------,0,0,48038,"[MFT
STD_INFO] inetpub\wwwroot\bg.jpg (Offset: 0x1ef2d800)"
Thu Jun 11 2015
22:09:55,344,m.c.,---a-----------,0,0,30461,"[MFT STD_INFO]
Windows\System32\spool\spooler.xml (Offset: 0x2d66400)"
<…snip…>
This correlates to Apache logs showing this file being accessed at
18:09, which appears to be the file being uploaded via a POST request to /webfiles followed by an immediate download via a GET request, likely to
verify the upload was successful, which it was as indicated by the 200 response
code:
$ egrep -i -C20
"GET|POST" strings.sorted | egrep -i -C10 "bg.jpg"
9900047 58.64.141.245 - -
[11/Jun/2015:18:08:41 -0400] "GET /webfiles/?Javascript HTTP/1.1" 200
3714
9900141 58.64.141.245 - -
[11/Jun/2015:18:08:45 -0400] "GET /webfiles/?sort=1&dir=C%3A%5Cinetpub
HTTP/1.1" 200 8270
9900250 58.64.141.245 - -
[11/Jun/2015:18:08:45 -0400] "GET /webfiles/?Javascript HTTP/1.1" 200
3714
9900344 58.64.141.245 - -
[11/Jun/2015:18:08:50 -0400] "GET
/webfiles/?sort=1&dir=C%3A%5Cinetpub%5Cwwwroot HTTP/1.1" 200 8098
9900463 58.64.141.245 - -
[11/Jun/2015:18:08:50 -0400] "GET /webfiles/?Javascript HTTP/1.1" 200
3714
9900681 58.64.141.245 - - [11/Jun/2015:18:09:26 -0400] "POST
/webfiles/ HTTP/1.1" 200 8973
9900557 58.64.141.245 - - [11/Jun/2015:18:09:26 -0400] "GET
/webfiles/?first&uplMonitor=C%3A%5Cfakepath%5Cbg.jpg HTTP/1.1" 200 865
9900681 58.64.141.245 - -
[11/Jun/2015:18:09:26 -0400] "POST /webfiles/ HTTP/1.1" 200 8973
9900765 58.64.141.245 - -
[11/Jun/2015:18:09:26 -0400] "GET /webfiles/?Javascript HTTP/1.1" 200
3714
9900859 58.64.141.245 - -
[11/Jun/2015:18:09:28 -0400] "GET
/webfiles/?uplMonitor=C%3A%5Cfakepath%5Cbg.jpg HTTP/1.1" 200 574
9900977 58.64.141.245 - -
[11/Jun/2015:18:11:59 -0400] "GET /webfiles/?sort=1&dir=C%3A%5C
HTTP/1.1" 200 13384
9901080 58.64.141.245 - -
[11/Jun/2015:18:11:59 -0400] "GET /webfiles/?Javascript HTTP/1.1" 200
3714
9901174 58.64.141.245 - -
[11/Jun/2015:18:12:01 -0400] "GET /webfiles/?sort=1&dir=C%3A%5CWindows
HTTP/1.1" 200 48086
9901284 58.64.141.245 - -
[11/Jun/2015:18:12:01 -0400] "GET /webfiles/?Javascript HTTP/1.1" 200
3714
9901378 58.64.141.245 - -
[11/Jun/2015:18:12:16 -0400] "GET /webfiles/?first&uplMonitor=C%3A%5Cfakepath%5C12.bat
HTTP/1.1" 200 865
9901502 58.64.141.245 - -
[11/Jun/2015:18:12:16 -0400] "POST /webfiles/ HTTP/1.1" 200 48896
9901587 58.64.141.245 - -
[11/Jun/2015:18:12:16 -0400] "GET /webfiles/?Javascript HTTP/1.1" 200
3714
9901681 58.64.141.245 - -
[11/Jun/2015:18:12:18 -0400] "GET
/webfiles/?uplMonitor=C%3A%5Cfakepath%5C12.bat HTTP/1.1" 200 574
9901799 58.64.141.245 - -
[11/Jun/2015:18:12:42 -0400] "POST /webfiles/ HTTP/1.1" 200 2245
9901883 58.64.141.245 - -
[11/Jun/2015:18:13:16 -0400] "POST /webfiles/ HTTP/1.1" 200 2278
Windows event logs.
I was able to extract and open the Windows
Security event log (*.evtx) from the memory image, but analysis of this log is
not included here. The Windows Application and System event logs extracted from
the memory image were corrupted, and Windows Event Viewer could not open them (I didn't attempt to parse them with any other tools, such as log2timeline).
Lateral movement.
There were no other internal or external
connections identified; therefore, no lateral movement is believed to have
occurred. The following is the complete Volatility netscan plugin
output showing only the connection from the attacker’s external IP address:
$ vol.py -f
WIN-CEKM08E74HR-20150611-222930.raw netscan
Volatility Foundation Volatility Framework
2.3.1
Offset(P) Proto
Local Address
Foreign Address State Pid Owner Created
0x1ed95048 TCPv4 0.0.0.0:445 0.0.0.0:0 LISTENING 4
System
0x1ed95048 TCPv6 :::445 :::0 LISTENING 4
System
0x1edd4848 TCPv4 0.0.0.0:49157 0.0.0.0:0 LISTENING 596
services.exe
0x1edd4848 TCPv6 :::49157
:::0 LISTENING 596
services.exe
0x1edd7498 TCPv4 0.0.0.0:49157 0.0.0.0:0 LISTENING 596
services.exe
0x1ede2638 TCPv4 0.0.0.0:8009 0.0.0.0:0 LISTENING 1728
Tomcat7.exe
0x1ede2638 TCPv6 :::8009 :::0 LISTENING 1728
Tomcat7.exe
0x1ede2f60 TCPv4 0.0.0.0:8080 0.0.0.0:0 LISTENING 1728
Tomcat7.exe
0x1ede2f60 TCPv6 :::8080 :::0 LISTENING 1728
Tomcat7.exe
0x1edf2f60 TCPv4 127.0.0.1:8005 0.0.0.0:0 LISTENING 1728
Tomcat7.exe
0x1f0db3d0 TCPv4 192.168.56.30:139 0.0.0.0:0 LISTENING 4
System
0x1f1c0158 TCPv4 0.0.0.0:135 0.0.0.0:0 LISTENING 876
svchost.exe
0x1f1c0158 TCPv6 :::135
:::0 LISTENING 876
svchost.exe
0x1f1c0e70 TCPv4 0.0.0.0:135 0.0.0.0:0 LISTENING 876
svchost.exe
0x1f1c43a0 TCPv4 0.0.0.0:49152 0.0.0.0:0 LISTENING 520
wininit.exe
0x1f1c43a0 TCPv6 :::49152 :::0 LISTENING 520
wininit.exe
0x1f1c5008 TCPv4 0.0.0.0:49152 0.0.0.0:0 LISTENING 520
wininit.exe
0x1f1df188 TCPv4 0.0.0.0:49153 0.0.0.0:0 LISTENING 968
svchost.exe
0x1f1e2eb8 TCPv4 0.0.0.0:49153 0.0.0.0:0 LISTENING 968
svchost.exe
0x1f1e2eb8 TCPv6 :::49153 :::0 LISTENING 968
svchost.exe
0x1f22d738 TCPv4 0.0.0.0:49154 0.0.0.0:0 LISTENING 1012
svchost.exe
0x1f22e470 TCPv4 0.0.0.0:49154 0.0.0.0:0 LISTENING 1012
svchost.exe
0x1f22e470 TCPv6 :::49154 :::0 LISTENING 1012
svchost.exe
0x1f2905b0 TCPv4 0.0.0.0:49155 0.0.0.0:0 LISTENING 608
lsass.exe
0x1f291f60 TCPv4 0.0.0.0:49155 0.0.0.0:0 LISTENING 608
lsass.exe
0x1f291f60 TCPv6 :::49155 :::0 LISTENING 608
lsass.exe
0x1f2c6758 TCPv4 0.0.0.0:5357 0.0.0.0:0 LISTENING 4
System
0x1f2c6758 TCPv6 :::5357 :::0 LISTENING 4
System
0x1f2cea58 TCPv4 0.0.0.0:49156 0.0.0.0:0 LISTENING 1596
svchost.exe
0x1f2cea58 TCPv6 :::49156 :::0 LISTENING 1596
svchost.exe
0x1f2d6a48 TCPv4 0.0.0.0:49156 0.0.0.0:0 LISTENING 1596
svchost.exe
0x1f30a4f8 TCPv4 0.0.0.0:80 0.0.0.0:0 LISTENING 4
System
0x1f30a4f8 TCPv6 :::80 :::0 LISTENING 4
System
0x1eda4db0 TCPv4 -:8080
58.64.141.245:1057 CLOSED 1728 Tomcat7.exe
0x1edd0cb0 UDPv4 0.0.0.0:3702 *:* 1080
svchost.exe 2015-06-11 22:06:12
UTC+0000
0x1edde570 UDPv4 0.0.0.0:3702 *:* 1080 svchost.exe 2015-06-11 22:06:12 UTC+0000
0x1edde570 UDPv6 :::3702 *:* 1080 svchost.exe 2015-06-11 22:06:12 UTC+0000
0x1ee01f58 UDPv4 0.0.0.0:0 *:* 820 VBoxService.exe 2015-06-11 22:29:05
UTC+0000
0x1ee3bf58 UDPv4 0.0.0.0:0 *:* 820 VBoxService.exe 2015-06-11 22:30:30
UTC+0000
0x1ee8dd88 UDPv6 fe80::dd13:57ed:2d56:5b23:546 *:* 968 svchost.exe 2015-06-11 22:27:10 UTC+0000
0x1ee93ae8 UDPv4 0.0.0.0:0 *:* 1160 svchost.exe 2015-06-11 22:26:21 UTC+0000
0x1f0d1150 UDPv4 192.168.56.30:138 *:* 4 System 2015-06-11 22:05:25 UTC+0000
0x1f21c3a8 UDPv4 0.0.0.0:0 *:* 1184 svchost.exe 2015-06-11 22:05:44 UTC+0000
0x1f21c3a8 UDPv6 :::0 *:* 1184
svchost.exe 2015-06-11 22:05:44
UTC+0000
0x1f21d510 UDPv4 0.0.0.0:5355 *:* 1184 svchost.exe 2015-06-11 22:05:44 UTC+0000
0x1f21e008 UDPv4 0.0.0.0:5355 *:* 1184 svchost.exe 2015-06-11 22:05:44 UTC+0000
0x1f21e008 UDPv6 :::5355 *:* 1184 svchost.exe 2015-06-11 22:05:44 UTC+0000
0x1f25d608 UDPv4 0.0.0.0:3702 *:* 1080 svchost.exe 2015-06-11 22:06:12 UTC+0000
0x1f25d608 UDPv6 :::3702 *:* 1080 svchost.exe 2015-06-11 22:06:12 UTC+0000
0x1f2a5518 UDPv4 0.0.0.0:500 *:* 1012 svchost.exe 2015-06-11 22:05:54 UTC+0000
0x1f2a5518 UDPv6 :::500 *:* 1012 svchost.exe 2015-06-11 22:05:54 UTC+0000
0x1f2ab5f0 UDPv4 0.0.0.0:500 *:* 1012 svchost.exe 2015-06-11 22:05:54 UTC+0000
0x1f2af8c0 UDPv4 0.0.0.0:4500 *:* 1012
svchost.exe 2015-06-11 22:05:54
UTC+0000
0x1f2b1290 UDPv4 0.0.0.0:0 *:* 1012 svchost.exe 2015-06-11 22:05:54 UTC+0000
0x1f2b1290 UDPv6 :::0 *:* 1012 svchost.exe 2015-06-11 22:05:54 UTC+0000
0x1f2b1f58 UDPv4 0.0.0.0:0 *:* 1012 svchost.exe 2015-06-11 22:05:54 UTC+0000
0x1f2d72b8 UDPv4 0.0.0.0:0 *:* 1596 svchost.exe 2015-06-11 22:05:55 UTC+0000
0x1f2daf58 UDPv4 0.0.0.0:0 *:* 1596 svchost.exe 2015-06-11 22:05:55 UTC+0000
0x1f2daf58 UDPv6 :::0 *:* 1596 svchost.exe 2015-06-11 22:05:55 UTC+0000
0x1f2deaf8 UDPv4 0.0.0.0:3702 *:* 1080 svchost.exe 2015-06-11 22:06:12 UTC+0000
0x1f2dfbb8 UDPv4 0.0.0.0:55678 *:* 1080 svchost.exe 2015-06-11 22:05:56 UTC+0000
0x1f2e0b50 UDPv4 0.0.0.0:55679 *:* 1080
svchost.exe 2015-06-11 22:05:56
UTC+0000
0x1f2e0b50 UDPv6 :::55679 *:* 1080 svchost.exe 2015-06-11 22:05:56 UTC+0000
0x1f2e9160 UDPv4 0.0.0.0:0 *:* 1080 svchost.exe 2015-06-11 22:05:57 UTC+0000
0x1f2e9160 UDPv6 :::0 *:* 1080 svchost.exe 2015-06-11 22:05:57 UTC+0000
0x1f2ea008 UDPv4 0.0.0.0:0
*:* 1080 svchost.exe 2015-06-11 22:05:57 UTC+0000
0x1f2f9008 UDPv4 0.0.0.0:123 *:* 1080 svchost.exe 2015-06-11 22:05:57 UTC+0000
0x1f2f9008 UDPv6 :::123 *:* 1080 svchost.exe 2015-06-11 22:05:57 UTC+0000
0x1f2f9228 UDPv4 0.0.0.0:123 *:* 1080 svchost.exe 2015-06-11 22:05:57 UTC+0000
0x1fa2fb40 UDPv4 192.168.56.30:137 *:* 4 System 2015-06-11 22:05:25 UTC+0000
Other attacker activity.
The following activity attributable to
the attacker was also noted:
Executing the Windows time
command via the web shell
527519808 POST /webfiles/ HTTP/1.1
527519834 Accept: image/gif,
image/jpeg, image/pjpeg, image/pjpeg, application/x-shockwave-flash, */*
527519927 Referer:
http://192.168.56.30:8080/webfiles/
527519973 Accept-Language: en-us
527519997 User-Agent: Mozilla/4.0
(compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)
527520074 Content-Type:
application/x-www-form-urlencoded
527520123 Accept-Encoding: gzip,
deflate
527520155 Host: 192.168.56.30:8080
527520181 Content-Length: 95
527520201 Connection: Keep-Alive
527520225 Cache-Control: no-cache
527520250 Cookie:
JSESSIONID=D4BB0A17D08FE321DF87835231D79824
527520305
text=06%3A24+PM%0D%0A%0D%0A&dir=C%3A%5Cinetpub%5Cwwwroot&command=time+%2Ft&Submit=Launch&sort=1X
time+%2Ft is the URL-encoded version of time /t, which returns system time in the HH:MM AM|PM format.
Executing
the Windows tasklist command via the web shell
526843968 POST /webfiles/ HTTP/1.1
526843994 Accept: image/gif,
image/jpeg, image/pjpeg, image/pjpeg, application/x-shockwave-flash, */*
526844087 Referer:
http://192.168.56.30:8080/webfiles/
526844133 Accept-Language: en-us
526844157 User-Agent: Mozilla/4.0
(compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)
526844234 Content-Type: application/x-www-form-urlencoded
526844283 Accept-Encoding: gzip,
deflate
526844315 Host: 192.168.56.30:8080
526844341 Content-Length: 78
526844361 Connection: Keep-Alive
526844385 Cache-Control: no-cache
526844410 Cookie:
JSESSIONID=D4BB0A17D08FE321DF87835231D79824
526844465
text=%0D%0A&dir=C%3A%5Cinetpub%5Cwwwroot&command=tasklist&Submit=Launch&sort=1H
This finding is supported by Volatility pstree output, which shows tasklist.exe running as a child process of cmd.exe, which in turn is a child process of Tomcat7.exe:
$ vol.py -f
WIN-CEKM08E74HR-20150611-222930.raw pstree
<…snip…>
. 0x83139650:services.exe 596 520
6 234 2015-06-11 22:05:29 UTC+0000
.. 0x832dc560:Tomcat7.exe 1728 596
28 360 2015-06-11 22:05:56 UTC+0000
... 0x835eba10:cmd.exe 3604 1728
0 ------ 2015-06-11 22:25:15 UTC+0000
... 0x836407b0:cmd.exe 3612 1728
0 ------ 2015-06-11 22:25:24 UTC+0000
.... 0x830e2d90:tasklist.exe 3620 3612
0 ------ 2015-06-11 22:25:24 UTC+0000
... 0x831f3d90:cmd.exe 3248 1728
0 ------ 2015-06-11 22:21:49 UTC+0000
.... 0x8363c7f0:tasklist.exe
3256 3248
0 ------ 2015-06-11 22:21:49 UTC+0000
Thanks for the awesome walkthrough Matt.
ReplyDeleteI just wanted to let you know also that the new shimcachemem plugin was able to identify the bg.jpg file, the fact that it executed, and the files that executed before and after it. The standard shimcahce plugin wasn't able to detect this evidence.
Not sure how much value it adds in this case since we already knew about the file and it had a process so it was executing, but it may be useful in the future.
https://github.com/fireeye/Volatility-Plugins/tree/master/shimcachemem
I appreciate the feedback, David. The ShimCacheMem plugin hadn't been published yet when I originally did this write-up, and I never went back to try it. It's nice to see it worked in this situation - additional confirmation never hurts!
ReplyDeleteHow do you directly correlate the attacker's IP with detailed GET/POST found randomly throughout the vol strings module output? Are you just pivoting against the commands used as the URI to make that link?
ReplyDeleteGood question, "Unknown". The GET/POST requests found in strings are web server logs showing 58.64.141.245 as the source IP address of the connections. The same IP was the only IP shown as a foreign connection in the Volatility netscan output. Additionally, the timestamps of the connections from that IP line up with file system activity from the MFT. If I remember correctly, I found the strings of the web server logs by grepping for the IP address after finding the IP via netscan.
ReplyDeleteThanks. "Unknown" here again. I used the schtasks module from https://github.com/binglot/misc to track down 12.bat's execution cycle.
Delete$ vol.py -f ../WIN-CEKM08E74HR-20150611-222930.raw --profile=VistaSP1x86 schtasks
Volatility Foundation Volatility Framework 2.5
Offset(P) ScheduledDate MostRecentRunTime Application Author RunInstanceCount MaxRunTime ExitCode Comment
0x0c8f8ba8 2015-06-11 18:25:00.000 2015-06-11 18:25:00.028 c:\windows\12.bat SYSTEM 1 72:00:00.0 0x00000000 Created by NetScheduleJobAdd.
0x0c8f8cf0 2015-06-11 18:25:00.000 2015-06-11 18:25:00.028 c:\windows\12.bat SYSTEM 1 72:00:00.0 0x00000000 Created by NetScheduleJobAdd.
0x0ca2d5c0 2015-06-11 18:25:00.000 Not run yet c:\windows\12.bat SYSTEM 0 72:00:00.0 0x00000000 Created by NetScheduleJobAdd.
0x0ca2d6c8 2015-06-11 18:25:00.000 Not run yet c:\windows\12.bat SYSTEM 0 72:00:00.0 0x00000000 Created by NetScheduleJobAdd.
0x10332118 2015-06-11 18:25:00.000 2015-06-11 18:25:00.028 c:\windows\12.bat SYSTEM 1 72:00:00.0 0x00000000 Created by NetScheduleJobAdd.
0x10476000 2015-06-11 18:25:00.000 2015-06-11 18:25:00.028 c:\windows\12.bat SYSTEM 1 72:00:00.0 0x00000000 Created by NetScheduleJobAdd.
Nice, thanks for sharing that.
DeleteGreat write up. What command or tool did you use to get "evtx" logs from memory?
ReplyDeleteHi, Darcy, thanks for your comments. I believe I used Volatility's dumpfiles plugin to extract the EVTX logs after locating their offsets with the filescan plugin. Jamie Levy (@gleeda) from the Volatility team later told me the EVTXtract tool is good at parsing corrupted EVTX files, although I never went back to try it with this scenario. See https://github.com/williballenthin/EVTXtract
ReplyDeleteThanks for the write up! Great blog BTW
ReplyDeleteNice writeup. I know I'm several months late on this, but I just ran across Jack's Tweet today and decided to give it a shot.
ReplyDeleteI eventually got stuck while trying to find 12.bat in memory. I kept trying to find it using the 'handles' volatility plugin, but seemingly nothing had a handle to the bat file open at the time the memory image was taken. I completely forgot about the filescan plugin...
Like you, initially I was unable to find out how the at job was scheduled - eventually I found the following HTTP request while sifting through memory strings. As you correctly assumed, it was accomplished through the web shell:
---------------
POST /webfiles/ HTTP/1.1
Accept: image/gif, image/jpeg, image/pjpeg, image/pjpeg, application/x-shockwave-flash, */*
Referer: http://192.168.56.30:8080/webfiles/
Accept-Language: en-us
User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)
Content-Type: application/x-www-form-urlencoded
Accept-Encoding: gzip, deflate
Host: 192.168.56.30:8080
Content-Length: 94
Connection: Keep-Alive
Cache-Control: no-cache
Cookie: JSESSIONID=D4BB0A17D08FE321DF87835231D79824
text=%0D%0A&dir=C%3A%5CWindows&command=at+18%3A25+c%3A%5Cwindows%5C12.bat&Submit=Launch&sort=1
---------------
...additionally I have written my own parser for .job files, and was able to yank the information below out of the job file itself. Disclaimer: I have yet to publicly release my parser, and it hasn't properly been tested yet. Specifically, I have a sneaking suspicion that my "Flags" field is incorrect. In any event, here it is:
Product Version: Windows Vista
Job UUID: {486CBF7C-AABC-4E56-928F-6EB70574CCB}
Error Retry Count: 0
Error Retry Interval (minutes): 0
Idle Deadline (minutes): 60
Idle Wait (minutes): 10
Priority: NORMAL_PRIORITY_CLASS
Maximum Run Time (ms): 259200000
Status: SCHED_S_TASK_RUNNING
Flags: TASK_APPLICATION_NAME TASK_FLAG_DELETE_WHEN_DONE
Running Instance Count: 1
Application Name: c:\windows\12.bat
Parameters: None
Working Directory:
Author: SYSTEM
Comment: Created by NetScheduleJobAdd.
Trigger Type: ONCE
First Scheduled Date: 6-11-2015
First Scheduled Time: 18:25
Adam