Siber saldırılarda, saldırı düzenlemekten daha önemlisi yakalanmamaktır. Flood saldırıları ile ilgili ilk yazıyı bitirirken, monitör edilen bir networke yapılan DOS saldırılarında, saldırganın tespit edilme ihtimalinin %100 olduğunu belirtmiştik. Hedef sistemde, IP numarası loglandığı için saldırgan, rahatlıkla bulunabilir. İşte bu noktada devreye IP spoofing giriyor. Madem IP’ler, monitör edilen networklerde loglanıyor, o zaman biz de göndereceğimiz paketleri sahte IP’lerden göndeririz. Tabi, bunun için öncelikle paket yapılarına bakmak lazım. TCP’ye göre daha basit bir yapısı olduğu için öncelikle UDP protokolü ile veri nasıl taşınıyor, inceleyelim. UDP üzerinden iletişim gerçekleştirilmek istendiğinde, aşağıdaki gibi bir UDP paketi oluşturulmaktadır:

Görüldüğü gibi paket, IP Header, UDP Header ve datadan oluşuyor. IP Header’ın yapısı aşağıdaki gibidir:

  • Version: IPv4/IPv6 bilgisini saklar. 4 bittir.
  • IHL: Header’ın, boyut bilgisini saklar. 4 bittir.
  • Type of Service: Servis kalitesinin(Güvenilirlik, öncelik, gecikme vs.) yönetildiği parametreler. 8 bittir.
  • Total Length: Paketin toplam boyut bilgisi. 16 bittir.
  • Identification: Fragmentation durumlarında, paket parçalarının birleştirilmesi için kullanılır. Datagram’ın internette tek olmasını ifade eder. 16 bittir.
  • Flags: Paketin iletilirken, fargmentation(parçalanıp parçalanmayacağı) durumunu belirler. 3 bittir.
  • Fragment Offset: Parçalanarak iletim söz konusu ise mevcut parçanın, datagramın hangi parçası olduğu bilgisini tutar. 13 bittir.
  • Time to Live: Zaman damgası. 8 bittir
  • Protocol: Transport katmanında hangi protokolün(TCP, UDP vs.) kullanılacağını belirler. 8 bittir.
  • Header Checksum: Hata kontrol parametresi. 16 bittir.
  • Source Address: Paketin gönderileceği, kaynak IP. 32 bittir.
  • Destination Address: Paketin gideceği, hedef IP. 32 bittir.
  • Options: Kullanıcı tarafından belirlenen ek seçenekler.

Burada paket dediğimiz, yazılımsal olarak byte dizisine karşılık gelmektedir. Yukarıda, IP Header’ın yapısında görüldüğü gibi IP header minimum 160 bit20 byte‘lık bir dizidir. IP Header’ın yapısına göre IPHeader sınıfımız aşağıdaki gibi olmalıdır:

1ComputeChecksum metodu hata kontrol parametresini hesaplıyor. Checksum değeri, IP Header’ın 16 bitlik parçalara bölünmüş parçalarının toplamının bire tümleyenidir.  Eğer hatalı hesaplanır ise paket drop edilir.

OneSum, metodunda IP Header’ı 16 bitlik(2 byte) parçalara bölüp, parçaları topluyoruz. 1 byte = 8 bit olduğundan, toplamak için elde edeceğimiz elemanın 16 bit olması için dizinin elemanlarını sırayla ikişer ikişer ele alıyoruz. OnesComplementSum, metodunda ise toplamın bire tümleyenini elde ediyoruz. (~) operatörü, bir değerin bire tümleyenini verir.

IP Header’daki GetProtocolPacketBytes metodunda IP Header’ı build ediyoruz.

Görüldüğü gibi IP Header yapısına göre değerleri byte dizimize aktarıyoruz. IP Header yapısına tekrar bakacak olursanız, ilk değerin Version+IHL = 8bit olduğunu görürsünüz. Yani byte dizimizin ilk elemanı olan ipv4Packet[0], Version+IHL değerini tutacaktır. Burada Verision=4+IHL=5 değeri için 69 set ediyoruz.  ipv4Packet[1], Type of Service değerini tutacaktır. TotalLength bilgisi 16 bit olduğundan  ipv4Packet[2] – ipv4Packet[3] elemanlarında tutulacaktır. Offset(Flags+Offset) bilgisi 16 bit olduğundan  ipv4Packet[4] –  ipv4Packet[5] elemanlarında tutulacaktır. Identification bilgisi 16 bit olduğundan  ipv4Packet[6] –  ipv4Packet[7] elemanlarında tutulacaktır. Dizinin 8 ve 9. elemanlarında 8 bit boyutunda olan TTL ve Protocol bilgileri yer alacaktır.  Dizinin 10 ve 11. elemanlarında 16 bit boyutunda olan Checksum bilgisi yer alacaktır. Metodun sonunda Checksum değeri hesaplanarak, dizinin 10 ve 11. elemanına aktarılıyor. Dizinin 12-13-14-15. elemanlarında 32 bit değerinde olan Source IP ve 16-17-18-19. elemanlarında yine 32 bit olan Destination IP bilgileri yer alacaktır.  Böylece paket göndermek için gerekli olan IP Header’ı oluşturmuş olduk.

IP Header’ı anladıktan sonra şimdi UDP Header’a bakalım. UDP Header’ın aşağıdaki gibi basit bir yapısı vardır:

Bu yapıya göre UDPHeader sınıfı aşağıdaki gibidir:

UDP Header, 8 byte boyutundadır. GetProtocolPacketBytes  metodunda UDP paketini build ediyoruz.

16 bit olan Source Port ve Destination Port bilgileri dizinin 1-2 ve 3-4. elemanlarında tutulmaktadır. Dizinin 5. elemanında UDP Header boyut bilgisi yer almaktadır. 6-7. elemanlarda Checksum bilgisi tutulmaktadır. Sonrasında, kaynaktan hedefe gönderilecek mesaj(payload) diziye ekleniyor. Böylece UDP paketini oluşturmuş olduk. Sonrasında, Checksum değerini hesaplamak için sahte IP Header oluşturuyoruz. Bu IP Header, paketin gerçek IP Header’ı değildir. Sadece Checksum değerini hesaplamak için kullanılır. Aşağıdaki resimde, kırmızı ile renklendirilmiş bölüm  IPv4 Pseudo Header formatıdır:

Görüldüğü gibi sahte IP Header’ı tutacak dizi, UDP paketinin boyutuna(UDP Header + Gönderilecek mesaj) ek olarak, Source IP(32 bit), Destination IP(32 bit), Zero biti, Protocol biti ve UDP Length(16 bit) olmak üzere +12 bytes boyutundadır. PseudoHeader dizisine, formatta belirtildiği sıra ile Source IP, Destination IP, Zero biti, Protocol ve UDP paketinin boyut bilgisini aktarıyoruz. UDP paketini de, sahte IP Header’ın sonuna ekliyoruz. Checksum değerini hesaplıyoruz ve UDP paketinde dizinin 6-7. elemanlarına aktarıyoruz. Buradaki checksum değeri optional’dır. Hesaplama yapmadan, sıfır set etmiş şekilde bıraksanız da pakette sorun oluşmaz. Checksum hesaplama işlemine, payload da dahil olduğu için aşağıdaki şekilde checksum değerini hesaplayabiliriz.

IP ve UDP Headerlar hazır. IP Spoofing yapacağımız için source IP olarak kullanmak üzere rastgele IP üreten bir metodumuzun olması lazım. IPv4 adresi 32 bit = 4 byte olduğundan, aşağıdaki şekilde rastgele IP üretebiliriz:

UDP paketimiz ve sahte IP’lerimiz hazır. Şimdi helva yapmaya başlayalım 🙂 Bir konsol uygulamanın main metoduna aşağıdaki kodları yazalım:

İlk olarak tanımlamalarımızı yapıyoruz. Source IP, Destination IP, Source Port, Destination Port, gönderilecek mesaj(payload) tanımlamalarını yaptık.  Sonrasında IPv4 için IP ve UDP headerları oluşturduk. Göndereceğimiz paketi, yani byte dizisini(sentPacket) tanımladık. Önce IP Header’ı sonra UDP Header’ı göndereceğimiz pakete kopyaladık. Göndereceğimiz mesajı(payload), UDP Header oluştururken, UDP Header’ın sonuna eklemiştik. Böylece paketimiz hazır. Socket işlemlerinde SetSocketOption metodunda, paketin başlık bilgisinin paketin içerisinde olduğunu belirtiyoruz. Hazırladığımız paketi hedef makineye gönderiyoruz.

Programı çalıştırdığımızda rastgele üretilen bir IP’den hedef IP’ye, UDP paketleri gönderilecektir. Bir Thread’den while döngüsü içerisinde bu kodları çalıştırırsanız, hedef makineye farklı IP’lerden sürekli mesaj gönderilecektir. Kullandığınız makine güçlü donanıma sahip ve güçlü ağ kaynaklarınız var ise DOS saldırısı ile DDOS etkisi gösterebilirsiniz. Aşağıda for döngüsünde 10 kere çalıştırılmış hali görünmektedir:

Görüldüğü gibi farklı IP’lerden hedef sisteme sorunsuz paket gönderiliyor. “Oooo süper! DOS görünen DDOS saldırısı gerçekleştirip, arkamda iz de bırakmam” diye düşünüyorsanız Microsoft’un güzel bir sürprizi var 🙂 Microsoft, client işletim sistemleri üzerinden IP spoofing ile DOS saldırıları yapılmasın diye client işletim sistemlerini raw socket işlemlerine kapatmıştır. Windows 7, Windows 8 gibi işletim sistemlerinden, raw socket üzerinden IP Spoofing yaparak sahte paket göndermeye çalıştığınızda, paketin source IP’si ile makinenin interface’lerinin IP’leri match ediliyor. Eğer uyuşmaz ise paket drop ediliyor. Dolaysı ile yukarıdaki resimdeki gibi “paketler gönderildi” mesajı alsanız da, Wireshark’ı açıp, trafiği monitör ettiğinizde herhangi bir paket göremeyeceksiniz. Bu nedenle uygulamayı Windows Server 2012 olan bir makineden test edelim:

Paketler, random IP’ler ile sorunsuz oluşturup, gönderiliyor. Ancak, hedef sistemin önünde IPS var ise bu paketler hedef sisteme ulaşmayacaktır. IPS, “Malformed Packet” olarak paketleri yakalayıp, drop edecektir. Yukarıdaki şekilde, mavi alanda görüldüğü gibi paket için BAD LENGTH uyarısı verilmiş. Gönderilen paketin boyutu 49 byte olarak hesaplanmış ama bizim paketimizin boyutu 20 byte (IP Header) + 8 byte (UDP Header) + 7 byte (Data) = 35 byte‘tır. 14 byte’lık bir eksiklik söz konusu. Hesaplanan paket boyutu ile gönderilmeye çalışılan paket boyutu farklı olduğu için IPS, paketi tutarsız bulup, yakalar ve drop eder. Aşağıda CheckPoint IPS, Packet Sanity kuralı görülmektedir:

Paketteki bu 14 byte’lık eksiklik, Wireshark ekran görüntüsünde sarı diktörgen ile işaretlenen bölümdür. Paket en üst layerdan, hedefe gönderilmek için alt layer’a doğru iletilirken ilgili layer’ın header’ı eklenerek iletilir.

L4 katmanında UDP Header’ı ekledik. Paketin, malformed olarak algılanmaması için ethernet frame’in eklenmesi gerekmektedir. Wireshark ekran görüntüsünde görüldüğü gibi ethernet frame, Destination MAC(6 byte), Source MAC(6 byte) ve Type(2 byte)‘tan oluşmaktadır. Ethernet frame yapısı aşağıdaki gibidir:

Önünde IPS bulunmayan sistemler için bu şekilde IP Spoofing yapılabilir. Paketleri L2’de manipüle etmek biraz çetrefilli bir iş.  Güvenlik üzerine devam 🙂

Reklamlar