huge commit

This commit is contained in:
2026-03-09 21:44:25 +01:00
parent ab2e537520
commit d1017bae51
441 changed files with 3438154 additions and 1363 deletions

View File

@@ -0,0 +1,25 @@
Foremost version 1.5.7 by Jesse Kornblum, Kris Kendall, and Nick Mikus
Audit File
Foremost started at Sun Mar 1 04:19:15 2026
Invocation: foremost -t bmp -i virtual_machine_ram.bin
Output directory: /home/cato/ctf/2026/srdnlen_quals/forensic/chapter2/foremost/output
Configuration file: /etc/foremost.conf
------------------------------------------------------------------
File: virtual_machine_ram.bin
Start: Sun Mar 1 04:19:15 2026
Length: 128 MB (134221824 bytes)
Num Name (bs=512) Size File Offset Comment
0: 00103872.bmp 43 KB 53182464 (182 x 237)
1: 00104770.bmp 5 KB 53642672 (310 x 35)
2: 00146504.bmp 576 KB 75010048 (512 x 384)
Finish: Sun Mar 1 04:19:15 2026
3 FILES EXTRACTED
bmp:= 3
------------------------------------------------------------------
Foremost finished at Sun Mar 1 04:19:15 2026

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 576 KiB

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,23 @@
Foremost version 1.5.7 by Jesse Kornblum, Kris Kendall, and Nick Mikus
Audit File
Foremost started at Sun Mar 1 04:30:50 2026
Invocation: foremost -i result_a.bin -v
Output directory: /home/cato/ctf/2026/srdnlen_quals/forensic/chapter2/foremost/output
Configuration file: /etc/foremost.conf
------------------------------------------------------------------
File: result_a.bin
Start: Sun Mar 1 04:30:50 2026
Length: 576 KB (589824 bytes)
Num Name (bs=512) Size File Offset Comment
0: 00000511.ole 5 KB 262100
Finish: Sun Mar 1 04:30:50 2026
1 FILES EXTRACTED
ole:= 1
------------------------------------------------------------------
Foremost finished at Sun Mar 1 04:30:50 2026

View File

@@ -0,0 +1,35 @@
def find_the_armory(bmp_path, wav_path, search_string):
with open(bmp_path, 'rb') as f_bmp, open(wav_path, 'rb') as f_wav:
# Load raw data, skipping standard headers
bmp_data = f_bmp.read()[54:]
wav_data = f_wav.read()[44:]
target = search_string.encode()
# We slide the WAV (the key) against the BMP (the lock)
# to account for memory alignment/fragmentation
for offset in range(0, 5000): # Check first 5000 bytes for alignment
# Create a chunk of XORed data
test_len = min(len(bmp_data), len(wav_data) - offset)
if test_len < len(target): break
# Efficiently XOR and check for the string
# We only check a 1024 byte window for the keyword to save time
window = 1024
sample = bytes(bmp_data[i] ^ wav_data[i + offset] for i in range(min(test_len, window)))
if target in sample:
print(f"[*] ARMORY FOUND! Offset: {offset}")
print(f"[*] Preview: {sample[sample.find(target):sample.find(target)+50]}")
# Save the full decrypted result for this offset
full_decrypted = bytes(bmp_data[i] ^ wav_data[i + offset] for i in range(test_len))
with open(f"decrypted_offset_{offset}.bin", "wb") as f:
f.write(full_decrypted)
return True
return False
# Try running this with a few different potential keywords
print("Searching for flag...")
find_the_armory('./bmp_output/bmp/00146504.bmp', './wav_output/wav/00072813.wav', 'srdnlen')
# If 'srdnlen' fails, try 'flag', 'CTF', or 'CANNON' (based on your vNNON string)

View File

@@ -0,0 +1,24 @@
def sliding_xor(bmp_path, wav_path):
with open(bmp_path, 'rb') as f_bmp, open(wav_path, 'rb') as f_wav:
bmp_data = f_bmp.read()[54:] # Skip BMP header
wav_data = f_wav.read()[44:] # Skip WAV header
# We try shifting the WAV data slightly in case of alignment issues
for offset in range(0, 100):
shifted_wav = wav_data[offset:]
length = min(len(bmp_data), len(shifted_wav))
# XOR the first 4 bytes to check for headers
head = bytes(bmp_data[i] ^ shifted_wav[i] for i in range(4))
if b'PK' in head or b'MZ' in head or b'\x89PNG' in head:
print(f"Match found at offset {offset}! Header: {head}")
# Save the full result for the successful offset
result = bytes(bmp_data[i] ^ shifted_wav[i] for i in range(length))
with open(f'found_at_{offset}.bin', 'wb') as f:
f.write(result)
return
# Run against both potential audio relics
sliding_xor('./bmp_output/bmp/00146504.bmp', './wav_output/wav/00038872.wav')
sliding_xor('./bmp_output/bmp/00146504.bmp', './wav_output/wav/00072813.wav')

Binary file not shown.

View File

@@ -0,0 +1,27 @@
Foremost version 1.5.7 by Jesse Kornblum, Kris Kendall, and Nick Mikus
Audit File
Foremost started at Sun Mar 1 04:19:53 2026
Invocation: foremost -t wav -i virtual_machine_ram.bin -T wav
Output directory: /home/cato/ctf/2026/srdnlen_quals/forensic/chapter2/foremost/output_Sun_Mar__1_04_19_53_2026
Configuration file: /etc/foremost.conf
------------------------------------------------------------------
File: virtual_machine_ram.bin
Start: Sun Mar 1 04:19:53 2026
Length: 128 MB (134221824 bytes)
Num Name (bs=512) Size File Offset Comment
0: 00014799.wav 36 B 7577580
1: 00038872.wav 676 KB 19902464
2: 00056278.wav 36 B 28814684
3: 00072813.wav 676 KB 37280640
4: 00099048.wav 1 KB 50712576
Finish: Sun Mar 1 04:19:53 2026
5 FILES EXTRACTED
rif:= 5
------------------------------------------------------------------
Foremost finished at Sun Mar 1 04:19:53 2026

View File

@@ -0,0 +1,24 @@
import os
def carve_pe(filename, offsets):
if not os.path.exists(filename):
print(f"File {filename} not found.")
return
with open(filename, 'rb') as f:
data = f.read()
for i, offset in enumerate(offsets):
# Carve from the offset to the end of the file
# Most PE files in CTFs will have a trailing XOR or be the remainder of the blob
pe_data = data[offset:]
output_name = f"weapon_{filename}_{i}.exe"
with open(output_name, 'wb') as out:
out.write(pe_data)
print(f"[*] Extracted {output_name} from {filename} at offset {offset}")
# Offsets provided by your binwalk analysis
wav_1_offsets = [111744] # 0x1B480
wav_2_offsets = [57344, 73728, 200704, 241664, 303104, 593920] # 0xE000, 0x12000, etc.
carve_pe('00072813.wav', wav_1_offsets)
carve_pe('00038872.wav', wav_2_offsets)

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,20 @@
def extract_secret(bmp_path, wav_path, output_path):
with open(bmp_path, 'rb') as f_bmp, open(wav_path, 'rb') as f_wav:
# Skip BMP header (54 bytes) and WAV header (44 bytes)
bmp_pixels = f_bmp.read()[54:]
wav_samples = f_wav.read()[44:]
# We XOR the pixels with the audio samples.
# The clue "remember to XOR" suggests the key is the audio.
length = min(len(bmp_pixels), len(wav_samples))
secret = bytearray(bmp_pixels[i] ^ wav_samples[i] for i in range(length))
with open(output_path, 'wb') as f_out:
f_out.write(secret)
print(f"Attempted extraction using {wav_path} -> {output_path}")
# Run for both 676KB WAV files found in your audit
extract_secret('./bmp_output/bmp/00146504.bmp', './wav_output/wav/00038872.wav', 'result_a.bin')
extract_secret('./bmp_output/bmp/00146504.bmp', './wav_output/wav/00072813.wav', 'result_b.bin')