ROP Primer: 1

A couple of times ago, a new challenge was released on the vulnhub website. Because it wass really interesting, I decided to blog it. You can find the challenge here:

Let’s have a look 🙂




First of all, the virtual machine has been deployed under VirtualBox. After finding the IP address, let’s begin with nmap:

an@chm:~/Pentest/Tools$ nmap
Starting Nmap 6.46 ( ) at 2015-04-22 14:04 CEST
Nmap scan report for
Host is up (0.00060s latency).
Not shown: 997 closed ports
22/tcp   open  ssh
80/tcp   open  http
8888/tcp open  sun-answerbook
Nmap done: 1 IP address (1 host up) scanned in 0.04 seconds

The web server contains all information about this challenge:



This challenge has to be performed locally through SSH.

A local program named level0 can be executed from the level0 home directory:

level0@rop:~$ ./level0
[+] ROP tutorial level0
[+] What's your name? Antoine
[+] Bet you can't ROP me, Antoine!

Let’s try to obtain some error:

level0@rop:~$ ./level0
[+] ROP tutorial level0
[+] What's your name? uilhnuiojzui&/%(&()J=/)(=KJK/()=ZNIHuiomziouz=)()=Kpuio.jivtrtü+bvät#vphrv#tr
[+] Bet you can't ROP me, uilhnuiojzui&/%(&()J=/)(=KJK/()=ZNIHuiomziouz=)()=Kpuio.jivtrtü+bvät#vphrv#tr!
Segmentation fault

Ok apparently parameters are not properly casted.

I analyzed the comportment with gdb (the peda plugin has been added): level0@rop:~$ gdb level0

In order to identify the impact of this error on the stack, I used a pattern generated with peda:

Now, the EIP is 0x41414641. With this value, I am able to determine the position of the EIP:

EIP found at offset 44. I decided to generate a complete shellcode and include it:

I created an exploit file with this shellcode:

an@chm:~$ perl -e 'print "A"x44 . "B"x4 . "\x90"x500 . "\x31\xc0\x50\x68\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x31\xc9\x89\xca\x6a\x0b\x58\xcd\x80"' > shellcode.bin

With gdb, I injected this shellcode.bin in the program input to analyze the result:

The EIP is 0x42424242. The good news is the EIP has been properly overwritten by the 42424242.

I can try to perform a ret2libc.

Return-to-libc attack (ret2libc):

I need the address of the bash and the system function. To find the bash, I am looking around the ESP:


I have the bash address. Now, I am looking for the system() address:

The system() address cannot be found. The ret2libc seems to be not possible.

Return oriented programming (rop):

an@chm:~$ perl -e 'print "A"x44 . "B"x4' > min.bin

I reproduced the exploit with gdb. As previously, the EIP has been replaced:

In order to perform a ROP, I need a gadget.

In this challenge I used the leave() function in the main. I put a breakpoint on this address to analyze the stack. Before the crash:

I made a step to see the stack after the leave() function:

What can we conclude?

Before leave():

  • ESP 0xbffff5c0
  • EBP 0xbffff5f8

After leave():

  • ESP 0xbffff5fc
  • EBP 0x41414141

I wrote a python script “” to use the main leave() call:

Ok, I still have the EIP at 42 🙂

Now I am looking for the mprotect/read call addresses and the mapped memory on the stack:

With these addresses, I adapted the previous script:

Now, I executed once again the exploit and see the difference in the mapped memory:

Good news, now we have a memory space mapped in rwxp!

In the same gdb session, I am looking for the POP POP POP RET – pop3ret gadget:

Sounds good! Let’s modify one more time the python script to include these addresses:

The EIP is 0x41414141! Perfect 🙂

The end is not so far away!

Let’s modified the python script for the last time with the real ret address:

Perfect, we don’t have any segmentation fault!

Now , let’s add a shell: