papa_bear

Papa Bear

The question:

Author: trupples

Papa bear loves knitting, and even more so taking thin wires and spinning them together to make a strong, bushy rope.
Code:

The answer:

We received a binary called papa_bear.
This binary has a very big buffer which looks pretty similar to the one in the question:

Starting with the same banner:

After the papa bear banner, you can see some difference:

After reversing, we realized that argv[1] is manipulating the “after papa bear banner” letters – each input letter manipulates the current pointer of the buffer, and advances it to the next “non-manipulated” letters. For example:

After all of the manipulations, papa_bear writes to stdin the manipulated buffer.
The next step, is understanding that the question includes the target buffer – and the input causing this target buffer is the flag. We checked our assumption using “HackTM{“ prefix – and we were right – “HackTM{“ manipulated the prefix of the buffer to be exactly the same as the target.

For comparison, let’s look at “HackTM” vs “a”:

While “a” is different from the 8th index, “HackTM{“ is different from 57th index.
So – we can brute force in reasonable time – each letter that advances the first index to be different is a potential letter in the flag. It is possible that a letter will advance the index, but won’t be in the flag – so we can’t stop on all letters that are advancing the first index to be different – we made a recursion algorithm for that exact case – if a letter has been picked and was incorrect, we will remove it and look for the next letter.

**In order to make our script work, we patched the binary to write to stdout instead of stdin. **

We ran the recursive brute force on the string – and that’s it 🙂

import string
import subprocess
from pwn import *

target = b"""dWWW=- dWWMWWWWWMWMb dMMWWWWWWWWWb -=MMMb
dWMWP dWWWMWWWMMWMMMWWWWWMMMMMMWMMMWWWMMMb qMWb
WMWWb dMWWMMMMMMWWWWMMWWWMWWWWWWMMWWWWMWMWMMMWWWWb dMMM
qMMWMWMMMWMMWWWMWMMMMMMMMWMMMMWWWMMWWMWMWMMWWMWWWWMWWMMWMMWP
QWWWWWWWMMWWWWWWWMMWWWWMMWP QWWWMWMMMMWWWWWMMWWMWWWWWWMP
QWMWWWMMWWMWMWWWWMWWP QWWMWWMMMWMWMWWWWMMMP
QMWWMMMP QMMMMMMP""".replace(b" ", b"").replace(b"\n", b"")

flag = "HackTM{F4th3r bEaR"

def matchlen(res):
    counter = 0
    for i in range(len(target)):
        if res[i] == target[i]:
            counter += 1
        else:
            return counter

    print("DONE")
    return counter

context.log_level = "ERROR"
current_matchlen = 0

def add_char(current_matchlen, flag):
    for c in string.printable: #"y@ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz}0123456789@_! ":
        print(["/bin/sh", "-c", './papa_bear %s' % (flag + c)])
        res = process(["/bin/sh", "-c", './papa_bear %s' % sh_string(flag + c)]).recvall().replace(b"\t",b"").replace(b" ", b"")[295:].replace(b"\n", b"")
        print(target)
        print(res)

        m = matchlen(res)
        print (m, current_matchlen)
        if m > current_matchlen:
            print (target)
            print (res)
            if m == len(res):
                print(flag + c)
                return
            print(flag + c)
            add_char(m, flag + c)

add_char(12, "HackTM{F4th3r bEaR s@y$: ")