Python3 ile Kendi SOCKS5 Serverımızı Yapmak

DR4K0L0L

Katılımcı Üye
24 Şub 2016
891
1
Bu yazı RFC1928 ve RFC1929 baz alınarak oluşturulmuştur.


Python, Python'da Struct, Python'da Socket ve Python'da Select hakkında az da olsa bilgi sahibi olmanız gerekmektedir. SOCKS5 hakkında bilginiz olması yararınızadır. Yakın zamanda SOCKS5 hakkında bir konu açacağım. İsteyen o konuyu bekleyebilir, RFC1928'i ve RFC1929'u inceleyebilir ya da başka kaynaklardan yardım alabilir.


Evet, ilk olarak bizimle bağlantı kurmak isteyen SOCKS5 istemcilerini (client) dinleyecek bir sokete ihtiyacımız var.


Kod:
[COLOR=#cc7832]import [/COLOR]socket[COLOR=#cc7832], [/COLOR]select[COLOR=#cc7832], [/COLOR]threading[COLOR=#cc7832], [/COLOR]struct
[COLOR=#cc7832]if [/COLOR]__name__ == [COLOR=#6a8759]"__main__"[/COLOR]:
    dinleyiciSoket = socket.socket(socket.AF_INET[COLOR=#cc7832], [/COLOR]socket.SOCK_STREAM)
Soketimizi oluşturduk. Soketimize AF_INET parametresi ile IPv4 ve SOCK_STREAM parametresi ile TCP kullanmasını söyledik. Bundan sonraki adımda soketimizle bir portu dinleyeceğiz. Ben localhost üzerinde çalışacağım. Bu yüzden localhostun 1080. portunu soketime bağlıyorum.


Kod:
[COLOR=#cc7832]import [/COLOR]socket[COLOR=#cc7832], [/COLOR]select[COLOR=#cc7832], [/COLOR]threading[COLOR=#cc7832], [/COLOR]struct

[COLOR=#cc7832]if [/COLOR]__name__ == [COLOR=#6a8759]"__main__"[/COLOR]:
    dinleyiciSoket = socket.socket(socket.AF_INET[COLOR=#cc7832], [/COLOR]socket.SOCK_STREAM)
    dinleyiciSoket.setsockopt(socket.SOL_SOCKET[COLOR=#cc7832], [/COLOR]socket.SO_REUSEADDR[COLOR=#cc7832], [/COLOR][COLOR=#6897bb]1[/COLOR])
    dinleyiciSoket.bind(([COLOR=#6a8759]"127.0.0.1"[/COLOR][COLOR=#cc7832], [/COLOR][COLOR=#6897bb]1080[/COLOR]))
dinleyiciSoket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) ile eğer bind etmek istediğimiz IP ve port kullanılıyorsa kernela o IP ve portu kullanan soketin TIME_WAIT durumuna geçtiğinde o soketi bize salmasını rica ediyoruz.
dinleyiciSoket.bind(("127.0.0.1", 1080)) ise localhostun 1080. portuna soketimizi bağlamamızı sağlıyor.



Kod:
[COLOR=#cc7832]import [/COLOR]socket[COLOR=#cc7832], [/COLOR]select[COLOR=#cc7832], [/COLOR]threading[COLOR=#cc7832], [/COLOR]struct
[COLOR=#cc7832]if [/COLOR]__name__ == [COLOR=#6a8759]"__main__"[/COLOR]:
    dinleyiciSoket = socket.socket(socket.AF_INET[COLOR=#cc7832], [/COLOR]socket.SOCK_STREAM)
    dinleyiciSoket.setsockopt(socket.SOL_SOCKET[COLOR=#cc7832], [/COLOR]socket.SO_REUSEADDR[COLOR=#cc7832], [/COLOR][COLOR=#6897bb]1[/COLOR])
    dinleyiciSoket.bind(([COLOR=#6a8759]"127.0.0.1"[/COLOR][COLOR=#cc7832], [/COLOR][COLOR=#6897bb]1080[/COLOR]))
    dinleyiciSoket.listen([COLOR=#6897bb]20[/COLOR])
    [COLOR=#cc7832]while True[/COLOR]:
        gelenBaglantiSoket[COLOR=#cc7832], [/COLOR]_ = dinleyiciSoket.accept()
        gelenBaglantiSoket.settimeout([COLOR=#6897bb]5.0[/COLOR])
        threading.Thread([COLOR=#aa4926]target[/COLOR]=handler[COLOR=#cc7832], [/COLOR][COLOR=#aa4926]args[/COLOR]=(gelenBaglantiSoket[COLOR=#cc7832],[/COLOR])).start()
Sunucumuzu döngüye sokuyoruz ve dinleyici soketimize gelen bağlantıları kabul edip handler fonksiyonumuza gönderiyoruz. Ayrıca kabul ettiğimiz bağlantılara 5 saniyelik bir zaman aşımı süresi tanıyoruz. Eğer bir SOCKS5 clientı bize 5 saniye içinde (Veri transferinde zaman aşımı süresi 30 saniye olacaktır.) veri göndermezse bağlantı sonlandırılacaktır. Birden fazla gelen bağlantıyla aynı anda meşgul olabilmek için Thread kullanıyoruz.

Kod:
[COLOR=#cc7832]import [/COLOR]socket[COLOR=#cc7832], [/COLOR]select[COLOR=#cc7832], [/COLOR]threading[COLOR=#cc7832], [/COLOR]struct

SunucumuzunKullaniciAdi = [COLOR=#6a8759]"Bu_1_Sunucudur"
[/COLOR]SunucumuzunSifresi = [COLOR=#6a8759]"0123456789abc"
[/COLOR][COLOR=#6a8759]
[/COLOR][COLOR=#cc7832]def [/COLOR][COLOR=#ffc66d]handler[/COLOR](socksClientinSoketi):
    versiyon[COLOR=#cc7832], [/COLOR]methodSayisi = struct.unpack([COLOR=#6a8759]"!BB"[/COLOR][COLOR=#cc7832], [/COLOR]socksClientinSoketi.recv([COLOR=#6897bb]2[/COLOR]))
    [COLOR=#cc7832]if [/COLOR]versiyon != [COLOR=#6897bb]5 [/COLOR][COLOR=#cc7832]or [/COLOR]methodSayisi == [COLOR=#6897bb]0[/COLOR]:
        socksClientinSoketi.close()
        [COLOR=#cc7832]return
   [/COLOR]methodlar = []
    [COLOR=#cc7832]for [/COLOR]_ [COLOR=#cc7832]in [/COLOR][COLOR=#8888c6]range[/COLOR](methodSayisi):
        methodlar.append([COLOR=#8888c6]ord[/COLOR](socksClientinSoketi.recv([COLOR=#6897bb]1[/COLOR])))
Sunucumuza bağlanılırken kimlik doğrulaması için (biz sunucumuzda opsiyonel olarak kontrol edeceğiz ve kimlik doğrulamasız girişi de destekleyeceğiz.) bir kullanıcı adı ve bir şifre tanımladık. Handler fonksiyonumuzu yazmaya başlıyoruz. İlk olarak handler fonksiyonumuzu tanımladık ve sunucumuza bağlanan client ile veri alışverişinde bulunmamızı sağlayacak soketimizi parametre olarak aldık. Clientın bize göndereceği 2 baytlık veriyi bekledik ve bu 2 baytlık verinin 1. baytını versiyon değişkenine, 2. baytını methodSayisi değişkenine atadık. Biz bu sunucuda SOCKS5 kullandığımız için versiyon 5 haricinde herhangi bir değeri kabul etmeyeceğiz. Ayrıca eğer method sayısı 0 ise, diğer bir deyiş ile client bize desteklediği herhangi bir metod olmadığını söylüyor ise yine bunu kabul edemeyiz. Bağlantıyı sonlandırmak zorundayız. Eğer method sayısı verilmişse soketimizden method sayısı kadar bayt okuyoruz. Bu okunan her bir bayt clientın desteklediği kimlik doğrulama methodlarını göstermektedir. Clientın bize gönderdiği methodları methodlar adında bir listeye ekliyoruz.

Kod:
[COLOR=#cc7832]import [/COLOR]socket[COLOR=#cc7832], [/COLOR]select[COLOR=#cc7832], [/COLOR]threading[COLOR=#cc7832], [/COLOR]struct

SunucumuzunKullaniciAdi = [COLOR=#6a8759]"Bu_1_Sunucudur"
[/COLOR]SunucumuzunSifresi = [COLOR=#6a8759]"0123456789abc"
[/COLOR][COLOR=#6a8759]
[/COLOR][COLOR=#cc7832]def [/COLOR][COLOR=#ffc66d]handler[/COLOR](socksClientinSoketi):
    versiyon[COLOR=#cc7832], [/COLOR]methodSayisi = struct.unpack([COLOR=#6a8759]"!BB"[/COLOR][COLOR=#cc7832], [/COLOR]socksClientinSoketi.recv([COLOR=#6897bb]2[/COLOR]))
    [COLOR=#cc7832]if [/COLOR]versiyon != [COLOR=#6897bb]5 [/COLOR][COLOR=#cc7832]or [/COLOR]methodSayisi == [COLOR=#6897bb]0[/COLOR]:
        socksClientinSoketi.close()
        [COLOR=#cc7832]return
[/COLOR]methodlar = []
    [COLOR=#cc7832]for [/COLOR]_ [COLOR=#cc7832]in [/COLOR][COLOR=#8888c6]range[/COLOR](methodSayisi):
        methodlar.append([COLOR=#8888c6]ord[/COLOR](socksClientinSoketi.recv([COLOR=#6897bb]1[/COLOR])))
    [COLOR=#cc7832]if [/COLOR][COLOR=#6897bb]2 [/COLOR][COLOR=#cc7832]in [/COLOR]methodlar:
        socksClientinSoketi.sendall(struct.pack([COLOR=#6a8759]"!BB"[/COLOR][COLOR=#cc7832], [/COLOR][COLOR=#6897bb]5[/COLOR][COLOR=#cc7832], [/COLOR][COLOR=#6897bb]2[/COLOR]))
        [COLOR=#cc7832]if [/COLOR][COLOR=#8888c6]ord[/COLOR](socksClientinSoketi.recv([COLOR=#6897bb]1[/COLOR])) == [COLOR=#6897bb]1[/COLOR]:
            clientinGonderdigiKullaniciAdi = socksClientinSoketi.recv([COLOR=#8888c6]ord[/COLOR](socksClientinSoketi.recv([COLOR=#6897bb]1[/COLOR]))).decode([COLOR=#6a8759]'utf-8'[/COLOR])
            clientinGonderdigiSifre = socksClientinSoketi.recv([COLOR=#8888c6]ord[/COLOR](socksClientinSoketi.recv([COLOR=#6897bb]1[/COLOR]))).decode([COLOR=#6a8759]'utf-8'[/COLOR])
            [COLOR=#cc7832]if [/COLOR]clientinGonderdigiKullaniciAdi != SunucumuzunKullaniciAdi [COLOR=#cc7832]or [/COLOR]clientinGonderdigiSifre != SunucumuzunSifresi:
                socksClientinSoketi.sendall(struct.pack([COLOR=#6a8759]"!BB"[/COLOR][COLOR=#cc7832], [/COLOR][COLOR=#6897bb]1[/COLOR][COLOR=#cc7832], [/COLOR][COLOR=#6897bb]255[/COLOR]))
                socksClientinSoketi.close()
                [COLOR=#cc7832]return
[/COLOR]socksClientinSoketi.sendall(struct.pack([COLOR=#6a8759]"!BB"[/COLOR][COLOR=#cc7832], [/COLOR][COLOR=#6897bb]1[/COLOR][COLOR=#cc7832], [/COLOR][COLOR=#6897bb]0[/COLOR]))
        [COLOR=#cc7832]else[/COLOR]:
            socksClientinSoketi.close()
            [COLOR=#cc7832]return
[/COLOR][COLOR=#cc7832]    elif [/COLOR][COLOR=#6897bb]0 [/COLOR][COLOR=#cc7832]in [/COLOR]methodlar:
        socksClientinSoketi.sendall(struct.pack([COLOR=#6a8759]"!BB"[/COLOR][COLOR=#cc7832], [/COLOR][COLOR=#6897bb]5[/COLOR][COLOR=#cc7832], [/COLOR][COLOR=#6897bb]0[/COLOR]))
    [COLOR=#cc7832]else[/COLOR]:
        socksClientinSoketi.sendall(struct.pack([COLOR=#6a8759]"!BB"[/COLOR][COLOR=#cc7832], [/COLOR][COLOR=#6897bb]5[/COLOR][COLOR=#cc7832], [/COLOR][COLOR=#6897bb]255[/COLOR]))
        socksClientinSoketi.close()
        [COLOR=#cc7832]return[/COLOR]
Biz sunucumuzda desteklenen kimlik doğrulama methodları olarak hiç kimlik doğrulama methodu kullanılmasın (0) veya RFC1929'da bahsedilen kimlik doğrulama methodu (2) kullanılsın istiyoruz. Eğer client, bu iki methodtan (0 ve 2) en az birini desteklemiyorsa hiçbir methodun desteklenmediğini belirtmek için clienta 255 (0xFF) desteklenen method yok kodu gönderiyoruz. Ardından bağlantıyı sonlandırıyoruz.


Eğer SOCKS5 clientı kullanıcı adı/şifre doğrulaması yapabiliyorsa kullanıcı adı/şifre doğrulamasını seçiyoruz ve SOCKS5 clientına gönderiyoruz. Clienttan alacağımız ilk bayt kimlik doğrulamasının versiyonunu temsil ediyor ve bu kullandığımız kimlik doğrulama methodu için 1 olmak zorunda. Eğer 1 değilse bağlantıyı kapatıyoruz. Bundan sonraki okuduğumuz bayt, bize kullanıcı adının uzunluğunu veriyor ve bu baytın değeri kadar daha okuyup bu okuduğumuz değeri kullanıcı adı değişkenimize yazıyoruz. Bu işlemden sonra bir bayt daha okuyoruz ve bu okuduğumuz bayt da şifrenin uzunluğunu veriyor. Bu baytın değeri kadar daha okuyarak şifreyi almış oluyoruz ve şifre değişkenimize atıyoruz. Daha sonra clienttan aldığımız bu kullanıcı adı ve şifreyi kendi sunucumuzda tuttuğumuz kullanıcı adı (SunucumuzunKullaniciAdi değişkeni) ve şifreyle (SunucumuzunSifresi) karşılaştırıyoruz. Eğer client ve sunucunun kullanıcı adları veya şifreleri birbiriyle uyuşmuyorsa 255 durum kodunu gönderiyoruz ve kimlik doğrulamanın başarısız olduğunu belirtmiş oluyoruz. Ardından bağlantıyı kapatıyoruz. Eğer client ve sunucunun kullanıcı adları ve şifreleri birbiriyle uyuşmuş ise 0 durum kodunu gönderiyoruz ve kimlik doğrulamanın başarılı olduğunu belirtmiş oluyoruz.


Eğer SOCKS5 clientı kullanıcı adı/şifre doğrulaması yapmıyorsa ve hiçbir kimlik doğrulama methodu kullanılmasın diyorsa clienta 0 (kimlik doğrulama methodu kullanılmasın) durumunu gönderiyoruz.


Eğer SOCKS5 clientı yukarıda bahsettiklerimizin ikisini de desteklemiyorsa 255 (kabul edilebilir method bulunmuyor) durumunu gönderiyoruz ve bağlantıyı sonlandırıyoruz.


Kod:
[COLOR=#cc7832]import [/COLOR]socket[COLOR=#cc7832], [/COLOR]select[COLOR=#cc7832], [/COLOR]threading[COLOR=#cc7832], [/COLOR]struct

SunucumuzunKullaniciAdi = [COLOR=#6a8759]"Bu_1_Sunucudur"
[/COLOR]SunucumuzunSifresi = [COLOR=#6a8759]"0123456789abc"
[/COLOR][COLOR=#6a8759]
[/COLOR][COLOR=#cc7832]def [/COLOR][COLOR=#ffc66d]handler[/COLOR](socksClientinSoketi):
    versiyon[COLOR=#cc7832], [/COLOR]methodSayisi = struct.unpack([COLOR=#6a8759]"!BB"[/COLOR][COLOR=#cc7832], [/COLOR]socksClientinSoketi.recv([COLOR=#6897bb]2[/COLOR]))
    [COLOR=#cc7832]if [/COLOR]versiyon != [COLOR=#6897bb]5 [/COLOR][COLOR=#cc7832]or [/COLOR]methodSayisi == [COLOR=#6897bb]0[/COLOR]:
        socksClientinSoketi.close()
        [COLOR=#cc7832]return
[/COLOR]methodlar = []
    [COLOR=#cc7832]for [/COLOR]_ [COLOR=#cc7832]in [/COLOR][COLOR=#8888c6]range[/COLOR](methodSayisi):
        methodlar.append([COLOR=#8888c6]ord[/COLOR](socksClientinSoketi.recv([COLOR=#6897bb]1[/COLOR])))
    [COLOR=#cc7832]if [/COLOR][COLOR=#6897bb]2 [/COLOR][COLOR=#cc7832]in [/COLOR]methodlar:
        socksClientinSoketi.sendall(struct.pack([COLOR=#6a8759]"!BB"[/COLOR][COLOR=#cc7832], [/COLOR][COLOR=#6897bb]5[/COLOR][COLOR=#cc7832], [/COLOR][COLOR=#6897bb]2[/COLOR]))
        [COLOR=#cc7832]if [/COLOR][COLOR=#8888c6]ord[/COLOR](socksClientinSoketi.recv([COLOR=#6897bb]1[/COLOR])) == [COLOR=#6897bb]1[/COLOR]:
            clientinGonderdigiKullaniciAdi = socksClientinSoketi.recv([COLOR=#8888c6]ord[/COLOR](socksClientinSoketi.recv([COLOR=#6897bb]1[/COLOR]))).decode([COLOR=#6a8759]'utf-8'[/COLOR])
            clientinGonderdigiSifre = socksClientinSoketi.recv([COLOR=#8888c6]ord[/COLOR](socksClientinSoketi.recv([COLOR=#6897bb]1[/COLOR]))).decode([COLOR=#6a8759]'utf-8'[/COLOR])
            [COLOR=#cc7832]if [/COLOR]clientinGonderdigiKullaniciAdi != SunucumuzunKullaniciAdi [COLOR=#cc7832]or [/COLOR]clientinGonderdigiSifre != SunucumuzunSifresi:
                socksClientinSoketi.sendall(struct.pack([COLOR=#6a8759]"!BB"[/COLOR][COLOR=#cc7832], [/COLOR][COLOR=#6897bb]1[/COLOR][COLOR=#cc7832], [/COLOR][COLOR=#6897bb]255[/COLOR]))
                socksClientinSoketi.close()
                [COLOR=#cc7832]return
[/COLOR]socksClientinSoketi.sendall(struct.pack([COLOR=#6a8759]"!BB"[/COLOR][COLOR=#cc7832], [/COLOR][COLOR=#6897bb]1[/COLOR][COLOR=#cc7832], [/COLOR][COLOR=#6897bb]0[/COLOR]))
        [COLOR=#cc7832]else[/COLOR]:
            socksClientinSoketi.close()
            [COLOR=#cc7832]return
[/COLOR][COLOR=#cc7832]    elif [/COLOR][COLOR=#6897bb]0 [/COLOR][COLOR=#cc7832]in [/COLOR]methodlar:
        socksClientinSoketi.sendall(struct.pack([COLOR=#6a8759]"!BB"[/COLOR][COLOR=#cc7832], [/COLOR][COLOR=#6897bb]5[/COLOR][COLOR=#cc7832], [/COLOR][COLOR=#6897bb]0[/COLOR]))
    [COLOR=#cc7832]else[/COLOR]:
        socksClientinSoketi.sendall(struct.pack([COLOR=#6a8759]"!BB"[/COLOR][COLOR=#cc7832], [/COLOR][COLOR=#6897bb]5[/COLOR][COLOR=#cc7832], [/COLOR][COLOR=#6897bb]255[/COLOR]))
        socksClientinSoketi.close()
        [COLOR=#cc7832]return
[/COLOR]versiyon[COLOR=#cc7832], [/COLOR]komut[COLOR=#cc7832], [/COLOR]rsv[COLOR=#cc7832], [/COLOR]adres_tipi = struct.unpack([COLOR=#6a8759]"!BBBB"[/COLOR][COLOR=#cc7832], [/COLOR]socksClientinSoketi.recv([COLOR=#6897bb]4[/COLOR]))
    [COLOR=#cc7832]if [/COLOR]versiyon != [COLOR=#6897bb]5 [/COLOR][COLOR=#cc7832]or [/COLOR]rsv != [COLOR=#6897bb]0 [/COLOR][COLOR=#cc7832]or [/COLOR]komut != [COLOR=#6897bb]1[/COLOR]:
        socksClientinSoketi.close()
        [COLOR=#cc7832]return
[/COLOR][COLOR=#cc7832]    if [/COLOR]adres_tipi == [COLOR=#6897bb]1[/COLOR]:
        hedef_adres = socket.inet_ntoa(socksClientinSoketi.recv([COLOR=#6897bb]4[/COLOR]))
    [COLOR=#cc7832]elif [/COLOR]adres_tipi == [COLOR=#6897bb]3[/COLOR]:
        domainKarakterSayisi = [COLOR=#8888c6]ord[/COLOR](socksClientinSoketi.recv([COLOR=#6897bb]1[/COLOR]))
        hedef_adres = socksClientinSoketi.recv(domainKarakterSayisi)
    [COLOR=#cc7832]else[/COLOR]:
        socksClientinSoketi.close()
        [COLOR=#cc7832]return
[/COLOR]hedef_port = struct.unpack([COLOR=#6a8759]"!H"[/COLOR][COLOR=#cc7832], [/COLOR]socksClientinSoketi.recv([COLOR=#6897bb]2[/COLOR]))[[COLOR=#6897bb]0[/COLOR]]
Devamında clienttan 4 bayt veri alıyoruz. İlk bayt SOCKS versiyonunu belirtiyor ve versiyon değişkenine atanıyor. İkinci bayt clientın bu sunucuyu neden kullanmak istediğini belirtiyor (Biz sadece CONNECT (1) destekleyeceğiz.) ve komut değişkenine atanıyor. Üçüncü bayt bizim için gereksiz bilgi, o yüzden onu bir değişkene atamıyoruz. Dördüncü bayt, clientın bağlanmak istediği hedef sunucuyu bize tanıtırken hangi adres tipinde (IPv4, IPv6, Domain) gönderdiğini belirtiyor. Eğer versiyon bizim sunucumuzun versiyonu (SOCKS5 için 5) ile aynı değilse veya komut 1 değil ise bağlantıyı sonlandırıyoruz.

Eğer dördüncü bayt, yani adres tipi 1 (IPv4) ise soketten 4 bayt okuyup IPv4 adresini hedef_adres değişkenine kaydediyoruz. Eğer dördüncü bayt, yani adres tipi 3 (Domain) ise soketten bir bayt okuyup domainin kaç bayt uzunluğunda olduğunu öğreniyoruz. Soketten bu baytın değeri kadar daha bayt okuyunca domaini elde etmiş oluyoruz. Mesela domain 15 bayt uzunluğunda ise, bu okuduğumuz baytın değeri 15 olacaktır ve bu bayttan sonraki 15 bayt domainin her bir tekil karakterini temsil edecektir. Eğer adres tipi 4 (IPv6) ise bağlantıyı kapatıyoruz, çünkü bizim sunucumuz IPv6 desteklemiyor.

Ardından iki bayt daha okuyoruz. Bu iki bayt, port numaramızı Big Endian bayt sırasına göre okumamızı sağlayacak. Mesela 20000. portumuzu hexe çevirirsek 0x4e20 elde ederiz. Bu hex değerini 0x4e ve 0x20 olarak iki bayta paylaştırdığımızda Big Endian bayt sırasında yazmış oluyoruz. Tekrar bu iki baytı birleştirince 0x4e20 elde etmiş oluyoruz.

Kod:
[COLOR=#cc7832]import [/COLOR]socket[COLOR=#cc7832], [/COLOR]select[COLOR=#cc7832], [/COLOR]threading[COLOR=#cc7832], [/COLOR]struct

SunucumuzunKullaniciAdi = [COLOR=#6a8759]"Bu_1_Sunucudur"
[/COLOR]SunucumuzunSifresi = [COLOR=#6a8759]"0123456789abc"
[/COLOR][COLOR=#6a8759]
[/COLOR][COLOR=#cc7832]def [/COLOR][COLOR=#ffc66d]handler[/COLOR](socksClientinSoketi):
    versiyon[COLOR=#cc7832], [/COLOR]methodSayisi = struct.unpack([COLOR=#6a8759]"!BB"[/COLOR][COLOR=#cc7832], [/COLOR]socksClientinSoketi.recv([COLOR=#6897bb]2[/COLOR]))
    [COLOR=#cc7832]if [/COLOR]versiyon != [COLOR=#6897bb]5 [/COLOR][COLOR=#cc7832]or [/COLOR]methodSayisi == [COLOR=#6897bb]0[/COLOR]:
        socksClientinSoketi.close()
        [COLOR=#cc7832]return
[/COLOR]methodlar = []
    [COLOR=#cc7832]for [/COLOR]_ [COLOR=#cc7832]in [/COLOR][COLOR=#8888c6]range[/COLOR](methodSayisi):
        methodlar.append([COLOR=#8888c6]ord[/COLOR](socksClientinSoketi.recv([COLOR=#6897bb]1[/COLOR])))
    [COLOR=#cc7832]if [/COLOR][COLOR=#6897bb]2 [/COLOR][COLOR=#cc7832]in [/COLOR]methodlar:
        socksClientinSoketi.sendall(struct.pack([COLOR=#6a8759]"!BB"[/COLOR][COLOR=#cc7832], [/COLOR][COLOR=#6897bb]5[/COLOR][COLOR=#cc7832], [/COLOR][COLOR=#6897bb]2[/COLOR]))
        [COLOR=#cc7832]if [/COLOR][COLOR=#8888c6]ord[/COLOR](socksClientinSoketi.recv([COLOR=#6897bb]1[/COLOR])) == [COLOR=#6897bb]1[/COLOR]:
            clientinGonderdigiKullaniciAdi = socksClientinSoketi.recv([COLOR=#8888c6]ord[/COLOR](socksClientinSoketi.recv([COLOR=#6897bb]1[/COLOR]))).decode([COLOR=#6a8759]'utf-8'[/COLOR])
            clientinGonderdigiSifre = socksClientinSoketi.recv([COLOR=#8888c6]ord[/COLOR](socksClientinSoketi.recv([COLOR=#6897bb]1[/COLOR]))).decode([COLOR=#6a8759]'utf-8'[/COLOR])
            [COLOR=#cc7832]if [/COLOR]clientinGonderdigiKullaniciAdi != SunucumuzunKullaniciAdi [COLOR=#cc7832]or [/COLOR]clientinGonderdigiSifre != SunucumuzunSifresi:
                socksClientinSoketi.sendall(struct.pack([COLOR=#6a8759]"!BB"[/COLOR][COLOR=#cc7832], [/COLOR][COLOR=#6897bb]1[/COLOR][COLOR=#cc7832], [/COLOR][COLOR=#6897bb]255[/COLOR]))
                socksClientinSoketi.close()
                [COLOR=#cc7832]return
[/COLOR]socksClientinSoketi.sendall(struct.pack([COLOR=#6a8759]"!BB"[/COLOR][COLOR=#cc7832], [/COLOR][COLOR=#6897bb]1[/COLOR][COLOR=#cc7832], [/COLOR][COLOR=#6897bb]0[/COLOR]))
        [COLOR=#cc7832]else[/COLOR]:
            socksClientinSoketi.close()
            [COLOR=#cc7832]return
[/COLOR][COLOR=#cc7832]    elif [/COLOR][COLOR=#6897bb]0 [/COLOR][COLOR=#cc7832]in [/COLOR]methodlar:
        socksClientinSoketi.sendall(struct.pack([COLOR=#6a8759]"!BB"[/COLOR][COLOR=#cc7832], [/COLOR][COLOR=#6897bb]5[/COLOR][COLOR=#cc7832], [/COLOR][COLOR=#6897bb]0[/COLOR]))
    [COLOR=#cc7832]else[/COLOR]:
        socksClientinSoketi.sendall(struct.pack([COLOR=#6a8759]"!BB"[/COLOR][COLOR=#cc7832], [/COLOR][COLOR=#6897bb]5[/COLOR][COLOR=#cc7832], [/COLOR][COLOR=#6897bb]255[/COLOR]))
        socksClientinSoketi.close()
        [COLOR=#cc7832]return
[/COLOR]versiyon[COLOR=#cc7832], [/COLOR]komut[COLOR=#cc7832], [/COLOR]rsv[COLOR=#cc7832], [/COLOR]adres_tipi = struct.unpack([COLOR=#6a8759]"!BBBB"[/COLOR][COLOR=#cc7832], [/COLOR]socksClientinSoketi.recv([COLOR=#6897bb]4[/COLOR]))
    [COLOR=#cc7832]if [/COLOR]versiyon != [COLOR=#6897bb]5 [/COLOR][COLOR=#cc7832]or [/COLOR]rsv != [COLOR=#6897bb]0 [/COLOR][COLOR=#cc7832]or [/COLOR]komut != [COLOR=#6897bb]1[/COLOR]:
        socksClientinSoketi.close()
        [COLOR=#cc7832]return
[/COLOR][COLOR=#cc7832]    if [/COLOR]adres_tipi == [COLOR=#6897bb]1[/COLOR]:
        hedef_adres = socket.inet_ntoa(socksClientinSoketi.recv([COLOR=#6897bb]4[/COLOR]))
    [COLOR=#cc7832]elif [/COLOR]adres_tipi == [COLOR=#6897bb]3[/COLOR]:
        domainKarakterSayisi = [COLOR=#8888c6]ord[/COLOR](socksClientinSoketi.recv([COLOR=#6897bb]1[/COLOR]))
        hedef_adres = socksClientinSoketi.recv(domainKarakterSayisi)
    [COLOR=#cc7832]else[/COLOR]:
        socksClientinSoketi.close()
        [COLOR=#cc7832]return
[/COLOR]hedef_port = struct.unpack([COLOR=#6a8759]"!H"[/COLOR][COLOR=#cc7832], [/COLOR]socksClientinSoketi.recv([COLOR=#6897bb]2[/COLOR]))[[COLOR=#6897bb]0[/COLOR]]
    [COLOR=#cc7832]try[/COLOR]:
        ClientinBaglanmakIstedigiHedefSunucu = socket.socket(socket.AF_INET[COLOR=#cc7832], [/COLOR]socket.SOCK_STREAM)
        ClientinBaglanmakIstedigiHedefSunucu.connect((hedef_adres[COLOR=#cc7832], [/COLOR]hedef_port))
        hedefeBaglandimizSoketimizinAdresi[COLOR=#cc7832], [/COLOR]hedefeBaglandimizSoketimizinPortu = ClientinBaglanmakIstedigiHedefSunucu.getsockname()[:[COLOR=#6897bb]2[/COLOR]]
        donut = struct.pack([COLOR=#6a8759]"!BBBB4sH"[/COLOR][COLOR=#cc7832], [/COLOR][COLOR=#6897bb]5[/COLOR][COLOR=#cc7832], [/COLOR][COLOR=#6897bb]0[/COLOR][COLOR=#cc7832], [/COLOR][COLOR=#6897bb]0[/COLOR][COLOR=#cc7832], [/COLOR][COLOR=#6897bb]1[/COLOR][COLOR=#cc7832], [/COLOR]socket.inet_aton(hedefeBaglandimizSoketimizinAdresi)[COLOR=#cc7832], [/COLOR]hedefeBaglandimizSoketimizinPortu)
    [COLOR=#cc7832]except [/COLOR][COLOR=#8888c6]Exception[/COLOR]:
        socksClientinSoketi.send(struct.pack([COLOR=#6a8759]"!BBBBIH"[/COLOR][COLOR=#cc7832], [/COLOR][COLOR=#6897bb]5[/COLOR][COLOR=#cc7832], [/COLOR][COLOR=#6897bb]1[/COLOR][COLOR=#cc7832], [/COLOR][COLOR=#6897bb]0[/COLOR][COLOR=#cc7832], [/COLOR][COLOR=#6897bb]0[/COLOR][COLOR=#cc7832], [/COLOR][COLOR=#6897bb]0[/COLOR][COLOR=#cc7832], [/COLOR][COLOR=#6897bb]0[/COLOR]))
        ClientinBaglanmakIstedigiHedefSunucu.close()
        socksClientinSoketi.close()
        [COLOR=#cc7832]return
[/COLOR]socksClientinSoketi.sendall(donut)
Burada SOCKS5 clientının bizden bağlanmamızı istediği sunucuya IPv4 ve TCP protokolleri ile bağlantı kuruyoruz. Bağlantı kurduğumuz soketten kaynak adresimizi ve kaynak portumuzu alıp değişkenlerimize atıyoruz. donut isimli değişkenimize SOCKS5 clientına göndereceğimiz yanıtı işliyoruz. İlk baytımız SOCKS versiyonumuz, yani 5. İkinci baytımız hedef sunucuya bağlanma girişimimizin başarıyla mı yoksa hatayla mı sonuçlandığını temsil ediyor. 0 haricindeki diğer değerler bir hatayla karşılaşıldığını bildiriyor. Üçüncü baytımız RSV, bu bayt her zaman 0 olmak zorunda. Dördüncü baytımız, SOCKS5 clientına göndereceğimiz kaynak adresimizin adres tipini belirtiyor ki biz IPv4 adresi göndereceğimiz için 1 (IPv4) seçiyoruz. Bundan sonraki 4 bayt kaynak adresimizi ve kaynak adresimizden sonraki 2 bayt Big Endian bayt sırasında yazılan portumuzu içerir.

Eğer yukarıdaki paragrafta anlattıklarım sırasında bir hata meydana gelirse, except bloğuna geçilir ve SOCKS5 clientına
"general SOCKS server failure" hatası (ikinci bayt, 0x01) döndürülür. Ben hatalarla uğraşmadım, dileyen kendisi bir hata yakalayıcı yapabilir.

Dönüt hazırlandıktan sonra bu dönüt SOCKS5 clientına gönderilir.


Kod:
[COLOR=#cc7832]import [/COLOR]socket[COLOR=#cc7832], [/COLOR]select[COLOR=#cc7832], [/COLOR]threading[COLOR=#cc7832], [/COLOR]struct

SunucumuzunKullaniciAdi = [COLOR=#6a8759]"Bu_1_Sunucudur"
[/COLOR]SunucumuzunSifresi = [COLOR=#6a8759]"0123456789abc"
[/COLOR][COLOR=#6a8759]
[/COLOR][COLOR=#cc7832]def [/COLOR][COLOR=#ffc66d]handler[/COLOR](socksClientinSoketi):
    versiyon[COLOR=#cc7832], [/COLOR]methodSayisi = struct.unpack([COLOR=#6a8759]"!BB"[/COLOR][COLOR=#cc7832], [/COLOR]socksClientinSoketi.recv([COLOR=#6897bb]2[/COLOR]))
    [COLOR=#cc7832]if [/COLOR]versiyon != [COLOR=#6897bb]5 [/COLOR][COLOR=#cc7832]or [/COLOR]methodSayisi == [COLOR=#6897bb]0[/COLOR]:
        socksClientinSoketi.close()
        [COLOR=#cc7832]return
[/COLOR]methodlar = []
    [COLOR=#cc7832]for [/COLOR]_ [COLOR=#cc7832]in [/COLOR][COLOR=#8888c6]range[/COLOR](methodSayisi):
        methodlar.append([COLOR=#8888c6]ord[/COLOR](socksClientinSoketi.recv([COLOR=#6897bb]1[/COLOR])))
    [COLOR=#cc7832]if [/COLOR][COLOR=#6897bb]2 [/COLOR][COLOR=#cc7832]in [/COLOR]methodlar:
        socksClientinSoketi.sendall(struct.pack([COLOR=#6a8759]"!BB"[/COLOR][COLOR=#cc7832], [/COLOR][COLOR=#6897bb]5[/COLOR][COLOR=#cc7832], [/COLOR][COLOR=#6897bb]2[/COLOR]))
        [COLOR=#cc7832]if [/COLOR][COLOR=#8888c6]ord[/COLOR](socksClientinSoketi.recv([COLOR=#6897bb]1[/COLOR])) == [COLOR=#6897bb]1[/COLOR]:
            clientinGonderdigiKullaniciAdi = socksClientinSoketi.recv([COLOR=#8888c6]ord[/COLOR](socksClientinSoketi.recv([COLOR=#6897bb]1[/COLOR]))).decode([COLOR=#6a8759]'utf-8'[/COLOR])
            clientinGonderdigiSifre = socksClientinSoketi.recv([COLOR=#8888c6]ord[/COLOR](socksClientinSoketi.recv([COLOR=#6897bb]1[/COLOR]))).decode([COLOR=#6a8759]'utf-8'[/COLOR])
            [COLOR=#cc7832]if [/COLOR]clientinGonderdigiKullaniciAdi != SunucumuzunKullaniciAdi [COLOR=#cc7832]or [/COLOR]clientinGonderdigiSifre != SunucumuzunSifresi:
                socksClientinSoketi.sendall(struct.pack([COLOR=#6a8759]"!BB"[/COLOR][COLOR=#cc7832], [/COLOR][COLOR=#6897bb]1[/COLOR][COLOR=#cc7832], [/COLOR][COLOR=#6897bb]255[/COLOR]))
                socksClientinSoketi.close()
                [COLOR=#cc7832]return
[/COLOR]socksClientinSoketi.sendall(struct.pack([COLOR=#6a8759]"!BB"[/COLOR][COLOR=#cc7832], [/COLOR][COLOR=#6897bb]1[/COLOR][COLOR=#cc7832], [/COLOR][COLOR=#6897bb]0[/COLOR]))
        [COLOR=#cc7832]else[/COLOR]:
            socksClientinSoketi.close()
            [COLOR=#cc7832]return
[/COLOR][COLOR=#cc7832]    elif [/COLOR][COLOR=#6897bb]0 [/COLOR][COLOR=#cc7832]in [/COLOR]methodlar:
        socksClientinSoketi.sendall(struct.pack([COLOR=#6a8759]"!BB"[/COLOR][COLOR=#cc7832], [/COLOR][COLOR=#6897bb]5[/COLOR][COLOR=#cc7832], [/COLOR][COLOR=#6897bb]0[/COLOR]))
    [COLOR=#cc7832]else[/COLOR]:
        socksClientinSoketi.sendall(struct.pack([COLOR=#6a8759]"!BB"[/COLOR][COLOR=#cc7832], [/COLOR][COLOR=#6897bb]5[/COLOR][COLOR=#cc7832], [/COLOR][COLOR=#6897bb]255[/COLOR]))
        socksClientinSoketi.close()
        [COLOR=#cc7832]return
[/COLOR]versiyon[COLOR=#cc7832], [/COLOR]komut[COLOR=#cc7832], [/COLOR]rsv[COLOR=#cc7832], [/COLOR]adres_tipi = struct.unpack([COLOR=#6a8759]"!BBBB"[/COLOR][COLOR=#cc7832], [/COLOR]socksClientinSoketi.recv([COLOR=#6897bb]4[/COLOR]))
    [COLOR=#cc7832]if [/COLOR]versiyon != [COLOR=#6897bb]5 [/COLOR][COLOR=#cc7832]or [/COLOR]rsv != [COLOR=#6897bb]0 [/COLOR][COLOR=#cc7832]or [/COLOR]komut != [COLOR=#6897bb]1[/COLOR]:
        socksClientinSoketi.close()
        [COLOR=#cc7832]return
[/COLOR][COLOR=#cc7832]    if [/COLOR]adres_tipi == [COLOR=#6897bb]1[/COLOR]:
        hedef_adres = socket.inet_ntoa(socksClientinSoketi.recv([COLOR=#6897bb]4[/COLOR]))
    [COLOR=#cc7832]elif [/COLOR]adres_tipi == [COLOR=#6897bb]3[/COLOR]:
        domainKarakterSayisi = [COLOR=#8888c6]ord[/COLOR](socksClientinSoketi.recv([COLOR=#6897bb]1[/COLOR]))
        hedef_adres = socksClientinSoketi.recv(domainKarakterSayisi)
    [COLOR=#cc7832]else[/COLOR]:
        socksClientinSoketi.close()
        [COLOR=#cc7832]return
[/COLOR]hedef_port = struct.unpack([COLOR=#6a8759]"!H"[/COLOR][COLOR=#cc7832], [/COLOR]socksClientinSoketi.recv([COLOR=#6897bb]2[/COLOR]))[[COLOR=#6897bb]0[/COLOR]]
    [COLOR=#cc7832]try[/COLOR]:
        ClientinBaglanmakIstedigiHedefSunucu = socket.socket(socket.AF_INET[COLOR=#cc7832], [/COLOR]socket.SOCK_STREAM)
        ClientinBaglanmakIstedigiHedefSunucu.connect((hedef_adres[COLOR=#cc7832], [/COLOR]hedef_port))
        hedefeBaglandimizSoketimizinAdresi[COLOR=#cc7832], [/COLOR]hedefeBaglandimizSoketimizinPortu = ClientinBaglanmakIstedigiHedefSunucu.getsockname()[:[COLOR=#6897bb]2[/COLOR]]
        donut = struct.pack([COLOR=#6a8759]"!BBBB4sH"[/COLOR][COLOR=#cc7832], [/COLOR][COLOR=#6897bb]5[/COLOR][COLOR=#cc7832], [/COLOR][COLOR=#6897bb]0[/COLOR][COLOR=#cc7832], [/COLOR][COLOR=#6897bb]0[/COLOR][COLOR=#cc7832], [/COLOR][COLOR=#6897bb]1[/COLOR][COLOR=#cc7832], [/COLOR]socket.inet_aton(hedefeBaglandimizSoketimizinAdresi)[COLOR=#cc7832], [/COLOR]hedefeBaglandimizSoketimizinPortu)
    [COLOR=#cc7832]except [/COLOR][COLOR=#8888c6]Exception[/COLOR]:
        socksClientinSoketi.send(struct.pack([COLOR=#6a8759]"!BBBBIH"[/COLOR][COLOR=#cc7832], [/COLOR][COLOR=#6897bb]5[/COLOR][COLOR=#cc7832], [/COLOR][COLOR=#6897bb]1[/COLOR][COLOR=#cc7832], [/COLOR][COLOR=#6897bb]0[/COLOR][COLOR=#cc7832], [/COLOR][COLOR=#6897bb]0[/COLOR][COLOR=#cc7832], [/COLOR][COLOR=#6897bb]0[/COLOR][COLOR=#cc7832], [/COLOR][COLOR=#6897bb]0[/COLOR]))
        ClientinBaglanmakIstedigiHedefSunucu.close()
        socksClientinSoketi.close()
        [COLOR=#cc7832]return
[/COLOR]socksClientinSoketi.sendall(donut)
    [COLOR=#cc7832]while True[/COLOR]:
        okunabilirSoketler[COLOR=#cc7832], [/COLOR]_[COLOR=#cc7832], [/COLOR]_ = select.select([socksClientinSoketi[COLOR=#cc7832], [/COLOR]ClientinBaglanmakIstedigiHedefSunucu][COLOR=#cc7832], [/COLOR][][COLOR=#cc7832], [/COLOR][][COLOR=#cc7832], [/COLOR][COLOR=#6897bb]30[/COLOR])
        [COLOR=#cc7832]if not [/COLOR]okunabilirSoketler:
            [COLOR=#cc7832]break
[/COLOR][COLOR=#cc7832]        if [/COLOR]socksClientinSoketi [COLOR=#cc7832]in [/COLOR]okunabilirSoketler:
            [COLOR=#cc7832]try[/COLOR]:
                [COLOR=#cc7832]if [/COLOR]ClientinBaglanmakIstedigiHedefSunucu.send(socksClientinSoketi.recv([COLOR=#6897bb]4096[/COLOR])) <= [COLOR=#6897bb]0[/COLOR]:
                    [COLOR=#cc7832]break
[/COLOR][COLOR=#cc7832]            except [/COLOR]socket.error:
                [COLOR=#cc7832]break
[/COLOR][COLOR=#cc7832]        if [/COLOR]ClientinBaglanmakIstedigiHedefSunucu [COLOR=#cc7832]in [/COLOR]okunabilirSoketler:
            [COLOR=#cc7832]try[/COLOR]:
                [COLOR=#cc7832]if [/COLOR]socksClientinSoketi.send(ClientinBaglanmakIstedigiHedefSunucu.recv([COLOR=#6897bb]4096[/COLOR])) <= [COLOR=#6897bb]0[/COLOR]:
                    [COLOR=#cc7832]break
[/COLOR][COLOR=#cc7832]            except [/COLOR]socket.error:
                [COLOR=#cc7832]break
[/COLOR]socksClientinSoketi.close()
    ClientinBaglanmakIstedigiHedefSunucu.close()
Sonrasında sonsuz döngüye giriyoruz. Döngümüzde Select kütüphanesinden seçtiğimiz Select fonksiyonumuzla SOCKS5 clienta bağlı olan soketimiz ve hedef sunucuya bağlı olan soketimizin veri döndürüp döndürmediğini kontrol ettiriyor ve SOCKS5 client ile hedef sunucu arasında veri transferi başlatıyoruz. Select fonksiyonuna 30 saniyelik bir zaman aşımı süresi veriyoruz ve bu zaman aşımı bitiminde eğer herhangi bir veri alınmadıysa veri transferini durduruyoruz. Ayrıca soketlerin döndüreceği hatalarda da veri transferini durduruyoruz.


Kodu BU LİNKten edinmeniz en sağlıklısıdır. Konudaki kodlar maalesef kaymış, yamulmuş.


Eğer konuda herhangi bir yanlış ya da eksik bilgi görürseniz bana bildirebilir ve düzeltilmesini sağlayabilirsiniz. Aynı şekilde kodun daha iyi bir hale getirilmesi için de bana bildirilebilir ve düzeltilmesini sağlayabilirsiniz. İyi günler dilerim. :yardimsever
 
Son düzenleme:
Ü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.