简单实现Socks5代理(Python&

发布时间:2019-08-29 07:38:30编辑:auto阅读(1635)

    只实现了CONNECT功能

    参考:点击打开链接


    Python版:

    import socket
    import threading
    import select
    import time
    
    IsNeedAuth=False
    Username='admin'
    Password='123456'
    Port=7456
    
    def prxoy(sock,address): 
        cs = sock  
        DspPort=0
        DspAddr=''    
        try:
            recv= cs.recv(512)
            VER=recv[0:1]
            #MethodNum=ord(recv[1:2])
            #Methods=[]
            #for i in range(0,MethodNum):
               # Methods.append(ord(recv[2+i:3+i]))
            if(IsNeedAuth):          #Need AUTHENICATION
                cs.send(b'\x05\x02')     #Reply
                recv= cs.recv(1024)
                Ver=recv[0:1]
                UserLen=ord(recv[1:2])
                User=recv[2:2+UserLen]
                PassLen=ord(recv[2+UserLen:3+UserLen])
                Pass=recv[3+UserLen:3+UserLen+PassLen]
                if (User==Username and Pass==Password):
                    cs.send(Ver+'\x00')
                else:
                    cs.send(Ver+'\xff')
                    cs.close()
                    return 
            else:
                cs.send(VER+'\x00')  #  NO AUTHENICATION REQUEST
            try :
                recv= cs.recv(1024)
            except Exception,ex:
                 print 'Client is Closed'
                 return
            CMD=ord(recv[1:2])
            ATYP=ord(recv[3:4])
            if(CMD ==0x01):             # CONNECT CMD
                if (ATYP==03):                      # DOMAINNAME
                    AddrLen=ord(recv[4:5])
                    DspPort=256*ord(recv[5+AddrLen:5+AddrLen+1])+ord(recv[1+5+AddrLen:5+AddrLen+2])
                    DspAddr=socket.gethostbyname(recv[5:5+AddrLen])
                elif (ATYP==01):                     #IPV4
                    if (recv.count('.')==4):    # Asiic  format  split by  '.'
                        AddrLen=ord(recv[4:5])
                        DspAddr=recv[5:5+AddrLen]
                        DspPort=256*ord(recv[5+AddrLen:5+AddrLen+1])+ord(recv[5+AddrLen+1:5+AddrLen+2])
                    else:                                      #four hex number format
                        DspAddr=recv[4:8]
                        DspAddrr=''
                        for i in DspAddr:
                            DspAddrr +=str(ord(i))+'.'
                        DspAddr=DspAddrr[:-1]
                        DspPort=256*ord(recv[4+4:4+4+1])+ord(recv[4+4+1:4+4+2])
                else:
                    print "IPV6 is not support"
                    return
                cs.send(VER+'\x00\x00\x01\x00\x00\x00\x00\x00\x00')   # REPLY
                forward(cs,DspAddr,DspPort)
            else :
                print "Don't suport  this Cmd",CMD
        except Exception,e:
            print e
    
    def forward(cs,DspAddr,DspPort):
        try:
            #print DspAddr +'\n'
            ss = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
            
            ss.connect((DspAddr, DspPort))
        except Exception,e:
                    print "Connect to ",DspAddr,"Fail"
                    return
        socks=[]
        socks.append(cs)
        socks.append(ss)
        while(True):
           try:
            r, w, e = select.select(socks, [], [])
            for s in r:
                if s is cs:
                    recv=cs.recv(2048)
                    caddr,cport= cs.getpeername()
                    if (len(recv) >0):
                        saddr,sport=ss.getpeername()
                        print caddr,':',cport,'<',len(recv),'>',saddr,':',sport
                        ss.send(recv)
                        
                    else:
                        for sock in socks:
                            sock.close()
                        return
                elif s is ss:           
                    recv=ss.recv(2048)
                    saddr,sport= ss.getpeername()                
                    if (len(recv) >0):
                        caddr,cport= cs.getpeername()
                        print saddr,':',sport,'<',len(recv),'>',caddr,':',cport
                        cs.send(recv)
                    else:
                        for sock in socks:
                            sock.close()
                        return
           except Exception,e:
                print "Translate data error"
                break            
    
    if __name__ == "__main__":
        ls = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        ls.bind(('0.0.0.0',Port))
        ls.listen(500)
        while (True):
            clientSock, address = ls.accept()
            thread = threading.Thread(target=prxoy, args=(clientSock,address))
            thread.start()
    
    

    C#版:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Net.Sockets;
    using System.Net;
    using System.Threading;
    using System.Collections;
    
    namespace ProxyTest
    {
        class Program
        {
            static string Username = "test";
    
            static string Password = "test";
    
            static public bool IsRun = false;
            static bool IsNeedAuth = false;
            static Socket ProxySocket;
            static int ListenPort = 1080;
            static ArrayList ClientSocks = new ArrayList();
            static int SockNum = 0;
            static object obj = new object();
            static void BeginProxy()
            {
                IsRun = true;
                IPAddress ip = IPAddress.Parse("0.0.0.0");
                ProxySocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                ProxySocket.Bind(new IPEndPoint(ip, ListenPort));
                ProxySocket.Listen(100);
                Console.WriteLine("Bind On 0.0.0.0:" + ListenPort.ToString());
                while (IsRun)
                {
                    try
                    {
                        Socket clientSocket = ProxySocket.Accept();
                        Console.WriteLine(" 接受了来自 " + ((IPEndPoint)clientSocket.RemoteEndPoint).Address.ToString() +":" +((IPEndPoint)clientSocket.RemoteEndPoint).Port.ToString() + "的连接");
                        ClientSocks.Add(clientSocket);
                        Thread T = new Thread(ProcessClient);
                        T.Start(clientSocket);
                    }
                    catch
                    {
                        break;
                    }
                }
    
            }
    
    
    
            static void StartTransData(Socket clisock, Socket sersock)
            {
                int SocketNum;
                byte[] RecvBuf = new byte[1024*4];
                lock (obj)
                {
                    SocketNum = ++SockNum;
                }
                int Len;
    
    
                String DstHost = ((IPEndPoint)sersock.RemoteEndPoint).Address.ToString() + ":";
                DstHost += ((IPEndPoint)sersock.RemoteEndPoint).Port.ToString();
                String SrcHost = ((IPEndPoint)sersock.LocalEndPoint).Address.ToString() + ":";
                SrcHost += ((IPEndPoint)sersock.LocalEndPoint).Port.ToString();
                while (IsRun)
                {
    
                    try
                    {
                        if (clisock.Poll(1000, SelectMode.SelectRead))
                        {
    
                            Len = clisock.Receive(RecvBuf);
    
    
    
                            if (Len == 0)
                            {
                                clisock.Shutdown(SocketShutdown.Both);
                                clisock.Close();
                                sersock.Shutdown(SocketShutdown.Both);
                                sersock.Close();
                                break;
                            }
                            else
                            {
                                Len = sersock.Send(RecvBuf, 0, Len, 0);
                                Console.WriteLine("【" + SockNum.ToString() + "】" +  SrcHost + "==>" + DstHost + "[发送" + Len.ToString() + "字节]");
    
    
                            }
    
                        }
                        if (sersock.Poll(1000, SelectMode.SelectRead))
                        {
    
                            Len = sersock.Receive(RecvBuf);
    
    
                            if (Len == 0)
                            {
                                sersock.Shutdown(SocketShutdown.Both);
                                sersock.Close();
                                clisock.Shutdown(SocketShutdown.Both);
                                clisock.Close();
                                break;
                            }
                            else
                            {
                                Len = clisock.Send(RecvBuf, 0, Len, 0);
                                Console.WriteLine("【" + SockNum.ToString() + "】" + DstHost + " ==> " + SrcHost + " [接收" + Len.ToString() + "字节]");
    
    
                            }
    
    
    
                        }
                    }
                    catch
                    {
    
                        break;
    
    
                    }
                }
    
    
            }
            static void ProcessClient(object sock)
            {
                byte[] RecvBuf = new byte[1024];
                Socket CliSock = (Socket)sock;
                Socket ServerSock;
                IPAddress ip = null;
                int Port = 0;
                byte[] buf = new byte[1024];
                int Len = 0;
                try
                {
                    Len = CliSock.Receive(buf);
    
                    byte SockVer = buf[0];
    
                    if (IsNeedAuth)
                    {
                        CliSock.Send(new byte[] { 0x05, 0x02 });  //需要验证
                        Len = CliSock.Receive(buf);
                        byte UserLen = buf[1];
                        byte[] User = new byte[UserLen];
                        Buffer.BlockCopy(buf, 2, User, 0, UserLen);
    
    
    
                        byte PassLen = buf[2 + UserLen];
                        byte[] Pass = new byte[PassLen];
    
                        Buffer.BlockCopy(buf, 3 + PassLen, Pass, 0, PassLen);
                        if (Encoding.ASCII.GetString(User) == Username && Encoding.ASCII.GetString(Pass) == Password)
                        {
                            CliSock.Send(new byte[] { 0x05, 0x00 });
                        }
                        else
                        {
                            CliSock.Send(new byte[] { 0x05, 0xff });
                            CliSock.Close();
                        }
                    }
                    else
                    {
                        CliSock.Send(new byte[] { 0x05, 0x00 });
                    }
                }
                catch
                {
    
                }
                try
                {
                    Len = CliSock.Receive(RecvBuf);
                    byte CMD = RecvBuf[1];
                    byte ATYP = RecvBuf[3];
                    if (CMD == 0x01)
                    {
                        if (ATYP == 0x01)
                        {
                            if (RecvBuf.ToString().Split('.').Length == 5)
                            {
                                byte AddrLen = RecvBuf[4];
                                byte[] Addr = new byte[AddrLen];
                                Buffer.BlockCopy(RecvBuf, 5, Addr, 0, AddrLen);
                                IPAddress[] ips = Dns.GetHostAddresses(Addr.ToString());
                                ip = ips[0];
                                Port = 256 * RecvBuf[AddrLen + 5] + RecvBuf[AddrLen + 6];
                            }
                            else
                            {
                                byte[] Addr = new byte[4];
                                Buffer.BlockCopy(RecvBuf, 4, Addr, 0, 4);
                                String sip = "";
                                foreach (byte b in Addr)
                                {
                                    sip += b.ToString() + ".";
                                }
                                IPAddress[] ips = Dns.GetHostAddresses(sip.Remove(sip.Length - 1));
                                ip = ips[0];
                                Port = 256 * RecvBuf[9] + RecvBuf[10];
                            }
                        }
                        else if (ATYP == 0x03)
                        {
                            byte AddrLen = RecvBuf[4];
                            byte[] Addr = new byte[AddrLen];
                            Buffer.BlockCopy(RecvBuf, 5, Addr, 0, AddrLen);
    
                            String HostName = System.Text.Encoding.Default.GetString(Addr);
                            IPAddress[] ips = Dns.GetHostAddresses(HostName);
                            ip = ips[0];
                            Port = 256 * RecvBuf[AddrLen + 5] + RecvBuf[AddrLen + 6];
                        }
    
                        else
                        {
    
                            return;
                        }
    
                        CliSock.Send(new byte[] { 0x05, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 });
                    }
                }
                catch
                {
                    return;
                }
    
                try
                {
                    ServerSock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    
                    ServerSock.Connect(ip, Port);
    
                    StartTransData(CliSock, ServerSock);
                }
                catch
                {
                    CliSock.Shutdown(SocketShutdown.Both);
                    CliSock.Close();
                    return;
                }
    
    
            }
    
            static void Main(string[] args)
            {
                BeginProxy();
            }
        }
    }
    





关键字