首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >简单实现Socks5代理(Python&

简单实现Socks5代理(Python&

作者头像
py3study
发布2020-01-13 00:37:52
1.8K0
发布2020-01-13 00:37:52
举报
文章被收录于专栏:python3python3

只实现了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();
        }
    }
}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-08-29 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档