Man In the Middle – 2

Örneğin şöyle bir senaryoda:

Orjinal CH içinde çok sayıda cipher suite var, ancak bizdeki OpenSSL yeni bir CH üretirken daha az cipher suite ekledi ve daha küçük bir paket oluştu diyelim. Buna cevap olarak server’dan çıkan SH, içinde önceki paketin ack değeri seq+payload_len = 181 olarak geldi bize. Bu durumda network içinde normalde sorunsuz giden ack/seq değerlerini modifiye etmeden gönderdiğimizde, 200 byte gönderen client ack içinde 181 görünce önceki paketin gitmediğini zannedip aynı paketi tekrar gönderecek ve bir türlü ilerleyemeyecek.

Ya da tam tersi durumda:

Biz arada raw socket üzerinden dinlediğimiz için her türlü geri dönen SH paketini göreceğiz. Ama tcp header’ı yeniden yazmazsak 201 bekleyen client büyük ihtimalle paketi discard edecektir. Bu tür bir durumu örneğin wireshark’ta incelediğimizde “ACK’ed unseen segment” şeklinde bir hata görünür.

Bunlara ek olarak, paketin içeriği değiştiği için her iki durumda da tcp ve ip checksum değerleri invalid olacak. Bunların da tcp ile ilgili değişiklikler bittikten sonra en son olarak yeniden hesaplanması lazım. Paket boyutunun değiştiği durumları garanti altına almak için de her zaman IP-checksum’ın da yeniden hesaplanması faydalı olacaktır.

Burada wireshark ile ilgili kısa bir not geçelim. Wireshark->Edit->Preferences->Protocols->TCP penceresinde “Validate checksum” işaretli değilse bu kontrol yapılmaz ve ilk bakışta bu tür hatalar görünmeyebilir. Bunu açtığınızda ise çok fazla pakette hata varmış gibi görünecektir. Örneğin client tarafından pcap aldığınızda, outgoing paketlerin hepsinde bu uyarı çıkabilir. Network kartı genelde bu hesaplamaları yapacak şekilde optimize edildiği için, wireshark’ın yakaladığı noktada henüz CRC hesaplanmamış olabilir. Dolayısıyla yanlış olduğunu zannediyor.

Doğru hesaplanmış bir MITM senaryosunun en basit hali şu şekilde olabilir:

Modifiye edilip gönderilecek her paket için şu formül uygulanır:

ackn = seqn-1 + lenn-1
seqn = ackn-1

Burada yine unutulmaması gereken iki nokta var. Birincisi, ack hesaplanırken seq ve len değerleri toplanmadan önce host-byte-order’a çevrilip, pakete yazılmadan önce yeniden network-byte-order’a çevrilmeli. İkincisi, burada gösterilen değerlerin tamamı offset olarak hesaplanıyor. Yani ilk CH paketi geldiğinde client’a ait initial sequence number(ISN) paketteki seq değerinden, server’a ait ISN de aynı paketteki ack değerinden alınıp sonraki hesaplamalar bu sayılara eklenerek yapılmalı.

Devam etmeden önce kısa bir not. SSL session’lardan sonra gönderilen FIN/FINACK/ACK mesajlarının da yukarıdaki şekilde işlenip gönderilmesi çok önemli. Aksi takdirde taraflar handshake’in doğruluğundan emin olamayacak ve devam etmeyeceklerdir.

Ortadaki çizgiye, yani kendi uygulamamıza biraz daha yakından bakalım. Senkronizasyonla ilgili önemli bir sorun var aslında şu an.

İlk CH paketlerinden sonra, bizim ürettiğimiz paketler hep gerçek paketlerin gelmesine bağlı. Örneğin server’dan SH geldiği anda, aslında client’dan gelen CH’ye cevap olarak gönderilecek SH çoktan FS içinde üretilmişti. server’dan gelen paket FS’yi tetikleyerek bu paketin client’a gönderilmesini sağlıyor. Ardından client’dan CKE gelerek FS’nin handshake’e devam etmesini sağlıyor. Burada en önemli varsayım client’dan gelen her pakete karşılık server’dan da bir paket geleceği. Bu doğru olsa, gelen paketleri direk FC/FS’ye besleyip, karşı tarafa ait Fake yapıda bekleyen çıktıları göndermek sorun olmayacak. Ama bu varsayım her zaman tutmuyor. (client’a SH ile gönderilen sertfikada aslında server’ın bilgilerinin bulunmaması sorununa daha sonra geleceğiz)

Aslında daha derinde, bu sorunun en kolay sebebi disassemble edilmiş TCP paketleri olabilir. Normalde receive() ile işletim sisteminden aldığımız paketler, kernel’deki TCP implementasyonu tarafından bize reassemble edildikten sonra verildiği için bu sorunla karşılaşmıyoruz. Ama MITM sırasında raw soketler kullanmak zorunda olmamızdan dolayı, bu tür TCP işlemlerini yapabilecek ayrı bir kod hazırda yoksa, özellikle büyük CRT paketleri birkaç TCP paketine bölünmüş olarak gelip yukarıdaki senkronizasyonu kolayca bozabilir.

Reassemble gerektirmese bile, bazı SSL Server’lar SH içindeki CRT ve SHDone mesajlarını ayrı paketlerde yollayabiliyorlar. İlk SH den sonra bizim client’a ilettiğimiz toplu SH’ye karşılık client da kendi CKE’sini bize dönecek. Burada işler karışabilir. Eğer server’dan SH ile ilgili tüm paketler gelmeden client’ın CKE’si bize gelirse, bu mesajı FC’ye iletemeyeceğiz, çünkü henüz bu mesajı işleyebilecek state’e gelmedi. Öncelikle server’dan sertifikayı alıp kendi pre-master-key’ini üretebilecek duruma gelmesi gerekiyor.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s