---
# System prepended metadata

title: BadPress Write-up

---

# BadPress Write-up

This is a writeup for the challenge "Bad Press" in the Xiamora 5.0 CTF held at Anokha '20.

I wasn't able to solve this problem during the competition, but it intrigued me, and so I decided to give it another try.

The challenge comprises of a single python file, a `chal.py` with the following contents:
```python
from flag import flag
b = ""
for i in range(len(flag)):
    b += bin(ord(flag[i]))[2:].zfill(8)

def drop(b,m):
    return(b[:m]+b[(m+1):])
    
def shift(b, i):
    return(b[i:] + b[:i])

l = len(b)
i = 1
while(i<l):
    m = l%i
    b = drop(b,m)
    b = shift(b,i)
    l = len(b)
    i+=1

print("Compressed data: ",b)


'''
Output: 
('Compressed data: ', '111110110101101010010100')

sha256sum of the complete flag with CTF{<flag>}
sha256sum : c8c3c0e9791d188dd0a13085b9207016d1fc0040c46592a46ac54efe66627a27
'''
```

Examining it a bit, it is quite evident to what it does. The flag is first converted to its equivalent binary form, and then passed through a loop that drops a bit and then shifts the binary string.

After reading through the code, I realized that the compressed string would always turn out to be exactly half the size of the original string -- this meant that the **actual flag was only 6 characters!**

We have the sha256 hash of the flag, so what if we used hashcat to bruteforce it?
```shell
$ hashcat -a 3 -1 "?l?d?s?u" -m 1400 sha256.hash "CTF{?1?1?1?1?1?1}" --force

...
Time.Estimated...: Thu Feb 27 15:33:58 2020 (5 days, 22 hours)
```
5 days, 22 hours? I guess that's out of question (on my laptop). I guess we'll have to do it the hard way.

I started reversing the operations and decided to replace the dropped bit with an "x".
```python
b = '111110110101101010010100'
def undrop(b, m):
    return(b[:m] + "x" + b[m:])
def unshift(b, i):
    return(b[-i:] + b[:-i])

i=25
while(i>1):
    i-=1;
    l=len(b) + 1
    m=l%i
    b=unshift(b, i)
    b=undrop(b,m)
print(b)
# xxxx11x1x1x0110xxxxxxxx1011x0x10xx10x0x10x1001xx
```

We can split the final string into 6, with each section representing a single chracter.
```!
['xxxx11x1', 'x1x0110x', 'xxxxxxx1', '011x0x10', 'xx10x0x1', '0x1001xx']
```

We know that the first bit must be 0, as none of the ascii characters surpass 128. Also, the flag probably contains only printable characters, so we can disregard any non printable characters. Designing a function to output possibilities for each character, I end up with:
```python
def possibles(dec):
    ar = ""
    printable = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~ '
    def rex(dec, i=0):
        global ar
        if i == 0:
            ar = ""
        if i == len(dec):
            theChar = chr(int(dec, 2))
            if theChar in printable:
                ar+=theChar
        elif dec[i] == "x":
            if not i == 0:
                rex(dec[:i] + "1" + dec[i+1:], i+1)
            rex(dec[:i] + "0" + dec[i+1:], i+1)
        else:
            rex(dec, i+1)
        if i == 0:
            return ar
    
    return [rex(letter)for letter in [dec[i:i+8] for i in range(0, len(dec), 8)]]
    
possibles("xxxx11x1x1x0110xxxxxxxx1011x0x10xx10x0x10x1001xx")
```

The above code might seem unnecessarily complicated, but all it's doing is recursively filling the "x"s with 0s and 1s and then converting it to its equivalent character.

It returns:
```
['}om_]OM?=/-',
 'mlML',
 "}{ywusqomkigeca_][YWUSQOMKIGECA?=;97531/-+)'%#!",
 'vrfb',
 'kica+)#!',
 "gfed'&%$"]
```
This gibberish is the possible values for each character. I considered writing python code to bruteforce the actual flag, but then felt that it would be better suited to use hashcat.

```shell
$ hashcat -a 3 -1 '}om_]OM??=/-' -2 'mlMLvrfbkica+)#!' -3 '}{ywusqomkigeca_][YWUSQOMKIGECA??=;97531/-+)%#!'"'" -4 'gfed&%$'"'" -m 1400 sha256.hash 'CTF{?1?2?3?2?2?4}\n' --force
```
Hashcat only supports up to 4 custom charsets, so I had to merge some of the shorter charsets (see -2).

Hashcat took around 5 seconds to tell me that it couldn't find the matching plaintext flag. This was where I hit a wall. I wondered what went wrong and started verifying my code to no avail.

It was around here when I started thinking about how exactly the challenge was made. The original py file mentioned using sha256sum. The command used was probably along the lines of `echo "CTF{flaggg}" | sha256sum`. But echo automatically appends a newline `\n` character. What if that was part of the hash?

Doing some research online on how to add a `\n` to hashcat masks, I learnt that everything needed to converted to hex (t his is so that `0A`, the hex equivalent of `\n` can be used).

```shell
$ hashcat -a 3 --hex-charset -1 7d6f6d5f5d4f4d3f3d2f2d -2 6d6c4d4c767266626b6963612b292321 -3 7d7b79777573716f6d6b69676563615f5d5b59575553514f4d4b49474543413f3d3b39373533312f2d2b2927252321 -4 6766656427262524 -m 1400 sha256.hash '4354467b?1?2?3?2?2?47d0a' --force
```

And voila! That was it! That gives us the plaintext of `$HEX[4354467b6f6d796261647d0a]` or when converted, `CTF{omybad}\n`.


##### Notes

1. Thank goodness I did not try waiting for 5 days for hashcat to recover the plaintext (I had half the mind to xD). I would have been sorely disappointed when it finished running.
2. I may have over-complicated some steps, or there's some super simple way to crack this challenge, or you just don't like my writing. In any case, feel free to chat me.