huge commit
This commit is contained in:
@@ -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
@@ -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
|
||||
Binary file not shown.
BIN
2026/srdnlen_quals/forensic/chapter2/foremost/result_a.bin
Normal file
BIN
2026/srdnlen_quals/forensic/chapter2/foremost/result_a.bin
Normal file
Binary file not shown.
BIN
2026/srdnlen_quals/forensic/chapter2/foremost/result_b.bin
Normal file
BIN
2026/srdnlen_quals/forensic/chapter2/foremost/result_b.bin
Normal file
Binary file not shown.
@@ -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)
|
||||
24
2026/srdnlen_quals/forensic/chapter2/foremost/sliding_xor.py
Normal file
24
2026/srdnlen_quals/forensic/chapter2/foremost/sliding_xor.py
Normal 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')
|
||||
BIN
2026/srdnlen_quals/forensic/chapter2/foremost/virtual_machine_ram.bin
(Stored with Git LFS)
Normal file
BIN
2026/srdnlen_quals/forensic/chapter2/foremost/virtual_machine_ram.bin
(Stored with Git LFS)
Normal file
Binary file not shown.
@@ -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
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -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
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
20
2026/srdnlen_quals/forensic/chapter2/foremost/xor_shit.py
Normal file
20
2026/srdnlen_quals/forensic/chapter2/foremost/xor_shit.py
Normal 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')
|
||||
Reference in New Issue
Block a user