简单实现Socks5代理(Python&

  • 2020 年 1 月 13 日
  • 笔记

只实现了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'x05x02')     #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+'x00x00x01x00x00x00x00x00x00')   # 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();          }      }  }