在研究一个系统或程序时,跟踪和观察版本之间的变化是很有价值。当一个新版本发布时,如果能够轻松直观地看到它的更改,可以很容易发现一些东西,比如厂商默默修补的bug,没有声明的新功能甚至是新bug的引入。这不仅适用于单个二进制文件,而且适用于整个系统,包括整个操作系统。
这篇文章将介绍我如何使用Git和CI(Continuous Integration)来自动可视化记录系统的变化过程,以及我如何使用它来跟踪Windows每周的更新。
目标-跟踪ETW
Windows的事件跟踪可以很好地了解正在运行的计算机上发生的情况。目前,有1000多个不同的程序提供事件监测数据,并且在每周的Windows更新中定期添加,重命名和删除事件提供程序。
一个新的ETW(事件监测)提供程序出现通常表示Windows的一部分已升级或更改,并且来自提供程序的日志消息通常可以提供有关Windows内部工作原理的新见解。
我的目标是在Windows系统更新过程中安装新的ETW提供程序时,能够自动收到这些通知,并能够查看已添加,删除或更改了哪些事件提供程序。
另外,我维护了一个称为Sealighter的ETW跟踪程序,因此能够检验Sealighter在发现新的事件提供程序中起到很重要的作用。
基于Git的可视化
获取ETW提供程序的列表非常容易,我只需从以管理员权限运行的PowerShell中运行以下命令:
logman query providers > providers.txt
现在,providers.txt文件中列出了当前版本的Windows的ETW提供程序列表。下次Windows更新时,我可以再次运行命令以获取更新的列表。
为了能够跟踪记录Windows更新的更改,我使用git和GitHub,就像我以前是软件开发人员一样,也可以使用github跟踪记录代码更改。创建GitHub帐户和新的存储库后,我创建了以下脚本,并在每次Windows更新后运行脚本。脚本会生成新的git提交,提交内容包含了ETW提供程序列表的所有变化,然后我可以从命令行或Github界面进行查看:
#Get the current Windows Version
$WINDOWS_VERSION = ([System.Environment]::OSVersion.Version).ToString()
# Get the list of Providers
logman query providers > providers.txt
# Add and commit the updated version
# If nothing has changed then these will do nothing
git add providers.txt
git commit -m "Updated to $WINDOWS_VERSION"
git push
在GitHub界面中,发生更改时,我会看到类似以下内容:
要从命令行查看相同的信息,可以在文件夹内运行以下命令:
git diff HEAD~1
上述命令会得到类似的不同颜色输出:
当添加、删除或更改新的提供者时,它们将被突出显示,这样我就知道要分析哪些提供者。
自动化数据收集
如果在每次Windows更新时都手动运行脚本,这当然也可以,但是我想让这些脚本自动运行,并且当提供者内容发生更改时,它还能够通知我。
有很多方法可以实现这一点:
方案A-计划任务
如果我的计算机一直处于运行状态并设置自动更新,最简单的解决方案是在主机上运行计划任务:
# Change directory to folder with the git repo
cd C:\path\to\repo
# Write out git code into a script file
$SCRIPT = @"
`$WINDOWS_VERSION = ([System.Environment]::OSVersion.Version).ToString()
# Get the list of Providers
logman query providers > providers.txt
# Add and commit the updated version
# If nothing has changed then these will do nothing
git add providers.txt
git commit -m "Updated to `$WINDOWS_VERSION"
git push
"@
Write-Output $SCRIPT | Out-File "run.ps1"
# Create Scheduled task action
$action = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-ep bypass -f $pwd\run.ps1" -WorkingDirectory $pwd
# Create a trigger to make scheduled task every times
# Windows starts, as once windows updates it'll have to restart
$trigger = New-ScheduledTaskTrigger -AtStartup
# Now actually register the Task
Register-ScheduledTask -Action $action -Trigger $trigger -TaskName "Git-Update-Checker" -Description "Checks for windows updates"
如果使用此方法,我建议将run.ps1脚本添加到git repo,这样就不会丢失它。
方案B-使用github actions CI
另一个选择是利用GitHub Actions及其托管的CI运行程序。它们的优点是GitHub每周更新一次,但缺点是作为Windows容器,它可能会缺少常规桌面或服务器版本的Windows所具有的某些文件或功能。
Github Actions有一个名为Add&Commit的插件,它可以很容易地定义一个操作来替换我们的git脚本,这些步骤将自动在托管运行器上运行:
name: CI
on:
push:
branches: [ main ]
schedule:
- cron: '0 0 * * *' # every day at midnight
jobs:
run:
runs-on: windows-latest
steps:
# Checkout Code
- name: Checkout code
uses: actions/checkout@v2
with:
submodules: recursive
# Run command
- name: Run Script
run: logman query providers | Out-File -FilePath .\providers.txt -Encoding ascii
shell: powershell
# Set WINDOWS_VERSION environment variable
- name: Set WINDOWS_VERSION env variable
run: Echo ("WINDOWS_VERSION="+([System.Environment]::OSVersion.Version).ToString()) | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
shell: powershell
# If the script changed any files, this step will commit them and make a new tag
- name: Add new commit if needed
uses: EndBug/add-and-commit@v5
with:
add: "providers.txt --force"
message: "Updated to ${{ env.WINDOWS_VERSION }}"
tag: "${{ env.WINDOWS_VERSION }} --force"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
重要提示
GitHub管理的运行程序仅用于协助GitHub中存储的软件的持续开发和部署。GitHub actions可接受的使用策略如下:
- cryptomining;
- using our servers to disrupt, or to gain or to attempt to gain unauthorized access to, any service, device, data, account or network (other than those authorized by the GitHub Bug Bounty program)
- the provision of a stand-alone or integrated application or service offering Actions or any elements of Actions for commercial purposes;
- any activity that places a burden on our servers, where that burden is disproportionate to the benefits provided to users (for example, don’t use Actions as a content delivery network or as part of a serverless application, but a low benefit Action could be ok if it’s also low burden); or
- any other activity unrelated to the production, testing, deployment, or publication of the software project associated with the repository where GitHub Actions are used.
所以,如果你确保100%不违反第4条,你这样做是出于非商业原因,并且结果被用来帮助开发同样托管在这个存储库中的项目,我认为这种操作是在指导原则范围内的行为。
对我来说,拥有一份更新的ETW提供程序列表,对于确保Sealighter能够监测所有ETW提供程序和事件至关重要。
方案c 使用Terraform云
第三种方法是使用Terraform和Ansible等工具在云中(例如在AWS或Azure中)自动创建新的更新虚拟机,运行我们的
脚本,然后关闭并销毁它们。
我计划在以后的博客系列中讨论这个问题,因为如果你是新手,这需要一段时间来设置,而且这个博客已经太长了。
自动通知
如果使用GitHub,通知部分实际上是最简单的,因为GitHub默认情况下会在存储库上创建新标记时向您发送电子邮件。因此,只需要对脚本进行以下简单的更改,以便在更改时创建新标记:
# Get the current Windows Version
$WINDOWS_VERSION = ([System.Environment]::OSVersion.Version).ToString()
# Get the list of Providers
logman query providers > providers.txt
# Add and commit the updated version
git add providers.txt
git commit -m "Updated to $WINDOWS_VERSION"
# If we actually commited changes, also tag and then push up
# '$?' means 'was the last command successfull?'
if ($?) {
git tag $WINDOWS_VERSION
git push
git push --tags
}
然后,每当Windows更新过程更改ETW提供程序时,git将创建一个新的提交和新标记,然后通过电子邮件发送到我的Github帐户的电子邮件地址,提醒我有更改。
结果-UacScan
我创建了一个名为ETW Watcher的项目,该项目演示了如何使用托管的Github Actions运行程序记录ETW提供程序列表的每日更新。
一个最近的自动提交提醒我又多了一个新的ETW提供者:Microsoft-Antimalware-UacScan。
这听起来非常有趣,所以我使用以下配置运行Sealighter,以从该新提供程序中获取事件的示例:
{
"session_properties": {
"session_name": "Sealighter-Trace",
"output_format": "stdout"
},
"user_traces": [
{
"trace_name": "UACScan",
"provider_name": "Microsoft-Antimalware-UacScan"
}
]
}
为了测试新的提供程序,我运行了由axagarampur创建的ByeIntegrity2 UAC绕过PoC 。
此UAC实现用户账户控制绕过的原理是,通过与自动提升权限的COM对象的接口Internet Explorer Add-on Installer进行通信,该对象在自动提升权限的IEInstal.exe进程中运行。绕过命令使ieinstal运行任意二进制文件作为“设置命令”,运行的二进制程序会保留提升的特权。
运行此UAC POC,Sealighter将产生以下日志:
{
"header": {
"activity_id": "{00000000-0000-0000-0000-000000000000}",
"event_flags": 576,
"event_id": 1201,
"event_name": "",
"event_opcode": 0,
"event_version": 0,
"process_id": 7588,
"provider_name": "Microsoft-Antimalware-UacScan",
"thread_id": 7932,
"timestamp": "2020-11-24 06:20:11Z",
"trace_name": "myTrace"
},
"properties": {
"autoElevateRequest": "BOOLEAN",
"comClsid": "{BDB57FF2-79B9-4205-9447-F5FE85F37312}",
"comRequestor": "C:\\WINDOWS\\explorer.exe",
"comServerBinary": "C:\\Program Files\\Internet Explorer\\IEInstal.exe",
"exeApplicationName": "",
"exeCommandLine": "",
"exeDllParam": "",
"requestorProcessId": 0,
"uacRequestType": 1,
"uacTrustState": 0
}
}
因此,我们可以从Sealighter中看到,新的ETW Provider记录了有关COM对象,DLL和可执行文件何时创建UAC请求以及何时自动批准这些请求的信息。查看OLEView(和axagarampur的注释),我们可以确认此comClsid是易受攻击的“加载项安装程序” COM组件:
对于防御者而言,这些事件提供了一些指示,表明哪些程序正在启动权限提升的程序,以及它们正在使用哪些DLL或COM对象。
对于漏洞挖掘者而言,在寻找自动权限提升的COM对象或dll时,这些事件看起来是一个很好的信息来源。在系统上运行一段时间的跟踪可能会发现有趣的COM对象值得去逆向分析,使用Sealighter的stack_trace选项可以帮助快速找到这些对象是如何使用的,以及是否可以通过对它们的操作实现权限提升。
结论
这个博客介绍了我使用开源工具自动化分类数据以备将来研究的过程。
这些技术可以应用到任何以文本形式表示的有趣的内容,并且这些内容可能会随着时间的推移而改变。例如:
目录列表
DLL导出函数
来自HTTP端点的响应
从开源代码获取的文档
有关更多信息,请在Twitter上联系我,或查看以下Github项目:
https://github.com/pathtofile/etw_watcher/
https://github.com/pathtofile/Sealighter/
https://github.com/AzAgarampur/byeintegrity2-uac
https://gist.github.com/mattifestation/4bc43dfbd46429ec18ce60a2ea1bcf3c#file-amsi-tmf-L28