简单实现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(); } } }