zl程序教程

您现在的位置是:首页 >  后端

当前栏目

Python - 简单实现SOCKS5-dailifuwuqi

Python 实现 简单
2023-09-27 14:29:10 时间

Python版:

# -*- coding:utf-8 -*-
import os
import random
import socket
import threading
import select
import time

import psutil


class NetInfo(object):

    @staticmethod
    def get_port():
        """
        Gets the free port in the specified range
        :return: Available ports
        """
        net_cmd = "netstat -ntl |grep -v Active| grep -v Proto|awk '{print $4}'|awk -F: '{print $NF}'"
        port_list = os.popen(net_cmd).read().split("\n")
        port = random.randint(1024, 65535)
        if port not in port_list:
            return port
        else:
            NetInfo.get_port()

    @staticmethod
    def get_net_card():
        """Get the network card Ming and IP
        """
        card_list = []
        for card, values in psutil.net_if_addrs().items():
            if card == "lo":
                continue
            address = ""
            for key in values:
                if key.family == 2:
                    address = key.address
            if address == "":
                continue
            card_list.append(card + "-" + address)
        return card_list

    @staticmethod
    def get_local_ips():
        """Get all IP of the machine, not including 127.0.0.1"""
        res = [
            item[1]
            for k, v in psutil.net_if_addrs().items()
            for item in v
            if item[0] == 2
        ]
        if "127.0.0.1" in res:
            res.remove("127.0.0.1")
        return res[0]


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
        print("recv = {}".format(recv))
        CMD = ord(recv[1:2])
        ATYP = ord(recv[3:4])
        print("CMD = {}, ATYP = {}".format(CMD, ATYP))
        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__":
    IsNeedAuth = True
    Username = 'admin'
    Password = '123456'
    host, port = NetInfo.get_local_ips(), NetInfo.get_port()
    print("host = {}, port = {}, username = {}, password = {}".format(host, port, Username, Password))
    ls = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    ls.bind((host, 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();
        }
    }
}