Rating:
# Underscore in Corrupted
## Files
[`ohno.png`](ohno.png)\
[`Underscore_in_C.png`](Underscore_in_C.png)
## Steps to Solve
The flag starts with "kqctf{" so we know that if we xor the first 6 values of the flag with the first 6 values of enc, we will get the first 6 values of the key.
### getkeys.py
```python
flag = "kqctf{"
enc = [0xe2, 0x21, 0x2d, 0x33, 0x6b, 0x71]
key = []
for i, x in enumerate(flag):
key.append(hex(ord(x) ^ enc[i]))
print(key)
```
```bash
$ python3 getkeys.py
['0x89', '0x50', '0x4e', '0x47', '0xd', '0xa']
```
From the output, we can see that this is the magic bytes of a PNG file. Using the [PNG example](https://en.wikipedia.org/wiki/Portable_Network_Graphics#Examples) from wikipedia, we can try to figure out more values of the flag.
### example.py
```python
enc = [0xe2, 0x21, 0x2d, 0x33, 0x6b, 0x71, 0x63, 0x3a, 0x75, 0x5f, 0x72, 0x3e, 0x2a, 0x78, 0x32, 0x61, 0x72, 0x33, 0x67, 0xe1, 0x6d, 0x79, 0x5b, 0xc9, 0x3c, 0x33, 0x37, 0x33, 0x72, 0x34, 0xa5, 0xe5, 0x11, 0x33, 0x21, 0x53, 0x55, 0x36, 0x20, 0x77, 0x3e, 0x16, 0x2e, 0x77, 0x4b, 0x63, 0x2d, 0x5c, 0x52, 0x1b, 0x59, 0x3a, 0x62, 0x6c, 0x7b, 0xba, 0xf1, 0xc8, 0x33, 0x32, 0xa3, 0x70, 0x73, 0xf3, 0x9d, 0x42, 0xfd, 0x10, 0xd5, 0x6e, 0x79]
png = [0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, 0x00, 0x00, 0x00, 0x0D, 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x08, 0x02, 0x00, 0x00, 0x00, 0x90, 0x77, 0x53, 0xDE, 0x00, 0x00, 0x00, 0x0C, 0x49, 0x44, 0x41, 0x54, 0x08, 0xD7, 0x63, 0xF8, 0xCF, 0xC0, 0x00, 0x00, 0x03, 0x01, 0x01, 0x00, 0x18, 0xDD, 0x8D, 0xB0, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4E, 0x44, 0xAE, 0x42, 0x60, 0x82]
arr = []
for i, x in enumerate(enc):
if i < len(png):
arr.append(chr(x ^ png[i]))
print(arr)
```
```bash
$ python3 example.py
['k', 'q', 'c', 't', 'f', '{', 'y', '0', 'u', '_', 'r', '3', 'c', '0', 'v', '3', 'r', '3', 'g', 'à', 'm', 'y', '[', 'È', '4', '1', '7', '3', 'r', '¤', 'Ò', '¶', 'Ï', '3', '!', 'S', 'Y', '\x7f', 'd', '6', 'j', '\x1e', 'ù', '\x14', '³', '¬', 'í', '\\', 'R', '\x18', 'X', ';', 'b', 't', '¦', '7', 'A', 'È', '3', '2', '£', '9', '6', '½', 'Ù', 'ì', '¿', 'p', 'W']
```
The output shows that the first 18 values of the arr is correct but the rest is incorrect. We can guess that "r3c0v3r3d" is going to be the second word in the flag so the 19th value in enc must be xor'd with a value that will result in 'd'. We can also guess that "my" is going to be the third word in the flag. Since the second word ends at the 19th value and the third word starts at the 21st value, the 20th value must be '\_'.
```
Python 3.9.7 (default, Oct 12 2021, 22:38:23)
[Clang 13.0.0 (clang-1300.0.29.3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> enc = [0xe2, 0x21, 0x2d, 0x33, 0x6b, 0x71, 0x63, 0x3a, 0x75, 0x5f, 0x72, 0x3e, 0x2a, 0x78, 0x32, 0x61, 0x72, 0x33, 0x67, 0xe1, 0x6d, 0x79, 0x5b, 0xc9, 0x3c, 0x33, 0x37, 0x33, 0x72, 0x34, 0xa5, 0xe5, 0x11, 0x33, 0x21, 0x53, 0x55, 0x36, 0x20, 0x77, 0x3e, 0x16, 0x2e, 0x77, 0x4b, 0x63, 0x2d, 0x5c, 0x52, 0x1b, 0x59, 0x3a, 0x62, 0x6c, 0x7b, 0xba, 0xf1, 0xc8, 0x33, 0x32, 0xa3, 0x70, 0x73, 0xf3, 0x9d, 0x42, 0xfd, 0x10, 0xd5, 0x6e, 0x79]
>>> hex(enc[19 - 1] ^ ord('d'))
'0x3'
>>> hex(enc[20 - 1] ^ ord('_'))
'0xbe'
```
Based on the output, the 19th key value must be 0x3 and the 20th key must be 0xbe. The 19th and 20th bytes of a PNG file are the bytes for the width of the PNG.
```
Python 3.9.7 (default, Oct 12 2021, 22:38:23)
[Clang 13.0.0 (clang-1300.0.29.3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> 0x3be
958
```
The width of the PNG must be 958. The width of [Underscore_in_C](Underscore_in_C.png) is also 958 so we can try to use the bytes of Underscore_in_C as the keys.
## Solution
### solve.py
```python
# The enc array contains the hex values of ohno.png
# The key array contains the hex values of Underscore_in_C.png
enc = [0xe2, 0x21, 0x2d, 0x33, 0x6b, 0x71, 0x63, 0x3a, 0x75, 0x5f, 0x72, 0x3e, 0x2a, 0x78, 0x32, 0x61, 0x72, 0x33, 0x67, 0xe1, 0x6d, 0x79, 0x5b, 0xc9, 0x3c, 0x33, 0x37, 0x33, 0x72, 0x34, 0xa5, 0xe5, 0x11, 0x33, 0x21, 0x53, 0x55, 0x36, 0x20, 0x77, 0x3e, 0x16, 0x2e, 0x77, 0x4b, 0x63, 0x2d, 0x5c, 0x52, 0x1b, 0x59, 0x3a, 0x62, 0x6c, 0x7b, 0xba, 0xf1, 0xc8, 0x33, 0x32, 0xa3, 0x70, 0x73, 0xf3, 0x9d, 0x42, 0xfd, 0x10, 0xd5, 0x6e, 0x79]
key = [0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x03, 0xbe, 0x00, 0x00, 0x04, 0xa4, 0x08, 0x06, 0x00, 0x00, 0x00, 0x44, 0x94, 0xd6, 0x72, 0x00, 0x00, 0x0c, 0x64, 0x69, 0x43, 0x43, 0x50, 0x49, 0x43, 0x43, 0x20, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x00, 0x00, 0x48, 0x89, 0x95, 0x97, 0x07, 0x5c, 0x93, 0x47, 0x1b, 0xc0, 0xef, 0x1d, 0x99, 0x24, 0xac, 0x40, 0x04]
# The arr array contains the xor of enc and key values
# The for loop loops over the contents of enc and appends the value of enc[index] ^ key[index] to arr
arr = []
for i, x in enumerate(enc):
arr.append(chr(x ^ key[i]))
# Prints out arr which is the flag
print("".join(arr))
```
```bash
$ python3 solve.py
kqctf{y0u_r3c0v3r3d_my_m4573rp13c3!_1_c4n_m4k3_34r5_bl33d_4n07h3r_d4y.}
```