# Level 3 - Needle in a Greystack

> An attack was detected on an internal network that blocked off all types of executable files. How did this happen?\
> \
> Upon further investigations, we recovered these 2 grey-scale images. What could they be?

**Disclaimer:** I did not manage to fully solve this during the competition itself. I did shortly after (an hour after the CTF), though, with the help of my friend Rainbowpigeon :smile:

### Understanding the BMP Files

I noticed early on that `1.bmp` was essentially a Windows executable, but split into chunks with the order reversed. This is pretty obvious given the `MZ` and `PE` file signatures at the end. This allowed me to successfully recover the executable, but as we will see later, was insufficient for me to solve the challenge.

I did not notice that these 'chunks' were essentially the different bitmap lines, which 010 Editor would generously show me!

![](https://3167364547-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MX1bWRlBzHpEPe1TYDD%2Fuploads%2Fgit-blob-087b6fdae160209397c95b030265eb713620d104%2FScreenshot%202021-11-19%20at%206.54.26%20PM.png?alt=media)

These lines consist of data followed by some padding (null bytes).

![](https://3167364547-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MX1bWRlBzHpEPe1TYDD%2Fuploads%2Fgit-blob-403d319bf78212672df4aaf45c74f19a6e8d8c84%2FScreenshot%202021-11-19%20at%207.04.19%20PM.png?alt=media)

Extracting the data (in reverse order) and removing the padding bytes thus gives us the executable.

```python
chunk_size = 148

with open('decoded' ,'rb') as infile, open('out.txt', 'wb') as outfile:
	data = infile.read()
	i = len(data) - chunk_size
	
	while i > 0:
		outfile.write(data[i:i + chunk_size][:-3])
		i -= chunk_size
		
	outfile.write(data[:chunk_size])
```

### Understanding the Executable

First of all, we need a `.txt` file as an argument.

![Checking the File Extension](https://3167364547-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MX1bWRlBzHpEPe1TYDD%2Fuploads%2Fgit-blob-efbe4cad4f428c24fa049d0102dc2bba843b93c3%2FScreenshot%202021-11-19%20at%207.11.26%20PM.png?alt=media)

Failing which, the file will not be read!

![Reading the File](https://3167364547-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MX1bWRlBzHpEPe1TYDD%2Fuploads%2Fgit-blob-30a5958a4f3572a03f7d7841c8e13a58d8c1ad22%2FScreenshot%202021-11-19%20at%207.14.16%20PM.png?alt=media)

Upon reading the file, its contents will then go thorugh a decoding algorithm (we don't actually need to know how it works for the purpose of this challenge).

![Decoding the File Contents](https://3167364547-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MX1bWRlBzHpEPe1TYDD%2Fuploads%2Fgit-blob-3199668e086dc0bdbd8703ffc5239dbc74d2f34c%2FScreenshot%202021-11-19%20at%207.18.00%20PM.png?alt=media)

Once decoded, a second function is called. The decoded buffer must then start with 0x5A4D (i.e. `MZ`), otherwise the function exits.

![Checking the Magic Bytes](https://3167364547-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MX1bWRlBzHpEPe1TYDD%2Fuploads%2Fgit-blob-2d43e7f1ed257bc36e93be97f1831564da67afe5%2FScreenshot%202021-11-19%20at%207.22.27%20PM.png?alt=media)

Subsequently, a DLL is loaded. Given that the decoded buffer must start with `MZ`, it is clear that we have to make our input file successfully decode into a DLL in memory, which is then executed.

![](https://3167364547-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MX1bWRlBzHpEPe1TYDD%2Fuploads%2Fgit-blob-f128d085d564ec1ecc1bc6a29440aedbf10ea05c%2FScreenshot%202021-11-19%20at%207.25.08%20PM.png?alt=media)

I figured this much out during the competition, but the missing piece was finding an appropriate input file that will decode successfully. Supplying the contents of `2.bmp` yielded the `MZ` file signature *somewhere* in the decoded contents, but not at the start as was expected.

It turns out that `2.bmp` followed the same structure as `1.bmp`, and with the newfound knowledge about the bitmap file structure, I only had to tweak the previous script to accomodate the line and padding sizes of this second bitmap file.

![](https://3167364547-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MX1bWRlBzHpEPe1TYDD%2Fuploads%2Fgit-blob-0d08387c2428c8d5e25efbfd1041a96a0f0a05ed%2FScreenshot%202021-11-19%20at%207.30.56%20PM.png?alt=media)

```python
chunk_size = 100

with open('2.bmp' ,'rb') as infile, open('out.txt', 'wb') as outfile:
	data = infile.read()
	i = len(data) - chunk_size
	
	while i > 0:
		outfile.write(data[i:i + chunk_size][:-1])
		i -= chunk_size
		
	outfile.write(data[:chunk_size])
```

Great, we have some progress!

![](https://3167364547-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MX1bWRlBzHpEPe1TYDD%2Fuploads%2Fgit-blob-d0fc76221ad5576f509134dfec1488a18bb9da37%2FScreenshot%202021-11-19%20at%207.33.35%20PM.png?alt=media)

We want to know what the DLL is doing, so let's set a breakpoint and dump the decoded DLL from memory.

![Decoded DLL in Memory](https://3167364547-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MX1bWRlBzHpEPe1TYDD%2Fuploads%2Fgit-blob-76b4b2481dfea5ac89de427e6c0fe53f2d8bda0b%2FScreenshot%202021-11-19%20at%207.40.06%20PM.png?alt=media)

A `key.txt` file is required.

![](https://3167364547-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MX1bWRlBzHpEPe1TYDD%2Fuploads%2Fgit-blob-f05ecf805d80e97643c51aaa9bbfe07a4bb72f6e%2FScreenshot%202021-11-19%20at%207.57.27%20PM.png?alt=media)

Now, the un-decoded version of `2.bmp` looks conspicuously like a wordlist... and it turns out that while I was staring at the "wrong" stuff and trying to figure out its purpose, I had already stumbled upon what looks like a key!

![](https://3167364547-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MX1bWRlBzHpEPe1TYDD%2Fuploads%2Fgit-blob-eff45055679327f09295cbf2d45f22f37c19f725%2FScreenshot%202021-11-19%20at%208.01.15%20PM.png?alt=media)

With the correct key file, we get the flag.

![](https://3167364547-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MX1bWRlBzHpEPe1TYDD%2Fuploads%2Fgit-blob-01ccafca6887851bc6e3c3eea3d2aeee015f22f4%2FScreenshot%202021-11-19%20at%208.02.43%20PM.png?alt=media)
