Skip to content

Commit

Permalink
Added ATR HAX CTF 2021
Browse files Browse the repository at this point in the history
  • Loading branch information
Sam Quinn authored and Sam Quinn committed Mar 9, 2021
0 parents commit 25f16a6
Show file tree
Hide file tree
Showing 154 changed files with 21,502 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
**/.DS_Store
46 changes: 46 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# McAfee ATR Capture the Flag
## 2021 ATRHAX CTF Challenges

Based on feedback from our many CTF players, we've decided to release solutions for each of our CTF challenges. We thought it would be fun to provide solutions from one of the winning teams from our internal competition in late 2019 (these are the same challenges used in our public CTF from February 2021). You may have found a different solution as well, which is the entire point of these. Hope you enjoyed and look forward to a strong showing in our 2021-2022 public CTF.

### Crypto
**100 Points**
- [Light switch crypto](crypto/light_switch_crypto/)

**200 Points**
- [IVe seen sites like this before](crypto/ive_seen_sites_like_this_before/)
- [Know your header (Part I)](crypto/know_your_header_part1/)

**400 Points**
- [One time only](crypto/one_time_only/)
### Exploitation
**500 Points**
- [A winning attitude](exploitation/a_winning_attitude/)
- [Shellcode hollaback](exploitation/shellcode_hollaback/)
### Forensics
**200 Points**
- [Password in a haystack](forensics/password_in_a_haystack/)

**300 Points**
- [Not software not hardware](forensics/not_software_not_hardware/)
### Hardware
**200 Points**
- [Shack the secret](hardware/shack_the_secret/)
### Mobile
**100 Points**
- [Looking for droids?](mobile/looking_for_droids/)
### Recon
**200 Points**
- [A picture is worth a thousand vulns](recon/a_picture_is_worth_a_thousand_vulns/)
### Reversing
**300 Points**
- [Know your header (Part II)](reversing/know_your_header_part2/)

**400 Points**
- [Twos company](reversing/twos_company/)
### RF
**400 Points**
- [Smell Like Ham to You?](RF/smell_like_ham_to_you/)
### Web
**100 Points**
- [A dns query to rule them all](web/a_dns_query_to_rule_them_all/)
3 changes: 3 additions & 0 deletions RF/smell_like_ham_to_you/.hint
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
gqrx is your friend when it comes to SDR.

Remember, many radio frequencies are used for specific activities and data modes. You'll find that many encodings can be used, some Morse so than others. Some frequencies are for sending digital media. SSTV is often used to transmit images via radio.
13 changes: 13 additions & 0 deletions RF/smell_like_ham_to_you/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Smell Like Ham to You?

### 400 Points

## Description
You find 3 files of the form #_samplerate_frequency_bandwidth.iq:
- [1_2Msps_50.090MHz_2MHz.iq.tar.bz2](https://atr-repo.s3-us-west-2.amazonaws.com/atrhax_2021/rf/smell_like_ham_to_you/1_2Msps_50.090MHz_2MHz.iq.tar.bz2)
- [2_xMsps_xMHz_xMHz.iq.tar.bz2](https://atr-repo.s3-us-west-2.amazonaws.com/atrhax_2021/rf/smell_like_ham_to_you/2_xMsps_xMHz_xMHz.iq.tar.bz2)
- [3_xMsps_xMhz_xMHz.iq.bz2](https://atr-repo.s3-us-west-2.amazonaws.com/atrhax_2021/rf/smell_like_ham_to_you/3_xMsps_xMHz_xMHz.iq.bz2)

These files were captured over the air via a software-defined radio. You have a suspicion these broadcasts contain valuable information. As such, you have decided to try to determine the contents of each file.

NOTE: The format of the flag is ATR\[\], for example: ATR\[foobar\]. The flag must be submitted in full, including the ATR and square bracket parts.
34 changes: 34 additions & 0 deletions RF/smell_like_ham_to_you/SOLUTION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Solution Write Up to Smell Like Ham to You?

The first clue is 50.090Mhz given in the filename (1_2Msps_50.090MHz_2MHz.iq). A ham radio
operator would expect CW at 50.090Mhz in the 6M band.
The first tool will be GQRX convert the “.iq” files to audio.

[http://gqrx.dk](http://gqrx.dk)

With the morse code identified, fldigi can be used to decode the morse code.
[http://www.w1hkj.com/files/fldigi/](http://www.w1hkj.com/files/fldigi/)

Sample 1 CW Decoded: SAMPLE 2 WAS CAPTURED AT 146520KHZ SAMPRATE 2M
![Morse Code](assets/images/00.png)
**Figure:** Sample 1 Morse Code decode with fldigi

With the second clue, I expect FM simplex at 146.520Mhz on the 2M band. This was close,
although it turned out that AM voice was discovered. This was played with GQRX.

This clue provided: "THE THIRD FILE WAS CAPTURED AT 7.171MHZ AND 2.5MSPS"

For Sample 3, this is expected to be 7.171Mhz of the 40M ham radio band.
[https://en.wikipedia.org/wiki/Amateur_radio_frequency_allocations](https://en.wikipedia.org/wiki/Amateur_radio_frequency_allocations)

At 7.171Mhz, we expect CW, RTTY, data, phone and image. As a ham radio operator, I expected
this may be SSTV. I compared some known waterfalls and audio samples to further confirm that this is SSTV.
[http://www.hfradio.org.uk/html/digital_modes.html](http://www.hfradio.org.uk/html/digital_modes.html)

Finally, with GQRX playing the “.iq” sample, I decoded the SSTV via MultiScan 3B
\(Scottie/Scottie1\).
\(MultiScan 3B: [https://www.qsl.net/kd6cji/](https://www.qsl.net/kd6cji/)\)

At first, the center frequency tuning was slightly off. A second decode yielded better results providing the flag.
![Multiscan 3B](assets/images/01.png)
**Figure:** Sample 3 GQRX and SSTV decoding via MultiScan 3B
Binary file added RF/smell_like_ham_to_you/assets/images/00.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added RF/smell_like_ham_to_you/assets/images/01.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions crypto/ive_seen_sites_like_this_before/.hint
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
What happens when you modify parameters? Some encryption algorithms encrypt in static “blocks” measured in bytes. Which block contains the UID? What user ID may have access to all pages?
12 changes: 12 additions & 0 deletions crypto/ive_seen_sites_like_this_before/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# IVe seen sites like this before

### 200 Points

## Description
This webserver seems to enforce restrictions on users, can you find a way in?


NOTE: The format of the flag is ATR\[\], for example: ATR\[foobar\]. The flag must be submitted in full, including the ATR and square bracket parts.

## Hint
The hint is in the file ".hint"
21 changes: 21 additions & 0 deletions crypto/ive_seen_sites_like_this_before/SOLUTION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Solution Write Up to I've Seen Sites Like This Before!

Upon loading link 1, there appear to be some clues in the HTML source code.
![Developer comments in HTML source code](assets/images/00.png)
**Figure:** Developer comments in HTML source code

![Error message displayed via link1](assets/images/01.png)
**Figure:** Error message displayed via link1

By manipulating the “iv=” parameter, we get addition error output.
![Error output “invalid IV length”](assets/images/02.png)
**Figure:** Error output “invalid IV length”

By changing the last two digits of the “iv” parameter to 00, the UID changes to 27.

iv=f15188446e6e3100
![UID changed to 27](assets/images/03.png)
**Figure:** UID changed to 27

By changing the last two digits of the “iv” parameter to 27, the flag was revealed!
![flag](assets/images/04.png)
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions crypto/ive_seen_sites_like_this_before/docker/.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
node_modules
npm-debug.log
solution.txt
10 changes: 10 additions & 0 deletions crypto/ive_seen_sites_like_this_before/docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
FROM node:10

WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
RUN npm ci --only=production
COPY login.html ./
COPY server.js ./
EXPOSE 8080
CMD ["node", "server.js"]
10 changes: 10 additions & 0 deletions crypto/ive_seen_sites_like_this_before/docker/login.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<!DOCTYPE html>
<html>
<body>
<img src="iVBarslogo.png">
<h2>You need to get in</h2>
<p class="iv"></p>
<script type="text/javascript" src="https://cdn.rawgit.com/ricmoo/aes-js/e27b99df/index.js"></script>
<script src="cbc.js"> </script>
</body>
</html>
13 changes: 13 additions & 0 deletions crypto/ive_seen_sites_like_this_before/docker/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"name": "ATR_CTF_Bitflip",
"version": "1.0.0",
"description": "Node.js on Docker",
"author": "Sam Quinn <[email protected]>",
"main": "server.js",
"scripts": {
"start": "node server.js"
},
"dependencies": {
"express": "^4.16.1"
}
}
63 changes: 63 additions & 0 deletions crypto/ive_seen_sites_like_this_before/docker/server.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
'use strict';

const express = require('express');
const crypto = require('crypto');

// Constants
const PORT = 8080;
const HOST = '0.0.0.0';
const KEY = 'af1dd3e67233248d30690ab0614b3fdf';
const algorithm = 'aes-256-cbc';
const newiv = 'f15188446e6e3167'

function encrypt(text) {
let cipher = crypto.createCipheriv('aes-256-cbc', KEY, newiv);
let encrypted = cipher.update(text);
encrypted = Buffer.concat([encrypted, cipher.final()]);
return { iv: newiv, encryptedData: encrypted.toString('hex')};
}

function decrypt(iv, text) {
let encryptedText = Buffer.from(text, 'hex');
let decipher = crypto.createDecipheriv(algorithm, KEY, iv);
let decrypted = decipher.update(encryptedText);
decrypted = Buffer.concat([decrypted, decipher.final()]);
return decrypted.toString();
}

// App
const app = express();
app.get('/', (req, res) => {
//res.redirect('http://' + HOST + ':' + PORT + '/login?iv=104fb073f9a131f2cab49184bb864ca2&session=d71100525e8655b19792e0331a3b741a')
res.redirect('http://challenges.ctfd.io:30459/login?iv=f15188446e6e3167&session=bbf6ad986ed574e8949d7b7e9348f38c4d1d93ab85062c3f168b1c82b7279845')
});

app.get('/login', (req, res) => {
var out = decrypt(req.query.iv, req.query.session);
var split_txt = out.split('||');

res.writeHeader(200, {"Content-Type": "text/html"});
res.write('<!DOCTYPE html>\n');
res.write('<html>\n');
res.write('<body>\n');
res.write('<h2>This is a restricted page only authorized users can access it</h2>\n');
if (split_txt[1] == '00') {
res.write('<h1>Welcome "root" here is the flag</h1>\n');
res.write('<p>ATR[Crypt0IsAsGoodAsTheImplementation]</p>\n');
}
res.write('<br>\n');
res.write('<b>Current User: ' + split_txt[0] + ' UID: ' + split_txt[1] + '</b>\n');
res.write('</body>\n');
res.write('<!-- Changelog -->\n');
res.write('<!-- 09/15/2018 - Changed from DES to AES-256-CBC after our latest data breach -->\n');
res.write('<!-- 05/23/2018 - Todd is and idiot and somehow never knows how to login so I have added the encryption IV and the encrypted session to the URL parameters -->\n');
res.write('<!-- 03/12/2018 - String compare of the users is acting up I found a different way to validate users -->\n');
res.write('<!-- 02/08/2018 - Moved the default user from root to unprivlaged users. This way only admins can access this page -->\n');
res.write('</html>\n');
res.end();
});



app.listen(PORT, HOST);
console.log(`Running on http://${HOST}:${PORT}`);
3 changes: 3 additions & 0 deletions crypto/know_your_header_part1/.hint
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Learn about executable file headers and known plain text attacks.

Read the readme file and the comments in the python script. They are there to help. The python file gives an explanation of encoding using XOR. Use the hint file and encoded file with what you have learned.
18 changes: 18 additions & 0 deletions crypto/know_your_header_part1/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Know your header (Part I)

### 200 Points

## Description
The next challenge was encoded and we don't know the key.
We were able to recover the script used to encode the challenge and a hint binary.

What we know is that it is a Linux binary running on a x64 Ubuntu 18.04.
Maybe by looking at the encoding algorithm and the hint binary you can figure out how to decode it?

The flag for this challenge is the ATR[key] where key is the key you found, in hex, and lower case
(for example, if the key is 5566778899aabbcc, the flag will be ATR[5566778899aabbcc])

Good luck!

## Hint
The hint is in the file ".hint"
25 changes: 25 additions & 0 deletions crypto/know_your_header_part1/SOLUTION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Solution Write Up for Know Your Header (Part 1)

1. Xor'ed the first 10 bytes of the encrypted file and the hint together, until the resulting
number pattern started repeating. Resulting key: 9f05a8dd940a15dd
2. Used the key to decrypt the program with the provided decrypt program
3. Ran the program and it worked
4. Input the key into the Ctf as the flag

```python
#!/usr/bin/env python3
with open("challenge_encoded","rb") as f:
enc = f.read()

with open("hint", "rb") as f:
hint = f.read()

keylen=8
vals = [x ^ y for x,y in zip(enc[:keylen],hint[:keylen])]
key = [format (x, "02x") for x in bytearray(vals)]
print (''.join(key))
```

Output from ./decode.py is 9f05a8dd940a15dd which can be submitted as flag with
**ATR[9f05a8dd940a15dd]**.

Binary file not shown.
76 changes: 76 additions & 0 deletions crypto/know_your_header_part1/challenge/encode.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
#!/usr/bin/env python2
import sys


def encode(data, key):

# Initialize the return value of the function to an empty string
res = ""

# Iterate over all the bytes in data
for i in xrange(0, len(data)):
# Get the i-th character in the data
c = data[i]

# Get the i-th character of the key (modulo the length of the key)
# Fore example, if the key length is 10 characters, and i is 12, (i % 10) equals 2
# We do that so that when we reach the end of the key, we loop back to the begining
k = key[i % len(key)]

# ord converts a character into its ascii value (i.e. a number)
# chr converts an ascii value (a number < 256) into a character (a byte)
# ^ is the xor operator
# Info about xor:
# a ^ a = 0 (every value is its own opposite)
# a ^ b = b ^ a (the order does not matter)
# a ^ b ^ c = c ^ b ^ a = ... (same with more values)
# 0 ^ a = a (xoring with 0 doesn't change the value)

encoded_val = chr(ord(c) ^ ord(k))
res += encoded_val
return res






if __name__ == "__main__":

# Verifiy the arguments passed to the script
# are ok.
if len(sys.argv) < 4:
print "Usage: {} key_hex input output".format(sys.argv[0])
sys.exit(-1)
if (len(sys.argv[1]) % 2 == 1):
print "Invalid key length. It needs to be an even number."
sys.exit(-1)

# Converts the hex representation of a string into the actual bytes
key = sys.argv[1].decode("hex")

if (len(key) > 8):
print "This version of the encoder only works with short keys"
sys.exit(-1)

input_file = sys.argv[2]
output_file = sys.argv[3]

# Open the file
# rb means reading in binary mode
with open(input_file, "rb") as f:
data = f.read()

# Now we encode the data using the key we've read
encoded_data = encode(data, key)

# Open or create the output fule
# wb means writing binary data
with open(output_file,"wb") as f:
f.write(encoded_data)






Binary file not shown.
1 change: 1 addition & 0 deletions crypto/light_switch_crypto/.hint
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
When viewing the circuit diagram, does a 3-way switch implementation resemble a logic gate?
11 changes: 11 additions & 0 deletions crypto/light_switch_crypto/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Light Switch Crypto

### 100 Points

## Description
Here is a 3-way light switch. Look closely, it may help you uncover the secret message! Solve the secretly coded message to capture the flag!

NOTE: The format of the flag is ATR\[\], for example: ATR\[foobar\]. The flag must be submitted in full, including the ATR and square bracket parts.

## Hint
The hint is in the file ".hint"
Loading

0 comments on commit 25f16a6

Please sign in to comment.