İçeriğe atla
0 XP 0
14 dkderinleşmeyle 16 dk55 XP7 etkinlik

TCP ve UDP başlıklarını derinlemesine okumak

Bu derste
  • TCP başlığını, durum makinesini, sıra ve onay aritmetiğini ve tuhaf bayrak kombinasyonlarını okuyup UDP ile farkını ve savunmasını öğren.
  • UDP başlığı sekiz bayta sığar; bu sadelik hem hız kazandırır hem sahteciliği kolaylaştırır.
  • Bu derste bayrakları, pencere ölçeklemesini, ss çıktısını ve tarama imzalarını tcpdump filtreleriyle okuyacaksın.

Puan bütün etkinlikleri cevaplayınca hesaba yazılır. Bu dersi tamamlayınca +55 XP alacaksın. Giriş yapmadan ilerlersen puan yalnız bu tarayıcıda durur.

Temeller yolundaki Ağ 101 modülünde TCP'nin üç yönlü el sıkışmasını gördün. Başlığın taşıdığı bilgi ise el sıkışmadan ibaret değil. TCP başlığı en az 20 bayt, seçeneklerle 60 bayta kadar çıkar.

Başlık her segmentte yeniden taşınır; her paket kendi kopyasını yollar, önceki paketin başlığına güvenmez. Bu derste başlığın alanlarını tek tek okuyacak, bağlantının durum makinesini izleyecek ve aynı alanların normal dışı kombinasyonlarda nasıl bir imza bıraktığını göreceksin. Depo sunucusunda takılan bir servisi çözmek de, bir tarama girişimini yakalamak da aynı okuma becerisine dayanır.

TCP başlığının alanları ve bayraklar

TCP başlığını RFC 9293 tanımlar. Başlık iki portla açılır: Kaynak port ve Hedef port, her biri 16 bit. Ardından 32 bitlik Sıra Numarası ve Onay Numarası gelir. Sonra Veri Ofseti (başlık uzunluğu), dört bitlik ayrılmış alan ve sekiz kontrol biti durur.

Başlık Pencere Boyutu, Sağlama Toplamı, Acil İşaretçi ve Seçeneklerle biter. Veri Ofseti alanı IP başlığındaki IHL ile aynı işi görür: başlığın nerede bitip verinin nerede başladığını dört baytlık bloklarla sayar.

Kontrol bitleri soldan sağa CWR, ECE, URG, ACK, PSH, RST, SYN ve FIN'dir. İlk ikisi tıkanıklık bildirimi içindir. Kalan altısı bağlantının durumunu taşır ve günlük analizde en çok bunlara bakarsın.

SYNistemci → sunucuSYN-ACKsunucu → istemciACKistemci → sunucuVeribağlantı açık
El sıkışmanın üç paketi. Her paketteki bayrak kombinasyonu farklı bir anlam taşır.

SYN paketinde yalnız SYN biti 1'dir ve bağlantı başlatma isteğini taşır. SYN-ACK'te SYN ve ACK birlikte 1 olur. Onay paketinde yalnız ACK biti 1'dir.

PSH biti alıcı uygulamayı beklemeden veriyi hemen teslim etmeye zorlar; veri taşıyan paketlerde bu yüzden çoğu zaman PSH ile ACK birlikte görünür. FIN bağlantıyı düzgün kapatma isteğidir. RST bağlantıyı aniden keser; kapalı bir porta gelen paket ya da beklenmedik bir segment RST doğurur.

Her bayrak bağımsız bir bittir. Birden fazlası aynı anda 1 olabilir. Normal dışı kombinasyonlar da buradan doğar.

Etkinlik 1 / 7

TCP bayrağını anlamıyla eşleştir.

Soldan bir tane seç, sağdan eşini seç. Kullanılmış bir seçeneği yeniden seçersen yeni öğeye taşınır.

Durum makinesi ve ss çıktısı

Bir TCP bağlantısı bir durum makinesi izler. Sunucu portu LISTEN durumunda bekler. İstemci SYN yollayınca SYN-SENT durumuna geçer; sunucu bunu alınca SYN-RECEIVED olur.

El sıkışma bitince iki taraf da ESTABLISHED durumuna gelir. Kapanış da adım adımdır. FIN yollayan taraf FIN-WAIT durumlarından geçer.

FIN alan taraf CLOSE-WAIT durumuna girer ve uygulamanın soketi kapatmasını bekler. Bağlantıyı etkin kapatan taraf en sonunda TIME-WAIT durumunda bir süre bekler. Linux'ta bu süre 60 saniyedir. Amaç, ağda gecikmiş eski paketlerin yeni bir bağlantıya karışmasını önlemektir.

Bu durumları ss komutuyla okursun. ss -tan bütün TCP soketlerini durumuyla listeler: t TCP, a bütün durumlar, n sayısal port demektir. Çıktıdaki durum dağılımı çoğu zaman bir sorunu ya da saldırıyı ele verir. Çok sayıda SYN-RECV satırı, tamamlanmayan el sıkışma demektir; klasik SYN taşkını (SYN flood) böyle görünür.

Çok sayıda CLOSE-WAIT satırı ise başka bir soruna işaret eder. Karşı taraf bağlantıyı kapatmış ama uygulama soketi kapatmayı unutmuştur. Bu bir saldırı değil, bir yazılım hatasıdır ve çoğu zaman sızdıran soketlere işaret eder.

$ ss -tan
State      Recv-Q Send-Q  Local Address:Port   Peer Address:Port
LISTEN     0      511     0.0.0.0:8080         0.0.0.0:*
SYN-RECV   0      0       192.168.1.50:8080    203.0.113.10:52012
SYN-RECV   0      0       192.168.1.50:8080    203.0.113.10:52013
SYN-RECV   0      0       192.168.1.50:8080    203.0.113.10:52014
ESTAB      0      0       192.168.1.50:8080    192.168.1.20:51544
CLOSE-WAIT 1      0       192.168.1.50:44120   198.51.100.7:443
TIME-WAIT  0      0       192.168.1.50:51602   198.51.100.7:443
Depo sunucusunun ss çıktısı. Art arda SYN-RECV satırları yarım kalmış el sıkışmaları gösterir.

Çıktıda 8080 portu LISTEN durumunda hizmet bekler. Ardından üç SYN-RECV satırı gelir; üçü de aynı kaynaktan farklı portlarla yarım el sıkışma açmıştır. Tek başına üç satır zararsızdır, ama saniyede yüzlercesi görünüyorsa bu SYN taşkınının izidir. Böyle bir durumda çekirdek günlüğe Possible SYN flooding on port 8080.

Sending cookies. satırını yazar. ESTAB satırı sağlıklı, tamamlanmış bir bağlantıdır.

CLOSE-WAIT satırında Recv-Q 1'dir. Karşı tarafın FIN'i de bir sıra numarası tükettiği için, uygulama soketten okumayı bıraktığında sayaç çoğu zaman 1'de kalır; uygulama soketi kapatmayı unutmuştur. TIME-WAIT satırı ise normal kapanışın son adımıdır ve kısa sürede kaybolur.

Derinleş:SYN cookie: durumu istemciye emanet etmek

SYN taşkınının hedefi bellek değil, sunucunun yarım bağlantı kuyruğudur. Sunucu her SYN için kuyrukta bir kayıt tutar ve el sıkışmanın tamamlanmasını bekler. Saldırgan sahte kaynak adreslerle SYN yağdırırsa bu kuyruk dolar ve gerçek istemciler içeri giremez.

1996'da Daniel Bernstein bu soruna zarif bir çözüm önerdi: SYN cookie. Fikir, durumu sunucuda tutmak yerine SYN-ACK paketinin sıra numarasına gömmektir. Sunucu, istemcinin adresini, portlarını ve bir zaman damgasını bir gizli anahtarla karıştırıp sıra numarası olarak yollar.

Kuyrukta hiçbir kayıt tutmaz. Gerçek istemci son ACK'i döndürünce sunucu onay numarasından bilgiyi geri çıkarır ve bağlantıyı kurar. Sahte SYN'ler ise son ACK'i asla göndermez, hiçbir kaynak tüketmez. Linux'ta bu davranış tcp_syncookies ayarıyla açılır ve yalnız kuyruk dolduğunda devreye girer.

Etkinlik 2 / 7

Bir depo sunucusunun ss çıktısında yüzlerce CLOSE-WAIT satırı birikmiş, sayı sürekli artıyor. En olası açıklama hangisidir?

Önce kodu oku, sonra çıktıyı seç.

$ ss -tan | grep CLOSE-WAIT | wc -l
842

Sıra, onay ve pencere

Sıra ve onay numaraları veriyi bayt bayt sayar ve kaybı yakalar. Her yön kendi sıra numarasını rastgele bir başlangıç değeriyle (ISN) açar. SYN ve FIN bitleri de birer sıra numarası tüketir, ama veri taşımaz. Onay numarası, gönderenin bir sonraki beklediği baytı gösterir.

Wireshark bu numaraları okumayı kolaylaştırmak için varsayılan olarak göreli değer kullanır: her yönün ISN'ini sıfır kabul eder. Böylece SYN paketinin sıra numarası 0 görünür. Aşağıdaki tablo göreli değerlerle bir el sıkışmayı ve ilk veri alışverişini gösterir. Sütunlar tshark'ın tcp.seq, tcp.ack ve tcp.len alanlarından gelir.

No  Kaynak         Bayraklar   seq   ack   len   Anlam
1   192.168.1.20   SYN         0     0     0     istemci bağlantı açar
2   192.168.1.50   SYN, ACK    0     1     0     sunucu SYN'i onaylar (ack=1)
3   192.168.1.20   ACK         1     1     0     istemci el sıkışmayı kapatır
4   192.168.1.20   PSH, ACK    1     1     100   istemci 100 bayt yollar
5   192.168.1.50   ACK         1     101   0     sunucu 100 baytı onaylar
6   192.168.1.50   PSH, ACK    1     101   200   sunucu 200 bayt yollar
7   192.168.1.20   ACK         101   201   0     istemci 200 baytı onaylar
Göreli sıra numaralarıyla bir el sıkışma ve ilk veri alışverişi. Onay numarası her zaman beklenen bir sonraki baytı gösterir.

Tabloyu satır satır oku. İlk pakette istemci SYN yollar, seq 0'dır. İkinci pakette sunucu ack 1 ile cevap verir; SYN bir sıra numarası tükettiği için beklenen bir sonraki bayt 1'dir.

Üçüncü pakette el sıkışma kapanır. Dördüncü pakette istemci 100 bayt yollar, len 100'dür.

Beşinci pakette sunucu ack 101 döner: ilk 100 baytı aldım, 101. baytı bekliyorum. Altıncı pakette sunucu 200 bayt yollar. Yedinci pakette istemci ack 201 ile bunu onaylar.

Kural nettir: bir sonraki beklenen onay numarası, gelen paketin sıra numarasına veri boyunu eklemektir. Bu aritmetiği bilmek, kayıp segmenti ya da enjekte edilmiş bir paketi yakalamana yarar.

Sayılan baytların ne kadarının yolda olabileceğini pencere boyutu (window) belirler. Bu alan alıcının o an kabul edebileceği bayt sayısını söyler ve akış kontrolünü yürütür. RFC 9293'te bu alan 16 bittir, azami değer 65535.

Günümüz yüksek hızlı bağlantılarında bu yetmez. RFC 7323 pencere ölçekleme (window scaling) seçeneğini tanımlar ve el sıkışma sırasında konuşulan bir çarpan ekler. Çarpan yalnız SYN paketlerinde belirlenir, bağlantı ortasında değişmez.

Wireshark bunu WS=128 gibi gösterir: pencere değerini 128 ile çarp. Bu yüzden yakalamanın ortasından katılırsan çarpanı kaçırırsın ve Wireshark gerçek pencereyi hesaplayamaz. Diğer önemli seçenekler MSS (en büyük segment boyu), SACK izni (seçici onay) ve zaman damgasıdır.

Bu seçeneklerin sırası ve değerleri işletim sistemine göre değişir. Bir SYN paketinin MSS değeri, pencere ölçekleme çarpanı, SACK izni ve seçeneklerin sırası birlikte bir parmak izi oluşturur. Pasif işletim sistemi tanıma bu parmak izini kullanır; hiç paket yollamadan, yalnız gelen SYN'e bakarak karşı tarafın işletim sistemini tahmin eder.

Wireshark'ın tcp.analysis alanları da bağlantı sağlığını okur. tcp.analysis.retransmission yeniden gönderilen segmenti, tcp.analysis.duplicate_ack yinelenen onayı, tcp.analysis.zero_window ise alıcının tamponunun dolduğunu işaretler. Bir bağlantı yavaşsa önce bu alanlara bakarsın: sorun ağ kaybı mı, yoksa uygulamanın veriyi okuyamaması mı.

Etkinlik 3 / 7

Bir istemci seq=5000 ile 300 bayt veri yolladı. Sunucunun döneceği onay numarası (ack) kaçtır? Yalnız sayıyı yaz.

Etkinlik 4 / 7

Doğru mu, yanlış mı?

TCP pencere boyutu alanı başlıkta değişmeden sabit kalır.

Tarama imzaları

Normal trafikte SYN, SYN-ACK, ACK, FIN ve RST kombinasyonları görülür. Bazı taramalar hiç normal olmayan kombinasyonlar kullanır. NULL taramasında hiçbir bayrak set değildir.

FIN taramasında yalnız FIN biti set edilir. Xmas taramasında FIN, PSH ve URG birlikte yanar; paket, ışıkları yanan bir çam ağacına benzediği için bu adı almıştır. Nmap belgesine göre üç tarama aynı mantığa dayanır: kapalı porttan RST döner, açık ya da süzülen porttan cevap gelmez.

Nmap cevapsız portu bu yüzden open|filtered olarak raporlar; sonuç kesin değildir. Microsoft Windows, birçok Cisco cihazı, BSDI ve IBM OS/400 ise her duruma RST döner. Bu sistemlerde bütün portlar kapalı görünür ve tarama yanıltır. Bu taramaları yalnız kendi lab ortamında ya da yazılı iznin olan hedefte dene.

$ tcpdump -n -r tarama.pcap 'tcp[tcpflags] & (tcp-fin|tcp-push|tcp-urg) == (tcp-fin|tcp-push|tcp-urg)'
17:13:20.000000 IP 192.168.56.66.40000 > 192.168.56.10.22: Flags [FPU], seq 2918841204, win 1024, urg 0, length 0
17:13:20.030000 IP 192.168.56.66.40000 > 192.168.56.10.80: Flags [FPU], seq 2918841204, win 1024, urg 0, length 0

$ tshark -n -r tarama.pcap -Y "tcp.flags == 0x029" -T fields -e frame.number -e tcp.flags -e tcp.flags.str
1	0x029	······U·P··F
4	0x029	······U·P··F
Xmas taramasını yakalayan iki filtre. tcpdump bayrak baytını maskeyle, tshark ise tek bir eşitlikle süzer.

tcpdump filtresi tcp[tcpflags] ifadesiyle bayrak baytını okur ve maskeyle üç bitin birlikte set olduğunu ister. Çıktıda 22 ve 80 portlarına gelen iki Xmas sondası görünür; Flags [FPU] üç bayrağı gösterir. Nmap'in ham paketlerinde pencere çoğu zaman 1024'tür, bu da ek bir ipucudur. tshark tarafında aynı imzayı tcp.flags == 0x029 yakalar: 0x029 değeri URG (0x020), PSH (0x008) ve FIN (0x001) bitlerinin toplamıdır.

tcp.flags.str sütunu bunu görsel olarak doğrular; yanan üç harf U, P ve F'dir. NULL taramayı tcp.flags == 0x000, FIN taramayı tcp.flags == 0x001 arar. Bir IDS kuralı bu kombinasyonları gördüğünde çoğu zaman doğrudan tarama etiketi basar, çünkü meşru bir istemci bu paketleri üretmez.

Etkinlik 5 / 7

Xmas taramasının imzası olan FIN, PSH ve URG bayraklarının birlikte set edildiği satırları yakalayan düzenli ifade yaz.

Yazdıkça eşleşen satırlar işaretlenir. Hedef: yalnız doğru satırlar eşleşsin.

flags=FIN eşleşmedi
flags=SYN,ACK eşleşmedi
flags=FIN,PSH,URG eşleşmedi
flags=ACK eşleşmedi
flags=FIN,PSH,URG eşleşmedi

UDP, sahtecilik ve savunma

UDP başlığı çok daha kısadır: yalnız kaynak port, hedef port, uzunluk ve sağlama toplamı, toplam 8 bayt (RFC 768). Sıra numarası, onay ya da pencere yoktur; teslim garantisi de yoktur. Bu sadelik DNS sorgusu gibi tek paketlik işlerde hız kazandırır, çünkü el sıkışma beklemeden ilk baytla veri yola çıkar.

Durum bilgili güvenlik duvarları UDP için gerçek bir bağlantı olmasa da bir zaman aşımı tutar: giden bir UDP paketinden sonra kısa süre gelen cevabı eşleştirir. Kapalı bir UDP portuna paket gelince hedef ICMP Tür 3 Kod 3 (port ulaşılamıyor) mesajı döner; UDP taraması açık ve kapalı portu bu davranıştan ayırır.

UDP'nin sadeliği bir bedel de taşır. Bağlantı kurulumu olmadığı için kaynak adres sahteciliği (spoofing) kolaydır. DNS yükseltmeli (amplification) saldırılar bunu kullanır: saldırgan kurbanın adresini kaynak gibi göstererek küçük bir sorgu yollar, büyük cevap kurbana gider. Savunmanın temeli kaynak adresini ağ girişinde doğrulamaktır; BCP 38 (RFC 2827) bu ilkeyi tanımlar ve sahte kaynaklı paketi baştan keser.

TCP tarafında SYN taşkınına karşı SYN cookie, tuhaf bayrak kombinasyonlarına karşı ise normalizasyon devreye girer. Normalleştirici bir güvenlik duvarı NULL, FIN ve Xmas paketlerini geçmeden düşürür. IDS'te geçersiz durumlu paket sayacı da bu anomalileri sayar ve eşiği aşınca uyarı üretir.

$ tcpdump -n -r depo.pcap 'tcp[tcpflags] & (tcp-syn|tcp-ack) == tcp-syn' | awk '{print $3}' | cut -d. -f1-4 | sort | uniq -c | sort -rn | head -3
   4812 203.0.113.10
     37 192.168.1.20
     12 192.168.1.31
Depo sunucusuna gelen bağlantı açma paketlerinin kaynağa göre sayımı. Filtre, ACK biti 0 olan SYN paketlerini seçer.

Filtre bayrak baytında SYN ve ACK bitlerini maskeler. Yalnız SYN'in 1, ACK'in 0 olduğu paketleri, yani bağlantı açan ilk paketleri seçer. SYN-ACK cevapları ACK biti taşıdığı için dışarıda kalır.

awk kaynak adres sütununu alır, cut port kısmını atar, uniq -c her adresi sayar. Çıktıda 203.0.113.10 tek başına 4812 bağlantı açma denemesi yapmıştır. ss çıktısındaki SYN-RECV satırlarının kaynağı da bu adresti.

Diğer iki adres olağan istemcilerdir. Sahte kaynaklı bir taşkında adresler binlerce farklı değere dağılır ve bu sayım işe yaramaz. O durumda toplam SYN oranına ve el sıkışmayı tamamlayan ACK'lerin oranına bakarsın. Wireshark'ta aynı seçimi tcp.flags.syn ve tcp.flags.ack alanlarıyla kurarsın.

Derinleş:Kör RST enjeksiyonu ve RFC 5961

Saldırgan aradaki trafiği görmese bile bir TCP bağlantısını koparmayı deneyebilir. Kör RST enjeksiyonunda saldırgan dört bilgiyi (iki adres, iki port) tahmin eder ve pencereye düşen bir sıra numarasıyla RST yollar. Eski kural pencere içindeki her RST'yi kabul ettiği için tek bir isabetli paket bağlantıyı düşürüyordu.

RFC 5961 bu kuralı sıkılaştırdı. RST artık yalnız sıra numarası beklenen değere tam eşitse bağlantıyı düşürür. Pencere içinde ama tam değilse alıcı bir challenge ACK yollar ve segmenti atar; karşı taraf bağlantıyı gerçekten kapattıysa doğru sıra numarasıyla yeni bir RST gönderir.

Pencere dışındaki RST sessizce düşer. Aynı belge SYN ve veri enjeksiyonu için de benzer denetimler getirdi. Önlemin kendisi de bir açık doğurdu.

2016'da açıklanan CVE-2016-5696, Linux'un challenge ACK'ler için koyduğu genel hız sınırını kullandı. Bu ortak sayaç saldırgana bağlantı hakkında bilgi sızdırıyordu. Linux sınırı rastgeleleştirerek açığı kapattı.

Etkinlik 6 / 7

UDP başlığında TCP'de bulunan ama UDP'de olmayan alan hangisidir?

Etkinlik 7 / 7

Wireshark'ta tcp.flags.syn==1 && tcp.flags.ack==0 filtresi hangi paketleri gösterir?

Bu derste bir hata mı gördün? Bildir