typedef struct _llist {
struct _llist *next;
uint32_t tag;
char data[100];
llist;and:
register char *answer;
char *(*func)();
llist *head;
…
func = (char *(*)(llist *))userBuf;
answer = (char *)(*func)(head);
send_string(answer);
exit(0);Write me shellcode that traverses the randomly generated linked list, looking for a node with a tag 0x41414100, and returns a pointer to the data associated with that tag, such that the call to send_string will output the answer.
Running at linked.shallweplayaga.me:22222 OR linked2.shallweplayaga.me:22222
Summary: x86 shellcode golfing.
Alright, what could be easier?
55 push ebp 89E5 mov ebp, esp 8B45 08 mov eax, [ebp + 8] ; get first arg _loopAgain: 8178 04 00414141 cmp dword ptr [eax + 4], 41414100h ; eax->tag == 0x41414100 ? 74 04 je _found 8B00 mov eax, [eax] ; eax = eax->next EB F3 jmp _loopAgain _found: 83C0 08 add eax, 8 ; eax = &eax->data C9 leave C3 ret |
We’ve got our gorgeous shellcode:
5589e58b45088178040041414174048b00ebf383c008c9c3 |
Let’s send it in.
C:\Users\vos>nc linked.shallweplayaga.me 22222 List built. Send me your shellcode. Max size: 16 |
Oh dayum! Ours is 24. Let’s see what we can cut.
; first of all, fuck the prologue 59 pop ecx ; save return address in ecx _loopAgain: 5E pop esi ; get argument (pointer to list) in esi AD lodsd ; == mov eax, [esi] 66:8178 05 4141 cmp word ptr [eax+5], 4141h ; we have to sacrifice two bytes of the tag for 1 byte less code 50 push eax ; put eax back into stack for 'pop esi' 75 F5 jne _loopAgain 04 08 add al, 8 ; eax = &eax->data FFE1 jmp ecx ; jump back to return address. We don't care about stack frames. |
16 bytes exactly, phew.
F:\>nc linked2.shallweplayaga.me 22222 < shellcode List built. Send me your shellcode. Max size: 16 The key is: Who says ESP isn't general purpose!?!?
3 comments
What assembler did you use? Both nasm and yasm do not accept the “WORD PTR” syntax and assemble “pop ecx” as \x66\x59 instead of \x59. Did you hand massage the resulting shellcode?
Author
Actually I hand-crafted the shellcode in OllyDbg using built-in assembler, but any assembler should generate the exact same bytecode.
Looks like your NASM assembles in 16-bit mode by default.
Add ‘bits 32‘ at the top of your .asm.
nasm is very good for shellcodes!
1. for x64 you need to put “BITS 64” directive in file
2. don’t use PTR word (just mov dword [rax], 0x1234)