0. Scope, Location, and Submission
This lab is for the course-provided local environment. Do not run these techniques on any system, binary, or service outside this course lab.
~/ierg4851/week3/in-class-lab. If you do not know your lab-machine username or password, ask the TA or instructor during class.cd ~/ierg4851/week3/in-class-lab find . -maxdepth 2 -type f | sort
| Directory | Goal | Difficulty |
|---|---|---|
ret2libc32-demo | Run and explain the two-stage 32-bit ret2libc-with-ASLR exploit. | Required |
ret2libc32-leak-another | Modify the 32-bit exploit to leak a different libc function. | Required |
ret2libc64-no-aslr | Run and explain 64-bit ret2libc using a libc pop rdi; ret gadget. | Recommended |
ret2libc64-aslr-challenge | Complete a two-stage 64-bit ASLR exploit with a main-binary gadget. | Advanced |
Practice Record Contents
- For each required lab, include the commands you ran, key addresses, payload layout, and final output.
- Include screenshots from your own terminal or GDB session as evidence.
- For each thinking question, write a short answer in your own words.
- For the advanced challenge, submit either a working exploit or a clear design if you do not finish implementation.
1. Reproduce 32-bit ret2libc with ASLR
This lab matches the lecture flow: leak a libc address through the GOT/PLT, infer libc base, then call system("/bin/sh") in the same process.
system() no longer works. The PLT address is stable because the binary is non-PIE. Calling puts(puts@GOT) reveals the real runtime address of puts inside libc.cd ~/ierg4851/week3/in-class-lab/ret2libc32-demo make clean all make checksec cat /proc/sys/kernel/randomize_va_space python3 exploit_aslr.py
What to Understand
- Stage 1 payload: padding,
puts@PLT,main,puts@GOT. - Why returning to
maingives the process a second input round without losing the leaked libc base. - How
libc_base = leaked_puts - libc.symbols["puts"]. - Stage 2 payload: padding,
system,exit,"/bin/sh".
IERG4851_WEEK3_32_ASLR and the output of id.puts@libc, computed libc base, system and "/bin/sh" addresses, final marker, and a short explanation of both stages.Thinking Questions
- Why does the exploit call
puts@PLTinstead of directly calling libcputs? - Why is
puts@GOTused as the argument toputs? - Why does the exploit return to
mainafter stage 1?
2. Modify the Leak Target
Now modify the exploit so stage 1 leaks a different libc function. The purpose is to prove you understand the formula, not just the script.
cd ~/ierg4851/week3/in-class-lab/ret2libc32-leak-another
make clean all
python3 - <<'PY'
from pwn import ELF
elf = ELF("./vul_aslr")
print("GOT:", elf.got)
print("PLT:", elf.plt)
PY
cp exploit_template.py exploit.py
nano exploit.py
Required Change
Pick a libc function in the GOT other than puts, leak it using puts@PLT, then compute:
libc_base = leaked_function_address - libc.symbols["that_function"]
The second stage should still call system("/bin/sh").
IERG4851_WEEK3_LEAK_ANOTHER and the output of id.Thinking Questions
- Why does leaking any known libc function reveal the same libc base?
- Which functions appear in the GOT, and why are not all libc functions present there?
3. 64-bit ret2libc without ASLR
This lab connects to the 64-bit calling convention slides. In x86-64 Linux, the first argument goes in %rdi, so the exploit needs a pop rdi; ret gadget.
"/bin/sh" after the return address is not enough. You must load the address into %rdi before calling system().cd ~/ierg4851/week3/in-class-lab/ret2libc64-no-aslr make clean all make checksec ./example python3 exp_ret2libc.py
What to Understand
- The script disables ASLR for this process with pwntools so libc base is known during this run.
- The script searches libc for
pop rdi; ret, because the small main binary may not contain that gadget. - The final chain is padding,
pop rdi; ret,"/bin/sh", alignmentret,system,exit.
IERG4851_WEEK3_64_NO_ASLR and the output of id.pop rdi; ret address, "/bin/sh" address, system address, final marker, and a short explanation of why %rdi matters.Thinking Questions
- Why does the 64-bit exploit need
pop rdi; ret? - Why does the script search libc instead of only the main binary?
- Why might an extra
retbeforesystemhelp stack alignment?
4. Advanced Challenge: 64-bit ret2libc with ASLR
This optional challenge gives you a 64-bit binary with a main-binary pop rdi; ret gadget. Complete the two-stage exploit in exploit_template.py.
cd ~/ierg4851/week3/in-class-lab/ret2libc64-aslr-challenge make clean all make checksec python3 exploit_template.py
Design
- Stage 1: use the main-binary
pop rdi; retto callputs(puts@GOT), then return tomain(). - Parse the leaked
puts@libcaddress and compute libc base. - Stage 2: call
system("/bin/sh"). You may use the main-binarypop rdi; retagain or a libc gadget after computing libc base.
IERG4851_WEEK3_64_ASLR_CHALLENGE, or a clear design explaining the two stages, the gadgets, and why the first-stage gadget cannot come from libc before the leak.Harder Reading
If a real binary has no direct pop rdi; ret gadget, one common method is ret2csu. This is optional reading:
Thinking Questions
- Why can the no-ASLR 64-bit exploit use a libc gadget immediately, but the ASLR version cannot?
- What must be stable before the first libc leak?
- How does ret2csu help when a binary has no direct
pop rdi; ret?