Intro 2
CTF Write-up: Intro Reverse Engineering 2 - Reversing Static Input Transformation
Challenge: Intro Reverse Engineering 2 (108 points)
Description: Password "encoded", can't be found in plaintext. Find the right password.
Attachments: intro-rev-2.zip (containing rev2 binary)
Connection: ncat --ssl-verify 6e554da9024a3ed3b6cb73da-1024-intro-rev-2.challenge.cscg.live 1337
Analysis
Binary Properties (
checksec, IDA/GDB): The target binaryrev2is a 64-bit PIE-enabled ELF executable, dynamically linked, and not stripped. Key features arePIE Enabledand the presence of symbols.Code Functionality:
The program starts by calling
initialize_flag, which reads the contents of a file named./flag.txtinto a global buffer calledflagBuffer.The
mainfunction then prompts the user for a password and reads their input into a buffer on the stack (buf).A critical loop iterates through the user's input in
buf. For each characterc, it computesc - 0x77and overwrites the character inbufwith this new value. This is the "encoding" or transformation mentioned in the description.After modifying the entire input, the program compares the transformed input with a hardcoded target sequence (
s2) located in the.rodatasection (visible in IDA around address0x2020relative to.rodata). The comparison is done usingstrcmp.If the transformed input matches the target sequence
s2, the program prints a success message followed by the contents offlagBuffer(which holds the actual flag read from./flag.txt). Otherwise, it prints a failure message.
Vulnerability / Solution Path
The challenge requires bypassing the password check. Since the user input P is transformed into M (where M[i] = P[i] - 0x77) before being compared to the target S (sequence s2), we need to find an input P such that M = S.
Reversing the transformation gives the required input character:
P[i] = S[i] + 0x77
We need to:
Extract the target byte sequence
Sfrom the binary's.rodatasection.Calculate the required input
Pby adding0x77(modulo 256) to each byte ofS.Send the calculated password
Pto the remote server.
Reversing the Transformation
Identify Target Bytes (
S): By examining thestrcmpcall inmainwithin IDA or Ghidra, we find it compares the modified buffer against the data ats2. Extracting these bytes gives the target sequenceS. (Based on the successful execution, these bytes must result inyay_st4tic_transf0rmationafter adding0x77).Calculate Input Password (
P): Apply the reverse transformationP[i] = (S[i] + 0x77) & 0xFFto each byte. The successful execution log confirms this calculation results in the stringyay_st4tic_transf0rmation.
# Example snippet demonstrating the calculation (actual target_bytes derived from reverse engineering)
# Assuming target_bytes = bytes([...]) was extracted
OFFSET = 0x77
# input_password_bytes = bytes([(b + OFFSET) & 0xFF for b in target_bytes])
# input_password = input_password_bytes.decode('ascii')
input_password = "yay_st4tic_transf0rmation" # From successful script log
log.info(f"Calculated Input Password: {input_password}")Exploit Script (Python w/ pwntools)
This script connects, uses the pre-calculated correct password, sends it, and retrieves the flag.
#!/usr/bin/env python3
from pwn import *
import re
# --- Derived Input Password ---
# This password, when subtracted by 0x77 byte-wise, matches the binary's target sequence.
# Derived from reversing the process or from the successful execution log.
input_password = "yay_st4tic_transf0rmation"
log.info(f"Using Input Password: {input_password}")
# --- Connection Details ---
HOST = '6e554da9024a3ed3b6cb73da-1024-intro-rev-2.challenge.cscg.live'
PORT = 1337
USE_SSL = True
# --- Interaction ---
log.info(f"Connecting to {HOST}:{PORT}{' (SSL)' if USE_SSL else ''}")
p = remote(HOST, PORT, ssl=USE_SSL)
# Receive prompt
p.recvuntil(b"Give me your password: ")
# Send the calculated password
log.info("Sending calculated password...")
p.sendline(input_password.encode())
# Receive output and look for the flag
log.info("Waiting for response / flag...")
try:
response = p.recvall(timeout=5).decode()
log.success("Received response:")
print("-" * 20)
print(response)
print("-" * 20)
# Extract flag using regex
flag_match = re.search(r"CSCG\{[^\}]+\}", response)
if flag_match:
flag = flag_match.group(1)
log.success(f"Flag found: {flag}")
elif "Thats the right password!" in response:
log.warning("Correct password message received, but flag pattern not found.")
else:
log.warning("Failed password message or unexpected response received.")
except EOFError:
log.error("Connection closed unexpectedly.")
except Exception as e:
log.error(f"An error occurred: {e}")
p.close()Execution and Result
Running the script sends the calculated password yay_st4tic_transf0rmation. The remote server applies the c - 0x77 transformation, the result matches the hardcoded sequence, strcmp returns 0, and the server prints the flag read from its ./flag.txt.
[*] Using Input Password: yay_st4tic_transf0rmation
[*] Connecting to 6e554da9024a3ed3b6cb73da-1024-intro-rev-2.challenge.cscg.live:1337 (SSL)
[+] Opening connection to 6e554da9024a3ed3b6cb73da-1024-intro-rev-2.challenge.cscg.live on port 1337: Done
[*] Sending calculated password...
[*] Waiting for response / flag...
[+] Receiving all data: Done (81B)
[*] Closed connection to 6e554da9024a3ed3b6cb73da-1024-intro-rev-2.challenge.cscg.live port 1337
[+] Received response:
--------------------
Thats the right password!
Flag: CSCG{y0u_just_r3versed_a_st4tic_transformation!}
--------------------
[+] Flag found: CSCG{y0u_just_r3versed_a_st4tic_transformation!}Flag: CSCG{y0u_just_r3versed_a_st4tic_transformation!}
Conclusion
This reverse engineering task required identifying a static transformation applied to the user's input before a string comparison. By extracting the hardcoded target byte sequence from the binary and reversing the transformation (+ 0x77), the correct input password (yay_st4tic_transf0rmation) was calculated. Providing this input satisfied the check, leading the program to reveal the flag stored in the flagBuffer (which was read from ./flag.txt on the server).
Last updated
Was this helpful?