只实现了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();
}
}
}