Init. import
This commit is contained in:
62
Time spirit-Forensic/solve/extract_flag.py
Normal file
62
Time spirit-Forensic/solve/extract_flag.py
Normal file
@@ -0,0 +1,62 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Decode the flag from the timing-based ICMP channel in public/task.pcapng.
|
||||
Requires scapy: pip install scapy
|
||||
"""
|
||||
from scapy.all import rdpcap, IP, ICMP # type: ignore
|
||||
import sys
|
||||
from typing import Iterable, List
|
||||
|
||||
|
||||
TARGET_IP = "192.168.13.37"
|
||||
ZERO_DELAY = 1.2
|
||||
ONE_DELAY = 1.6
|
||||
TOLERANCE = 0.08 # Acceptable drift around each delay marker
|
||||
|
||||
|
||||
def load_icmp_times(pcap_path: str) -> List[float]:
|
||||
packets = rdpcap(pcap_path)
|
||||
icmp_flow = [
|
||||
pkt
|
||||
for pkt in packets
|
||||
if IP in pkt
|
||||
and ICMP in pkt
|
||||
and (pkt[IP].src == TARGET_IP or pkt[IP].dst == TARGET_IP)
|
||||
]
|
||||
icmp_flow.sort(key=lambda p: float(p.time))
|
||||
return [float(pkt.time) for pkt in icmp_flow]
|
||||
|
||||
|
||||
def as_deltas(times: List[float]) -> List[float]:
|
||||
return [cur - prev for prev, cur in zip(times, times[1:])]
|
||||
|
||||
|
||||
def decode_bits(deltas: Iterable[float]) -> str:
|
||||
bits = []
|
||||
for dt in deltas:
|
||||
if abs(dt - ZERO_DELAY) <= TOLERANCE:
|
||||
bits.append("0")
|
||||
elif abs(dt - ONE_DELAY) <= TOLERANCE:
|
||||
bits.append("1")
|
||||
return "".join(bits)
|
||||
|
||||
|
||||
def bits_to_ascii(bits: str) -> str:
|
||||
# Drop trailing bits if not a whole byte
|
||||
usable_len = len(bits) - (len(bits) % 8)
|
||||
out = []
|
||||
for i in range(0, usable_len, 8):
|
||||
out.append(chr(int(bits[i : i + 8], 2)))
|
||||
return "".join(out)
|
||||
|
||||
|
||||
def main() -> None:
|
||||
pcap_path = sys.argv[1] if len(sys.argv) > 1 else "../public/task.pcapng"
|
||||
times = load_icmp_times(pcap_path)
|
||||
bitstring = decode_bits(as_deltas(times))
|
||||
plaintext = bits_to_ascii(bitstring)
|
||||
print(plaintext)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
55
Time spirit-Forensic/solve/show_clusters.py
Normal file
55
Time spirit-Forensic/solve/show_clusters.py
Normal file
@@ -0,0 +1,55 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Quick delta clustering to show the two timing buckets that encode 0 and 1.
|
||||
Requires scapy: pip install scapy
|
||||
"""
|
||||
from collections import Counter
|
||||
import math
|
||||
import sys
|
||||
from typing import List
|
||||
from scapy.all import rdpcap, IP, ICMP # type: ignore
|
||||
|
||||
|
||||
TARGET_IP = "192.168.13.37"
|
||||
BIN_WIDTH = 0.05 # Seconds
|
||||
|
||||
|
||||
def load_icmp_times(pcap_path: str) -> List[float]:
|
||||
packets = rdpcap(pcap_path)
|
||||
icmp_flow = [
|
||||
pkt
|
||||
for pkt in packets
|
||||
if IP in pkt
|
||||
and ICMP in pkt
|
||||
and (pkt[IP].src == TARGET_IP or pkt[IP].dst == TARGET_IP)
|
||||
]
|
||||
icmp_flow.sort(key=lambda p: float(p.time))
|
||||
return [float(pkt.time) for pkt in icmp_flow]
|
||||
|
||||
|
||||
def as_deltas(times: List[float]) -> List[float]:
|
||||
return [cur - prev for prev, cur in zip(times, times[1:])]
|
||||
|
||||
|
||||
def bin_value(value: float) -> float:
|
||||
return round(math.floor(value / BIN_WIDTH) * BIN_WIDTH, 2)
|
||||
|
||||
|
||||
def main() -> None:
|
||||
pcap_path = sys.argv[1] if len(sys.argv) > 1 else "../public/task.pcapng"
|
||||
deltas = as_deltas(load_icmp_times(pcap_path))
|
||||
|
||||
histogram = Counter(bin_value(dt) for dt in deltas)
|
||||
print("Top timing buckets (bin width {:.2f}s):".format(BIN_WIDTH))
|
||||
for bucket, count in sorted(histogram.items(), key=lambda item: (-item[1], item[0]))[:20]:
|
||||
print(f"{bucket:>4.2f} s -> {count}")
|
||||
|
||||
for center, label in ((1.2, "0"), (1.6, "1")):
|
||||
window = [dt for dt in deltas if abs(dt - center) <= 0.1]
|
||||
if window:
|
||||
avg = sum(window) / len(window)
|
||||
print(f"Near {center:.2f}s (bit {label}) count={len(window)} avg={avg:.4f}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user