Go ile Port Scanner

Codx

Katılımcı Üye
30 Tem 2017
309
1
Merhabalar, iyi forumlar herkese.

Geçtiğimiz günlerde nmap ile bir IP adresi üzerinde hangi portlar ile haberleşebiliyorum diye kontrol etmek durumunda kaldım. Bunu,

Kod:
nmap -p- <IP_ADDRESS>
şeklinde yaptım ve yaklaşık bir 10 dk kadar bekledim. Bildiğiniz üzere bu tarz tarama tooları bir miktar bekletiyor. Bunun sebebi tabi arkaplanda çok işlem dönmesi.

Bende dedim ki bunu ihtiyacım olduğu zaman hızlandırmam lazım. Bende oturup port scanning tool'u yazdım. Kendim için yaptım. Paylaşma sebebim birilerinin de bundan istifade etmesi.

Concurrency kullanarak 65535 tane portu örnek bir hedef olarak scanme.nmap.org'u tarıyorum. 3 saniyeden daha kısa sürüyor.

Başlayalım...

Öncesinde nasıl bağlandığımızı kontrol ederiz bunu öğrenelim. Bağlanmak için net kütüphanesini kullanacağız. net paketinin dökümanına https://godoc.org/net buradan ulaşabilirsiniz.

Şimdi net.Dial() fonksiyonu ile bağlantı yapmaya çalışacağız. Eğer bağlanamazsa bize error dönecek bu yüzden error yoksa bağlantı sağlanmıştır. Şimdi uygulayalım.



Ben bunu çalıştırdığımda Ekrana Success! diye gayet güzel bir şekilde çıktımızı basıyor, çünkü ben nmap.org'un scanme subdomainine 80 portundan erişebiliyorum.

Şimdi nasıl bağlandığımızı gördük ama sadece hardcoded olarak verdiğimiz port'a bağlandık, fakat sadece 80 portuna bağlandık şimdi düz mantık for döngüsü içine alalım i. değerdeki porta bağlanmaya çalışalım. Connection'ı test edebilmek için ise bir üstteki örnekte olduğu gibi error dönüp dönmemesini kontrol ediyorum. İşimiz bittiğinde ise connection açık kalmasın diye conn.Close() yazarak bağlantıyı kapatacağım.



Şimdi çalıştırıp 1 - 1000 aralığındaki portları tarayalım.



Total time 59 saniye ve ben işlemin tamamlanmasını beklemeden iptal ettim. (Terminalimin böyle gözükmesinin sebebi vimden çıkmadan command mode'da ":!time go run fast-scan.go" yazarak scripti vimden çıkmadan çalıştırdığım içindir.)

Şimdiye kadar basit bir şekilde bağlantı sağladık for ile dönüp tek tek kontrol edebildiğimizi öğrendik asıl işlem bu noktadan sonra başlıyor. Şimdi bunu hızlandırmaya başlayalım.

Go dilinde goroutines işlemi var. Bundan istifade ederek işlemimizi hızlandıracağız. Şu şekilde,



Biz burada şu işlemi yaptık, bir anonim function oluşturduk j adında bir parametre aldırdık bu aldırdığımız parametreye i'nin değerini gönderdik. error dönerse bağlantı olmadığı mantığıyla çalıştığımız için error döndüğünde return edip döngünün o anki dönüşünden sonrakine geçmesini sağladık. Çalıştıralım,



Ekrana hiç bir şey basmadı, çünkü işlem çok hızlı gerçekleşti. Execution time'a bakınca 0,329 yazıyor. Ben istek gönderdim ama dönen istekleri yakalayana kadar connection kapandı bu yüzden bişey yakalayamadı. Bunu snyc paketinden WaitGroup kullanarak düzeltebiliriz.

İlk önce Add(1) yapıp WaitGroup sayacını bir arttıracağız. Sonra Done() ile sayacı bir eksilteceğiz. Wait() ile içerideki sayacın 0'a gelmesini bekletiyor olacağız. Bunları kullanma sebebimiz ise bağlantıların tamamlanmasını beklemesini istiyor olmamız. Aksi halde işlem tamamlanmadan connection kapanıyordu. Şimdi bunları ekleyelim,



Şimdi resimdeki kodu açıklayalım. for her döndüğünde WaitGroup'a 1 ekleyecek, anonim function içerisinde defer ile func'ın tüm işlemi bittiğinde en son WaitGroup'u 1 eksiltecek. for, en son döndüğünde tekrar dönmeyeceği zaman ve işlem bitiminde WaitGroup sayacı 0 olacağından Wait() fonksiyonu WaitGroup sayacını 0 olarak görüp işlemi bitirecek.

Şimdi çalıştırdığım zaman total time 1,721 olarak 1 - 1000 aralığındaki portları kontrol etti.



Bağlantı kurulabilecek 65535 adet port olduğunu düşünecek olursak içeride hardcoded olarak verdiğimiz 1000 yerine 65535 yazmamız gerekecek. Bu sefer sonuç 4 saniyeye çıkıyor. Şimdi işleri biraz daha hızlandıralım.

Şimdi şöyle bir örnek yapalım. chan kullanıcaz her goroutine işleminde chan'dan okuyacak birisi diğerini beklemeden çalışacak. Bu yüzden sırasız bir şekilde çalışacak. Birisinin işleminin bitmesini beklemeden diğeri işlemini yapıyor olacak.



Çıktısı ile birlikte alabilmek için vscode üzerinde ss aldım. Ben burada şunu yaptım. worker adında bir fonksion oluşturdum ports adında bir chan alıyor ve WaitGroup'un pointer'ını alıyor. WaitGroup sayacından bir düşüp işlemini bitiriyor.

main fonksiyonuna gelecek olursam eğer, wg adında WaitGroup tanımlıyorum. ports adında bir chan make ediyorum ve kapasitesini 100 olarak belirtiyorum. Bu şu demek oluyor aynı anda 100 goroutine bu channel'dan okuma yapabilecek ve bunun için diğer routine'ın işleminin bitmesini beklemeyecek. Paralel olarak çalışmasını hedefliyoruz.

Birinci for döngüsünde ports'un kapasitesi kadar dönüp bu döngünün her adımında worker'ı çağırıp ports'un o anki değerinden okuma yapıyorum, ve her seferinde WaitGroup sayacının bir eksilmesine ihtiyaç duyduğum, (goroutine süratini dengelemek amacıyla) wg.Wait() özelliğini kullanmak durumunda kalacağım için bu işlemi de worker içerisinde yapıyorum.

Port sayısı ekleme işlemimi ise ikinci for döngüsünde yapıyorum. Bu döngü içinde de sayacı her eklemede bir arttırıyorum. Bu sayede işlemlerimiz dengelenmiş oluyor. Son olarak close(ports) diyerek channel'ı kapatıyorum.

Buraya kadar tamamız. Devam edip bunları tarama yaptığımız script içerisine de koyarsak, sonuçlar ekrana basılırken yine sırasız olarak gelecektir, çünkü bunun kontrolünü sağlamadık.

Eğer bu sıralamayı yapmak istersek ayrı bir thread kullanmamız gerekecektir. Bunun yerine int tipinde bir array oluşturup sonuçları ona ekleyebilir en son sort edip ekrana bastıra biliriz de. Ben kolaya kaçıp ikinci yolu tercih ediyorum.



Scripti peşpeşe çalıştırıp 3 saniyeyi geçmeyen sonuçlar çıktığını görebiliyoruz.



Not: İçeride hardcoded olarak verdiğimiz "scanme.nmap.org:%d" kısmındaki domaini değiştirerek farklı hedefler için de kullanabilirsiniz.

main.go dosyasını https://github.com/0xCodx/Port-Scanner-Go burada paylaştım.

Anlatacaklarım bu kadardı. Ben yaparken çok keyif aldım. Umarım faydalı olmuştur. Okuduğunuz için teşekkür eder, iyi forumlar dilerim.
 
Son düzenleme:
  • Beğen
Tepkiler: fmd

Anonim6

Yeni üye
29 Şub 2012
0
5
nmapʼe uygun argümanları vermemiş, varsayılan ayarlar ile çalışmasına ses etmemiş iseniz hızlı çalışmasını beklemeniz hatalı: https://www.turkhackteam.org/9171197-post12.html concurrency kullanımınızı sakat buldum, hızlı çalışmasının sebebi de bu gördüğüm kadarıyla, zira aldığınız sonucun da doğru olduğunu zannetmiyorum. dokümanlara baksanız iyi olacak gibi. emeğinize sağlık, kolay gelsin.
 

Codx

Katılımcı Üye
30 Tem 2017
309
1
nmapʼe uygun argümanları vermemiş, varsayılan ayarlar ile çalışmasına ses etmemiş iseniz hızlı çalışmasını beklemeniz hatalı: https://www.turkhackteam.org/9171197-post12.html concurrency kullanımınızı sakat buldum, hızlı çalışmasının sebebi de bu gördüğüm kadarıyla, zira aldığınız sonucun da doğru olduğunu zannetmiyorum. dokümanlara baksanız iyi olacak gibi. emeğinize sağlık, kolay gelsin.

Eleştiri için teşekkür ederim. concurrency kullanımı çok sağlıklı değil dediğiniz gibi, her yeri bu haliyle tarayamıyor. scanme.nmap.org'da yanlış hatırlamıyorsam open durumda iki tane port vardı zaten ama tarama yapılması için var zaten orası o yüzden orada çalışıyor diye düşünüyorum. nmap'in varsayılan ayarları ile çalıştırmıştım sonrasında biraz eğlence biraz da alıştırma amaçlı gecenin bir vakti kaybedecek bişeyim yok diyerek kalkışmıştım. Bu bana go hakkında bişeyler kattı daha sonra konu halinde paylaşayım dedim. Dökümanları kurcalayacağım bunu biraz daha geliştirmek gibi bir hedefim var aslında hem kendime katkım olur hem paylaşırım ilerde güzel bir içerik olur diye düşünüyorum. Teşekkür ederim. Kolay gelsin.
 
Üst

Turkhackteam.org internet sitesi 5651 sayılı kanun’un 2. maddesinin 1. fıkrasının m) bendi ile aynı kanunun 5. maddesi kapsamında "Yer Sağlayıcı" konumundadır. İçerikler ön onay olmaksızın tamamen kullanıcılar tarafından oluşturulmaktadır. Turkhackteam.org; Yer sağlayıcı olarak, kullanıcılar tarafından oluşturulan içeriği ya da hukuka aykırı paylaşımı kontrol etmekle ya da araştırmakla yükümlü değildir. Türkhackteam saldırı timleri Türk sitelerine hiçbir zararlı faaliyette bulunmaz. Türkhackteam üyelerinin yaptığı bireysel hack faaliyetlerinden Türkhackteam sorumlu değildir. Sitelerinize Türkhackteam ismi kullanılarak hack faaliyetinde bulunulursa, site-sunucu erişim loglarından bu faaliyeti gerçekleştiren ip adresini tespit edip diğer kanıtlarla birlikte savcılığa suç duyurusunda bulununuz.