PATRIOT CTF 2024
Published:
Introduction

PatriotCTF is a beginner-friendly capture-the-flag competition hosted by GMU’s cybersecurity club, MasonCC. All are welcome to participate, including students and security professionals. Challenges will range from beginner to expert, so there should be something for everyone. This is a jeopardy-style CTF, meaning there will be various challenges from the different categories described below.
Forensic
- Slingshot
Author: AJ Hoepfner (greatvaluerice)
Description:
The challenge gives us a
.pcapng
file. Let’s analyze it! The first, I check Protocol Hierarchy Statistics.It showed 100% of the packet is TCP, so I filtered HTTP first.
Then, i export this
.pyc
file and uncompiled it. I got the.py
with content:import sys import socket import time import math s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) file = sys.argv[1] ip = sys.argv[2] port = 22993 with open(file, 'rb') as r: data_bytes = r.read() current_time = time.time() current_time = math.floor(current_time) key_bytes = str(current_time).encode('utf-8') init_key_len = len(key_bytes) data_bytes_len = len(data_bytes) temp1 = data_bytes_len // init_key_len temp2 = data_bytes_len % init_key_len key_bytes *= temp1 key_bytes += key_bytes[:temp2] encrypt_bytes = bytes((a ^ b for a, b in zip(key_bytes, data_bytes))) s.connect((ip, port)) s.send(encrypt_bytes)
The code opens the secret file in binary read mode
('rb')
and reads its contents into a byte stringdata_bytes
.The current time is obtained using time.time() and converted to an integer using math.floor(). This integer is then converted to a byte string
key_bytes
using the encode() method with the ‘utf-8’ encoding.The code calculates the length of the key
init_key_len
and the length of the datadata_bytes_len
. It then calculates the number of times the key needs to be repeated to match the length of the datatemp1
and the remaining bytestemp2
.The key is repeated
temp1
times and then padded with the firsttemp2
bytes of the key to match the length of the data.Then the code uses a generator expression to perform a byte-wise XOR operation between the key and the data, resulting in an encrypted byte string
encrypt_bytes
. Finally send it to some ip with port22993
.Continuously, i filtered the packet with port
22993
and havedata
Nice, i found 3 packets was send. So let’s extract all of them by using this command:
tshark -r Slingshot.pcapng -Y ‘tcp.port ==22993 and data and data.len!=1’ -T fields -e data > data.enc
Next step is find timestamp or key. It is the epoch time when the first packet send.
Nice, i got all things to decrypt the flag. Here is my code:
from datetime import datetime import math with open("data.enc") as f: total_hex = "".join([line.strip() for line in f.readlines()]) encrypted_bytes = bytes.fromhex(total_hex) current_time = 1726595769.063377000 current_time = math.floor(current_time) key_bytes = str(current_time).encode('utf-8') init_key_len = len(key_bytes) data_bytes_len = len(encrypted_bytes) temp1 = data_bytes_len // init_key_len temp2 = data_bytes_len % init_key_len key_bytes *= temp1 key_bytes += key_bytes[:temp2] decrypted_bytes = bytes(a ^ b for a, b in zip(key_bytes, encrypted_bytes)) image_filename = 'decrypted_image.jpg' with open(image_filename, 'wb') as f: f.write(decrypted_bytes) print("Done")
Flag:
### Conslusion:
- Export the encrypt code
- Filter to extract data and timestamp
- Decrypt flag
# Updating…