Hello Navi

Tech, Security & Personal Notes

1
2
3
4
5
6
7
8
9
10
11
# get help
# command /?

# Pagination
A:\> dir /p

# Wide List Format
A:\> dir /w

# Piping to more
A:\> dir | more

cat.exe (type)

1
2
3
4
5
6
7
8
9
10
11
12
13
DOS          <DIR>         12-15-25   5:07p
COMMAND COM 54,645 05-31-94 6:22a
WINA20 386 9,349 05-31-94 6:22a
CONFIG SYS 71 12-15-25 5:07p
AUTOEXEC BAT 78 12-15-25 5:07p
FLAG TXT 60 04-02-26 5:07a
6 file(s) 64,203 bytes
10,428,416 bytes free

C:\>type flag.txt
pwn.college{QMkbfHdYCkFD_y-FmBdS66_cyD2.******************}

C:\>

ls.exe (dir)

DOS filenames were case-insensitive

DOS assumed that every file had a name of 8 characters or less and an "extension" (after the one allowed . in the filename) of 3 characters or less.

there is no permission or ownership information

As a side note, extensions were critical in DOS for similar reasons that they remain important in Windows: figuring out the type of file. Specifically for DOS, programs needed to be named with extensions of EXE (normal DOS executable), COM (simple, older executables that were basically just raw binary code), and BAT (a batch script containing commands to run, analogous to a weird variant of a typical shell script).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
Booting from Hard Disk...
Starting MS-DOS...


HIMEM is testing extended memory...done.
Batch file missing

C:\>dir

Volume in drive C is MS-DOS_6
Volume Serial Number is 5B8F-88E6
Directory of C:\

DOS <DIR> 12-15-25 5:07p
COMMAND COM 54,645 05-31-94 6:22a
WINA20 386 9,349 05-31-94 6:22a
CONFIG SYS 71 12-15-25 5:07p
FLG396 TXT 60 04-02-26 5:14a
5 file(s) 64,125 bytes
10,432,512 bytes free

C:\>type flg396.txt
pwn.college{c1dnzzEBipHvxFUOKeBsqnezrlb.******************}

C:\>

Changing Disks

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
Boot failed: could not read the boot disk

Booting from Hard Disk...
Starting MS-DOS...


HIMEM is testing extended memory...done.

C:\>C:\DOS\SMARTDRV.EXE /X
C:\>d:

D:\>dir

Volume in drive D has no label
Volume Serial Number is 409D-8F04
Directory of D:\

FLAG TXT 60 04-02-26 5:15a
1 file(s) 60 bytes
16,723,968 bytes free

D:\>type flag.txt
pwn.college{A_QSyVfCu23CuMIMATEp-popFEE.******************}

D:\>

Reading Floppies

floppy disks (软盘)

DOS assigned floppy drives the A: and B: drives, and "mounting" happened automatically on access (or, more specifically, there was no filesystem "mounting"; access just happened). The two letters were for computers that had both a 5.25" and a 3.5" floppy drive

load floppy in control panel

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
iPXE (http://ipxe.org) 00:03.0 CA00 PCI2.10 PnP PMM+00F91FB0+00EF1FB0 CA00



Booting from Floppy...
Boot failed: could not read the boot disk

Booting from Hard Disk...
Starting MS-DOS...


HIMEM is testing extended memory...done.

C:\>C:\DOS\SMARTDRV.EXE /X
C:\>a:

A:\>cat flag.txt
Bad command or file name

A:\>type flag.txt
pwn.college{USkPRtXd3nCSZPKf6MUGwdJLU8J.******************}

A:\>

Installing MS-DOS

use the provided floppies to install MS-DOS 6.22

since each floppy only holds 1.44mb, it was necessary to ship software in multiple floppies. MS-DOS 6.22 used three disks

load floppy in control panel from 0 to 2 and follow the wizard

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
SeaBIOS (version rel-1.17.0-0-gb52ca86e094d-prebuilt.qemu.org)


iPXE (http://ipxe.org) 00:03.0 CA00 PCI2.10 PnP PMM+00F91FB0+00EF1FB0 CA00



Booting from Floppy...
Boot failed: could not read the boot disk

Booting from Hard Disk...
Starting MS-DOS...


HIMEM is testing extended memory...done.

C:\>C:\DOS\SMARTDRV.EXE /X
C:\>a:

A:\>type flag.txt
pwn.college{gF-MZnE1WGsp7qf0RwDh0DJDe2c.******************}

A:\>

autoexec.bat

Any boot process includes not just the loading of the OS itself, but its initialization. In DOS, this was elegantly handled by autoexec.bat, a script that specified what commands would run when the system booted.

you can access the various menu items using your Alt key (e.g., Alt-F to open the File menu).

modify the file from del to type

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
SeaBIOS (version rel-1.17.0-0-gb52ca86e094d-prebuilt.qemu.org)


iPXE (http://ipxe.org) 00:03.0 CA00 PCI2.10 PnP PMM+00F91FB0+00EF1FB0 CA00



Booting from Floppy...
Boot failed: could not read the boot disk

Booting from Hard Disk...
Starting MS-DOS...


HIMEM is testing extended memory...done.

C:\>type c:\flag.txt
pwn.college{UBwCBfcUDi1W3W0o4QuVdHGB6rH.******************}

C:\>

doskey

Once doskey is loaded, you gain access to command history with up/down arrows and command line editing

上下箭头 :浏览命令历史记录 左右箭头 :在行内移动光标 F7 :在弹出窗口中显示命令历史记录 F9 :按编号选择命令

FUN FACT: doskey was introduced in MS-DOS 5.0 (1991) and was a game-changer for productivity. Before doskey, if you made a typo in a long command, you'd have to retype the whole thing!

edit and add doskey at top of autoexec.bat and quit relaunch

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
C:\>
C:\>echo pwn.college{
pwn.college{

C:\>echo 011NPLaz5mkZ
011NPLaz5mkZ

C:\>echo PSINV-xsu6g7
PSINV-xsu6g7

C:\>echo 7JI.********
7JI.********

C:\>echo **********}
**********}

C:\>

pwn.college{011NPLaz5mkZPSINV-xsu6g77JI.******************}

DOS Networking

install the packet drivers (make sure to specify the interrupt!) install and configure mtcp netcat to 192.168.13.37 port 1337 for the flag!

load pcnet floppy

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
PKTCHK   COM           856 01-28-92   9:58p
PKTMODE COM 1,728 01-28-92 9:58p
PKTMULTI COM 1,822 01-28-92 9:59p
PKTRING COM 2,420 01-28-92 9:59p
PKTSEND COM 2,346 01-28-92 9:59p
PKTSTAT COM 1,693 01-28-92 9:59p
PKTTRAF COM 6,019 01-28-92 9:59p
TERMIN COM 1,419 01-28-92 9:58p
TRACE COM 2,124 01-28-92 9:58p
WINPKT COM 3,617 01-28-92 9:59p
18 file(s) 116,641 bytes
192,512 bytes free

A:\PKTDRVR>pcntpk int=0x60
Packet driver for an PCNTPK, version 03.10
Packet driver skeleton copyright 1988-92, Crynwr Software.
This program is free software; see the file COPYING for details.
NO WARRANTY; see the file COPYING for details.

Packet driver is at segment 0BC8
Interrupt number 0xB (11)
I/O port 0xC000 (49152)
My Ethernet address is 52:54:00:12:34:56

A:\PKTDRVR>

load mtcp floppy

netcat to 192.168.13.37 port 1337 for the flag!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
set mtcpcfg=ftp.cfg

# need edit yourself
A:\>type ftp.cfg
PACKETINT 0x60
IPADDR 192.168.13.100
NETMASK 255.255.255.0
GATEWAY 192.168.13.1
NAMESERVER 192.168.13.1
MTU 1500

A:\>set mtcpcfg=ftp.cfg

A:\>nc -target 192.168.13.37 1337
mTCP Netcat by M Brutman (mbbrutman@gmail.com) (C)opyright 2007-2025
Version: Jan 10 2025

Resolving server address - press Ctrl-Break to abort

Server resolved to 192.168.13.37 - connecting

Connected!

pwn.college{sig-JqvzdYNSstfBBdU6WAW8lln.******************}

Elapsed time: 0.00 Bytes sent: 0 Received: 60

A:\>

An investigator recovered a Linux disk image from a manuscript ward workstation in Varanasi. The drive appears normal, but operators suspect hidden transfer records were concealed using layered steganography and encryption workflows.

Initial Exploration

The provided disk image (kashi_ritual_ledger.img) is an ext4 filesystem.

1
2
3
4
5
6
7
8
9
❯ file kashi_ritual_ledger.img
kashi_ritual_ledger.img: Linux rev 1.0 ext4 filesystem data, UUID=f83285e2-bb1a-4a34-bdec-b901cf985c4e, volume name "KASHI_LEDGER" (extents) (64bit) (large files) (huge files)

# Mount the image
sudo mkdir -p /mnt/kashi_ledger
sudo mount -o loop,ro kashi_ritual_ledger.img /mnt/kashi_ledger

# Search for hidden files
find /mnt/kashi_ledger -type f -name ".*"

Exploring the filesystem reveals several key files: - challenge_runtime.json: Metadata containing passphrases and AES parameters. - /home/pandit_ved/: User home directory with Pictures/ward_scans, Notes, and a hidden .archive_payloads folder. - /deleted_mail_pool/: Contains .eml files discussing "passphrase doctrine."

Metadata Analysis

Reading challenge_runtime.json provided the following stages: - Stage 1 Steg Passphrase: trishul-lantern-braid - Stage 2 Steg Phrase: ghat-manjari-copper-owl

Notes in home/pandit_ved/Notes/ritual_index_notes.md hinted that the "hidden ledger capsule is in one scan that does not open with the standard (Stage 1) phrase."

Steganography Extraction

There were four BMP scans in the ward_scans directory. Using steghide with the Stage 1 passphrase:

1
2
3
for f in /mnt/kashi_ledger/home/pandit_ved/Pictures/ward_scans/*.bmp; do
steghide extract -sf "$f" -p "trishul-lantern-braid"
done

While most contained decoy files, scan_midnight_index.bmp failed, indicating it required the Stage 2 passphrase:

1
2
steghide extract -sf scan_midnight_index.bmp -p "ghat-manjari-copper-owl"
# Output: wrote extracted data to "stage2_ledger.enc"

Locating the Flag

The extracted stage2_ledger.enc matched a file in the hidden .archive_payloads directory. A corresponding .txt file was also present:

1
cat /mnt/kashi_ledger/home/pandit_ved/.archive_payloads/stage2_ledger.txt

Flag

kashiCTF{ledger_ashes_remember_every_ritual}

We sent the same announcement to three servers for redundancy. Each server has its own RSA key. Intercept all three — maybe you can piece something together.

Initial Analysis

The challenge provides an output.txt containing an exponent \(e=3\), three moduli (\(n1, n2, n3\)), and three ciphertexts (\(c1, c2, c3\)). By examining the data, we notice:

  1. Low Exponent: \(e = 3\) is very small.
  2. Identical Ciphertexts: \(c1 = c2 = c3\). This means the raw message \(M\) was not padded differently for each server.
  3. Magnitude of \(c\): The ciphertext \(c\) is significantly smaller than any of the moduli \(n\).

In RSA, the encryption process is \(c = M^e \pmod n\). Usually, \(M^e\) is much larger than \(n\). However, if \(M^e < n\), then the modulo operation has no effect, and \(c = M^e\).

Solution

Since \(c < n_i\) and \(e=3\), the message \(M\) can be recovered simply by calculating the integer cube root of \(c\): \[M = \sqrt[3]{c}\]

Implementation

Using Python and the gmpy2 library, we can solve for \(M\):

1
2
3
4
5
6
7
8
9
10
11
12
13
import gmpy2
from binascii import unhexlify

# Intercepted ciphertext
c = 475436441896018898725156479190091126537849994697426945980826369000641892902004477923335055269088235139492237640527487698088281484953901383579636883543216552932099156009006828723690550706326538736801225046068870773990108130474408522838234755277972911893744937243892927414355347438993698991261629557719442242861719577879055371620865465785392597257968132649494474946507819896785671106833645551504301840437212737125

# Calculate the cubic root
m, exact = gmpy2.iroot(c, 3)

if exact:
# Convert integer to hex, then to ASCII
flag = unhexlify(hex(m)[2:]).decode()
print(f"Flag: {flag}")

Note: This challenge is a simplified version of Håstad's Broadcast Attack. While Håstad's attack typically uses the Chinese Remainder Theorem (CRT) to solve for \(M^e\) when \(M^e > n_i\), the small size of the message relative to the key size here allowed for a direct cubic root calculation.

Flag

kashiCTF{h4st4d_s4ys_sm4ll_3xp0n3nts_k1ll_RSA_br04dc4sts}

Join the RITSEC CTF Discord server to get the most up-to-date information about the competition. The flag can be found in the topic of the #announcements channel, or in the CTF kickoff announcement.

Initial Analysis

The challenge points to the RITSEC CTF Discord server as a source for competition updates and a hidden flag.

Solution

By checking the topic of the #announcements channel, the flag is readily available.

Flag

RS{p1r4t3_d1sc0rd}

A secret message has been passed down through generations since the time of the great Mahabharata war. Legend says that every 64 years, the keepers of this secret would encode the message once more to protect it from those who might seek to misuse its power. The message has traveled through 3136 years of history, from the ancient battlefields of Kurukshetra in 3136 BCE to the dawn of the Common Era.

Initial Analysis

The challenge provides two main clues:

  1. Mathematical Clue: The message has existed for 3136 years and was re-encoded every 64 years. \[\frac{3136}{64} = 49\] This suggests the message has been recursively encoded 49 times.
  2. File Inspection: The provided file secret_message.txt is large (~59MB) and starts with the characters Vm0wd2Qy..., which is a classic signature for multiple layers of Base64 encoding.

Extraction & Decoding

We can use a Python script to iteratively decode the file 49 times. Each layer of decoding reduces the file size until the final plaintext flag is revealed.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import base64

def solve():
# Read the initial encoded data
with open('secret_message.txt', 'r') as f:
data = f.read().strip()

# Iteratively decode 49 times
print("[*] Starting iterative Base64 decoding...")
for i in range(49):
try:
data = base64.b64decode(data).decode('utf-8')
except Exception as e:
print(f"[-] Error at iteration {i+1}: {e}")
break

print(f"[+] Final Decoded Message: {data}")

if __name__ == "__main__":
solve()

Flag

kashiCTF{th3_s3cr3t_0f_mah4bh4r4t4_fr0m_3136_BCE}

I like to save my files as pdfs. Kashi kings hate 184.

Initial Analysis

The file is named flag.pdf, but standard PDF analysis tools fail to recognize it:

1
2
pdfid flag.pdf
# Output: Not a PDF document

Using the file command reveals its true identity:

1
2
file flag.pdf
# Output: flag.pdf: Netpbm image data, size = 284 x 150, rawbits, pixmap

The challenge hint "Kashi kings hate 184" suggests that the height of the image (currently 150) has been tampered with and should likely be 184.

Extraction & Decoding

Netpbm (PPM) files use a plain-text header. We can repair the height by editing the file header. Opening the file in a hex editor or a text editor like vim (using :set binary or simply editing the ASCII header) reveals:

1
2
3
4
P6
284 150
255
[Binary Data...]

Change the height value from 150 to 184:

1
2
3
4
P6
284 184
255
[Binary Data...]

After saving the change, the image can be opened with a standard image viewer to reveal the flag.

Flag

kashiCTF{iLOVEkashi}

Generating primes is expensive. I optimized my key generation to be twice as fast. The modulus is 4096 bits — perfectly secure.

Initial Analysis

The hint "optimized my key generation to be twice as fast" suggests that instead of generating two distinct large primes, the author might have reused the same prime (\(n = p^2\)) or chosen two primes that are extremely close to each other. This makes the modulus vulnerable to Fermat's Factorization Method or simply taking the square root.

Extraction & Decoding

Given a 4096-bit modulus \(n\), we can check if it's a perfect square or if its factors are close to \(\sqrt{n}\) by starting from \(\lfloor\sqrt{n}\rfloor\) and searching downwards. Once factored, we calculate \(\phi(n)\), derive the private key \(d\), and decrypt the AES key which was used to encrypt the flag.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
import math
import base64
from Crypto.Util.number import long_to_bytes, bytes_to_long
from Crypto.Util.Padding import unpad
from Crypto.Cipher import AES

# Modulus and public exponent
n = 0x752a94a112ba0ce096f47934dac094d3d07b8c036613938142c0d4c15fc82692eee38d2457dd8d16472c4ddbe8cb5e2a6331e0ca0351094fc9516559768ebfe44509154d64116fa1fe1daf698413d37c9fe3406555f3190e29d99bee0cdd663d531c8e818f2686c7ad24338b4e93c6bfbd1b5a6dc5161316b2cb9ac1ae05a4ac43fdeb3b024b2e00dfcd87069ea1645996d9ad16ac3a9697414c17279112303a1d21136a99dc47628e15a3d6e18779de7aec310331dff1a81871b03e214de09f56c0f3de02f9f399be4ebc094f34b578d311a8b48e9c6cf2fa2f4e321f1dab0a99e5b9d99464c19452d9cc21544ac8e32fb9f13d1b2990758de0876de465cbd3632f846ef49fd7b97abee2ce529cfbc75a0d0792df6cc8091198134e9f646cf7d33c85c4ddd2c4b9a248c2c470d7369ebc7245bcec049455da2ceb742b26058514418398149d03cd1ad74a997375d0462a43e73aa62fc1f7e0dcc67e8f1559073074b9b8d3c37edfcfce67fd1822227933c5a14425d76119fc0a25da4c059761c86bc3077c4d096d9b9f6ae2faf728dbf24d48fa74d99c8c0d8780d2963ca9eccef0dd847ce22fc5b13793981257a9d4dd1af965e9baa5bd9fc4e3321cf8c6fd9871e342e5ae0dff19ab6e9fd8e14b5cc766b92df3306ef63af248b019528928644007c17e31918f9fdf10daeadc1eb8abeb6297bdc8f8e9b27c591f12159479
e = 65537

# Factor n
p = math.isqrt(n)
while n % p != 0:
p -= 1
q = n // p

# Calculate phi
if p == q:
phi = p * (p - 1)
else:
phi = (p - 1) * (q - 1)

# Decrypt AES Key
d = pow(e, -1, phi)
ct_b64 = "MVoAMG4KRlXdSxEtVL/GpwXWyelWmAsJJhMnPaTzF2Hhjm/h/vkHJKQIyHSld2XuB6Q0sWq/TN1dkSePEB1oq6ugzMcgp5VQ9Xn0mOCn1GZ7fP3bKUVD6mG1bt3dkHxzlAT7v6c6xKaTtJJKTV3JXnB2u3duW4dCrFyassEjHM1PEML3CWqJBrgxnlTIYI4i9ydwg1MF1fTOBTm2KLlQ6rIGnBWcGwg4k+8I7e0mIbhod53w3FzIPXePv0ONVp+HBn4XsICwEHhJLXixmHcEz0jxwCgRdz9qr+Ur1pOaVuKN/26cwpYdVTlY5Fk7KapoV3Ews69353gCa+QYiJtzuwr1uFTBe74GfZZ8xzxFK51TnMbqB1M5cpzBK8/TK+ES/+yy1R4jsGkQ4i7Qz0oAsqBoNExSaLsNgwzZe4dYRE2BwDy2tW2QAYFUeU+SVjUb2BI67QtQYl2g+GB0kAMzbcRFr/kykIHqqb2N05BxgRrtsFjq2zWvpJJ71OFCrWVg8IzO7N+WUXFFyFv7ZfdnKOhC/iPNNmLbJXa3Gul89Fa6VyvCJw6lA/t7QCsjtcVG7ox51JAvoHhw5FLIpT+wmfq969iUujkXzLpjyXBVrfnEdjRt61zGEd3tmWIYst721GcKnbxKBehxwpseDBYR0hJRy+CIf5SnrP6/Blq55cQ="
ct_int = bytes_to_long(base64.b64decode(ct_b64))
aes_key = long_to_bytes(pow(ct_int, d, n))

# Decrypt Flag
iv = base64.b64decode("XSCnpZLyN1Oin7F67hOKWQ==")
flag_ct = base64.b64decode("n+H1n3ezKEm0ulyLMcp/ShxLZAddKX7y848o/Lf/56qDev/DPBz+IRcJ14yHWGOuodMaMwyLZi9er7slNa+QMw==")

cipher = AES.new(aes_key, AES.MODE_CBC, iv)
flag = unpad(bytes(cipher.decrypt(flag_ct)), AES.block_size).decode()

print(f"\n[+] FLAG: {flag}")

Flag

kashiCTF{wh3n_0n3_pr1m3_1s_n0t_3n0ugh_p_squared_1s_w0rs3}

Wait, you forgot to give me the Advent calendar!?!?! And what is that supposed to mean, I should have opened the doors up until today?? Ugh, okay, then I'll start: Door 1

Investigation

The hint suggests that we need to visit the "doors" of the Advent calendar. The URL structure was identified as:

1
GET https://hack.arrrg.de/adventskalender/$$ HTTP/1.1

Where $$ represents the door number. To find the flag, we need to check all possible doors (1 to 30).

Solution

Using Zaproxy (OWASP ZAP) or a similar fuzzer, we can automate the process:

  1. Intercept/Send Request: Create a base request to https://hack.arrrg.de/adventskalender/1.
  2. Set Payload: In Zaproxy's fuzzer, set the payload for the door number position.
  3. Configure Generator: Use a Numberzz generator:
    • From: 1
    • To: 30
    • Step: 1
  4. Execute Fuzz: Start the fuzzer and monitor the responses.
  5. Analyze Results: Look for a response that differs in content.

After fuzzing, collecting the responses and looking for a secret message was revealed the hidden message.

THE ANSWER: FELIZNAVIDAD

A network analysis challenge where data was exfiltrated via DNS queries.

Challenge Description

A network capture was obtained from an internal monitoring system after suspicious activity was detected. The traffic appears mostly benign, but analysts believe data was covertly exfiltrated during normal communication.

Initial Reconnaissance

Checking the protocol distribution of the capture.pcap file using tshark:

1
tshark -r capture.pcap -q -z io,phs

The output confirms that 100% of the traffic is DNS, indicating that DNS is being used as a tunnel for exfiltration.

DNS Query Analysis

Extracting the DNS query names reveals two distinct patterns: 1. Repetitive queries for common domains like kashi.com and amazon.com (likely noise). 2. High-entropy subdomains under .exfil.internal.

Extracting the subdomains:

1
2
3
4
5
6
7
tshark -r capture.pcap -T fields -e dns.qry.name | grep ".exfil.internal"
# Example output:
# NNQXG2DJINKE.exfil.internal
# M63ENZZV6ZLY.exfil.internal
# MZUWY5DSMF2G.exfil.internal
# S33OL5UXGX3T.exfil.internal
# NZSWC23ZPU.exfil.internal

Data Recovery

The strings (e.g., NNQXG...) are characteristic of Base32 encoding. We can concatenate these strings and decode them to recover the secret payload:

1
2
3
4
5
6
7
8
import base64

# Concatenated subdomains
encoded_payload = "NNQXG2DJINKEM63ENZZV6ZLYMZUWY5DSMF2GS33OL5UXGX3TNZSWC23ZPU"

# Base32 decoding (adding padding if necessary)
decoded = base64.b32decode(encoded_payload + "======").decode()
print(f"Decoded flag: {decoded}")

Flag

kashiCTF{dns_exfiltration_is_sneaky}

A forensics challenge involving network traffic analysis and IP Time-to-Live (TTL) steganography.

Challenge Description

A packet capture was collected from an internal network segment during routine monitoring. No alerts were triggered at the time, and the traffic appears largely normal. Your task is to analyze the capture and determine whether any meaningful information can be recovered.

Initial Analysis

The provided file ttl_stego.pcap contains a series of ICMP Echo (ping) requests. While the payloads appear standard, the IP Time-to-Live (TTL) values fluctuate between 64 and 65, suggesting binary data is encoded in these variations.

Using tshark to inspect the TTL values:

1
2
tshark -r ttl_stego.pcap -c 10 -T fields -e ip.ttl
# Output: 64, 65, 65, 64, 65, 64, 65, 65, 64, 65...

Extraction & Decoding

The TTL values can be mapped to binary bits: - 64 \(\rightarrow\) 0 - 65 \(\rightarrow\) 1

We can extract the full sequence of TTLs and decode them using a Python script:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import sys

# Extract TTLs using: tshark -r ttl_stego.pcap -T fields -e ip.ttl > ttls.txt
with open('ttls.txt', 'r') as f:
ttls = [int(line.strip()) for line in f if line.strip()]

# Convert TTLs to bits
bits = "".join(['0' if t == 64 else '1' for t in ttls])

# Convert bits to characters (8 bits per byte)
flag = ""
for i in range(0, len(bits), 8):
byte = bits[i:i+8]
if len(byte) == 8:
flag += chr(int(byte, 2))

print(f"Decoded message: {flag}")

Flag

kashiCTF{ttl_stego_is_evil}
+ + +
SYSTEM STATUS: ACTIVE ENCRYPTED SECTOR 7 PRTS_TERMINAL_V2.0 PROTOCOL: 0x2A ENCRYPTED DATA STREAM SYSTEM: ONLINE