Field Laptop
Overview
A 20MB disk image. The first 10MB is a normal ext2 partition with decoy files and two geotagged photos. The second 10MB is a hidden encrypted region, no partition table entry or filesystem label. A hint in the visible partition tells you where to look. The encryption key is derived from EXIF coordinates in the photos. The encryption parameters are self-documented in the hidden region's header, no external script needed.
Step 1: Mount and explore the visible partition
sudo mount -o loop,ro,offset=0 field_laptop.img /mnt/visible
ls -la /mnt/visible/
# Documents/ Pictures/ Desktop/ .config/
Read .config/hints.txt:
Storage layout:
visible region: offset 0x000000 (10 MB)
classified region: offset 0xA00000 (10 MB)
Classified region passphrase derivation:
Read GPS from field photos in Pictures/
Format: <lat_from_photo1>_<lon_from_photo2>
Encryption parameters are in the classified region header.
Inspect the first 128 bytes of the extracted blob.
Two jobs: get the passphrase from the photos, get the crypto params from the blob.
Step 2: Extract EXIF coordinates from the photos
exiftool /mnt/visible/Pictures/photo1.jpg | grep -i GPS
exiftool /mnt/visible/Pictures/photo2.jpg | grep -i GPS
Or with Python:
import piexif
def dms_to_decimal(dms, ref):
d = dms[0][0]/dms[0][1]
m = dms[1][0]/dms[1][1]
s = dms[2][0]/dms[2][1]
val = d + m/60 + s/3600
return -val if ref in (b'S', b'W') else val
for fname in ['photo1.jpg', 'photo2.jpg']:
exif = piexif.load(fname)
gps = exif['GPS']
lat = dms_to_decimal(gps[2], gps[1])
lon = dms_to_decimal(gps[4], gps[3])
print(f'{fname}: lat={round(lat,4)}, lon={round(lon,4)}')
48 deg 51' 23.76" N 2 deg 21' 7.92" E
decimal = degrees + minutes/60 + seconds/3600 So: 48 + 51/60 + 23.76/3600 = 48 + 0.85 + 0.0066 = 48.8566 And: 2 + 21/60 + 7.92/3600 = 2 + 0.35 + 0.0022 = 2.3522
Results:
- photo1.jpg: latitude 48.8566 (Paris)
- photo2.jpg: longitude 2.3522 (Paris)
Passphrase: 48.8566_2.3522
Step 3: Extract the hidden region
dd if=field_laptop.img bs=1M skip=10 of=hidden.bin
Step 4: Read the blob header for crypto parameters
xxd hidden.bin | head -6
0000 44 45 41 44 52 4f 50 5f 48 49 44 44 45 4e 5f 56 DEADROP_HIDDEN_V
0010 44 45 41 44 52 4f 50 5f 46 49 45 4c 44 5f 4f 50 DEADROP_FIELD_OP
0020 53 5f 53 41 4c 54 5f 56 31 00 50 42 4b 44 46 32 S_SALT_V1.PBKDF2
0030 2d 53 48 41 32 35 36 20 69 74 65 72 3d 31 30 30 -SHA256 iter=100
0040 30 30 30 00 XX XX XX XX XX XX XX XX XX XX XX XX 000.....[payload]
Or just strings hidden.bin | head:
DEADROP_HIDDEN_VDEADROP_FIELD_OPS_SALT_V1
PBKDF2-SHA256 iter=100000
Header layout:
| Offset | Length | Content |
|---|---|---|
| 0 | 16 | Magic: DEADROP_HIDDEN_V |
| 16 | 26 | Salt (null-terminated): DEADROP_FIELD_OPS_SALT_V1 |
| 42 | 26 | KDF string (null-terminated): PBKDF2-SHA256 iter=100000 |
| 68 | 4 | Payload length (LE uint32) |
| 72 | 16 | ChaCha20 nonce |
| 88 | N | Ciphertext |
Step 5: Decrypt
import struct
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms
from cryptography.hazmat.backends import default_backend
passphrase = b'48.8566_2.3522'
salt = b'DEADROP_FIELD_OPS_SALT_V1' # from blob header at offset 16
data = open('hidden.bin', 'rb').read()
plen = struct.unpack_from('<I', data, 68)[0]
nonce = data[72:88]
ct = data[88:88+plen]
kdf = PBKDF2HMAC(algorithm=hashes.SHA256(), length=32,
salt=salt, iterations=100000, backend=default_backend())
key = kdf.derive(passphrase)
cipher = Cipher(algorithms.ChaCha20(key, nonce), mode=None, backend=default_backend())
pt = cipher.decryptor().update(ct)
open('decrypted.img', 'wb').write(pt)
Step 6: Mount and read the flag
sudo mount -o loop decrypted.img /mnt/hidden
cat /mnt/hidden/flag.txt
The hidden partition also contains ops_log.txt with Nightjar field notes.
Flag: DEADROP{hidden_partition_hidden_life}
Key Takeaway
Hidden partitions don't need to appear in the partition table, they're just raw data at a known offset. The header here is self-describing by design, mimicking how real encrypted container formats (LUKS, VeraCrypt) store their parameters in-band. EXIF metadata in photos is a surprisingly common source of operational security failures in the field.