KnightCTF 2026 — Reconnaissance Writeup

192.168.1.104'ten 192.168.1.102'ye tam 65535 portluk TCP SYN taraması: her yanıtı SYN-ACK (açık) ve RST (kapalı) olarak sınıflandır; hedef tam olarak iki açık port sunuyor.

3 dk okuma
ibrahimsql
516 kelime

KnightCTF 2026 — Reconnaissance

Üç paket yakalamalık bir olay-müdahale senaryosunun ilki. Orta ölçekli bir e-öğrenim şirketi olan "Knight Blog" şüpheli trafik fark ediyor ve paket yakalamalarını teslim ediyor. Bu yakalama, keşif (reconnaissance) aşaması.

  • Etkinlik: KnightCTF 2026
  • Kategori: Network / Forensics
  • Soru: hedefte kaç port açık bulundu?
  • Flag formatı: KCTF{number}

1. Yakalama

Arşivde tek bir dosya var: pcap1.pcapng (yaklaşık 7 MB, ~141k paket). Soru yalnızca bu ilk aşamayla ilgili, dolayısıyla tüm iş tek bir taramayı sınıflandırmak.

Senaryo "şüpheli tarama aktivitesi" vaat ediyor; plan şu:

  1. Taramayı taşıyan TCP konuşmasını bul — tek bir kaynağın tek bir hedefe yaptığı büyük bağlantı denemesi patlaması.
  2. Hedefin yanıtlarını açık/kapalı olarak ayır: bir porta SYN'e SYN-ACK ile yanıt veriliyorsa açık, RST ile yanıt veriliyorsa kapalı.
  3. Farklı açık portları say.

2. Yakalamayı okumak

tshark kurulu değildi; bu yüzden pcapng'i hiçbir sistem kütüphanesine ihtiyaç duymadan ayrıştıran Scapy kullandım:

python3 -m venv venv && ./venv/bin/pip install scapy
Python
from scapy.all import rdpcap, TCP, IP
from collections import Counter
 
pkts = rdpcap("pcap1.pcapng")
tcp  = [p for p in pkts if p.haslayer(TCP) and p.haslayer(IP)]
 
# ACK'siz SYN = deneme
syns   = [p for p in tcp if (p[TCP].flags & 0x02) and not (p[TCP].flags & 0x10)]
# SYN + ACK = açık portun yanıtı
synack = [p for p in tcp if (p[TCP].flags & 0x12) == 0x12]
 
print("packets:", len(pkts), "tcp:", len(tcp))
print(Counter((p[IP].src, p[IP].dst) for p in syns).most_common(3))
Text
packets: 141259  tcp: 135532
SYN (no ACK) packets: 65574
SYN-ACK packets: 39
top SYN sources:
   ('192.168.1.104', '192.168.1.102') 65558
   ('192.168.1.110', '192.168.1.102') 7
   ('192.168.1.103', '57.155.141.115') 2

Tek bir konuşma baskın: 192.168.1.104, 192.168.1.102'ye 65.558 çıplak SYN gönderiyor. Tarayan taraf (192.168.1.104) hedefi (192.168.1.102) süpürüyor; diğer tüm kaynaklar arka plan trafiği. Taranan küme 65.535 TCP portunun tamamını kapsıyor.

3. Açık mı, kapalı mı

Hedefin yanıtlarında yalnızca iki bayrak kombinasyonu önemli: SYN+ACK (0x12) portun açık olduğunu, RST (0x04) kapalı olduğunu gösterir.

Python
scanner, target = "192.168.1.104", "192.168.1.102"
resp = {}
for p in tcp:
    if p[IP].src == target and p[IP].dst == scanner:
        port = p[TCP].sport
        if (p[TCP].flags & 0x12) == 0x12:
            resp[port] = "SYN-ACK"
        elif p[TCP].flags & 0x04:
            resp.setdefault(port, "RST")
 
open_ports = sorted(pt for pt, r in resp.items() if r == "SYN-ACK")
print("ports responded:", len(resp))
print("OPEN:", open_ports)
ports responded: 65535
OPEN: [22, 80]

Denenen 65.535 portun hepsi yanıt verdi ve tam olarak ikisi SYN-ACK ile yanıt verdi: SSH (22) ve HTTP (80). Geri kalan her şey RST döndü. Daha önce görülen büyük SYN-ACK sayısı (tarayıcıya 23 paket) o iki porttaki yeniden iletimden ibaret — bir SYN taraması el sıkışmayı hiç tamamlamaz, bu yüzden hedef SYN-ACK'ini yeniden gönderir.

Diğer daha küçük konuşmalarla çapraz kontrol bunu doğruluyor: hedefe dokunan her kaynak aynı iki portta yanıtlandı ve {22, 80} dışındaki hiçbir port RST dışında bir şey döndürmedi.

Text
SYN-ACK from 192.168.1.102 grouped by scanner:
   (192.168.1.102, 192.168.1.104) -> [22, 80]
   (192.168.1.102, 192.168.1.110) -> [80]
   (192.168.1.102, 192.168.1.101) -> [80]
ALL open ports on target 192.168.1.102: [22, 80]

4. Yanıt

192.168.1.102'ye karşı yapılan keşif taraması 2 açık port buldu:

  • 22/tcp — SSH
  • 80/tcp — HTTP

5. Flag

KCTF{2}
---
Bu yazıyı paylaş:
TwitterLinkedInFacebook

Ne düşünüyorsun?

Tepki bırakarak geri bildirim ver

İlgili Yazılar