好难QAQ
1.(填空)请分析检材1,该检材的蓝牙mac地址为 (参考格式:11:22:33:44:55:66) 分值:16
1 ([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}
类型
MAC地址
位置
WiFi MAC
a4:55:90:12:21:35
data/misc/apexdata/com.android.wifi/WifiConfigStore.xml:627
蓝牙MAC
a4:55:90:15:2e:76
data/misc/bluedroid/bt_config.bak:9
2.(填空)请分析检材1,该检材的系统Linux内核版本号为 (参考格式:1.1.1) 分值:16
1 \d{1,3}\.\d{1,3}\.\d{1,3}
3.(填空)请分析检材1,该检材中实际使用的密码管理软件的软件包包名为 (参考格式:com.forensix.cn) 分值:19
检材1-手机\storage\emulated\0\Android\data,在此路径中找一下
1 design.codeux.authpass.fdroid
4.(填空)请分析检材1,该检材中密码管理软件的主密钥为 (参考格式:Your answer is right.) 分值:16
在便签里面,检材1-手机\data\user\0\com.miui.notes\databases
password for keepass
5.(填空)请分析检材1,该检材中保存的github.com密码为 (参考格式:Abc123) 分值:19
安装Keepass
6.(填空)请分析检材1,该检材root工具的版本为 (参考格式:1.1) 分值:16
在package.list中查找magisk
7.(填空)请分析检材1,找到该手机上的Linux容器,并回答下列问题,该Linux发行版名称为 (参考格式:kali) 分值:19
8.(单选)请分析检材1容器,该系统默认桌面环境为 (参考格式:) 分值:19 A.KDE B.GNOME C.XFCE D.DDE
9.(填空)请分析检材1容器,该系统的android用户密码为 (参考格式:abc123) 分值:19
10.(填空)请分析检材1容器,浏览器下载的文件名为 (参考格式:1.txt) 分值:19
11.(填空)请分析检材1容器,陈某使用过的github代理的域名为 (参考格式:fic.forensix.cn) 分值:23
12.(填空)请分析检材1容器中助记词程序recphrase,其使用的壳类型为 (参考格式:VMP) 分值:19
13.(填空)请分析上题程序,程序运行后第2列第3行助记词为 (参考格式:salute) 分值:26
recphrase反编译后入口是reco.pyc
对这个reco.pyc进行反编译,得到字节码反汇编,然后再重构出代码
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 from matplotlib import pyplot as pltfrom matplotlib.font_manager import FontPropertiesimport stringfig, axes = plt.subplots(4 , 3 , figsize=(12 , 12 )) axes = axes.flatten() word_codes_list = [ [115 , 101 , 115 , 115 , 105 , 111 , 110 ], [102 , 101 , 118 , 101 , 114 ], [115 , 112 , 111 , 110 , 115 , 111 , 114 ], [99 , 114 , 111 , 117 , 99 , 104 ], [116 , 105 , 99 , 107 , 101 , 116 ], [116 , 119 , 105 , 115 , 116 ], [97 , 112 , 112 , 114 , 111 , 118 , 101 ], [118 , 105 , 108 , 108 , 97 , 103 , 101 ], [102 , 105 , 110 , 105 , 115 , 104 ], [115 , 113 , 117 , 97 , 114 , 101 ], [97 , 108 , 115 , 111 ], [99 , 111 , 111 , 107 ] ] for i, word_codes in enumerate (word_codes_list): ax = axes[i] ax.set_xlim(0 , len (word_codes) + 1 ) ax.set_ylim(0 , 3 ) ax.set_xticks([]) ax.set_yticks([]) word = '' .join([chr (code) for code in word_codes]) ax.text(0.5 , 1.5 , word, fontsize=24 , ha='left' , va='center' ) plt.tight_layout() plt.show()
这样创建的是一个三列四行的表格,所以第二列第三行应该是第八个,vilage
14.(填空)请分析上题程序,该组助记词对应的钱包种子前8位为 (参考格式:abc123) 分值:29
BIP39 助记词转换器
15.(填空)请分析检材1容器,钓鱼网站(phishing)的后台用户密码加密算法为 (参考格式:aes_sha1) 分值:23
16.(填空)请分析检材1容器,钓鱼网站超管用户的弱口令为 (参考格式:123456) 分值:26
17.(填空)请分析检材1容器,宝塔面板的入口为 (参考格式:/abc123) 分值:23
一般是在这里/www/server/panel/data/admin_path.pl
18.(填空)请分析检材1容器,宝塔面板运行在aarch64内核时报错的so文件为 (参考格式:a.so) 分值:29
19.(填空)请分析检材2,该检材系统中设备名称为neo4chen的系统分区的sha256值为 (参考格式:) 分值:16
1 E2219548F5A8E61F373258EB658625ADDA7BF858A83AD8D6E4213BCD8ECEB423
20.(填空)请分析检材2,上题系统中,曾被远程控制的ip为 (参考格式:1.1.1.1) 分值:16
搜TerminalServices或RemoteConnectionManager
21.(填空)请分析检材2加密系统,陈某通过物理方式保存助记词的东西名为 (参考格式:存钱罐) 分值:19
需要把计算机仿真起来
这还能登上???
22.(填空)请分析检材2加密系统,陈某保存记录完整助记词的文件的md5值为 分值:19
1 635aa992d8513105d3c27c6b9ef373f9
23.(单选)请分析检材2加密系统,陈某交代XI位为2^1,上题文件对应中文助记词不包含一下哪一项 (参考格式:) 分值:23 A.摇 B.选 C.的 D.以
1 2 3 4 5 6 7 8 lst = ["11100111101" , "11000000001" , "11111010110" , "01101010000" , "11000110110" , "00000000101" , "10001001000" , "11001111010" , "00001111000" , "00001100001" , "00000011001" , "10001011011" ] with open ("bip39_chinese_simplified.txt" , 'r' , encoding='utf-8' ) as f: lines = f.readlines() for binary in lst: print (lines[(int (binary, 2 )^1988 )-1 ].strip(), end="" )
BIP39 词表的索引规则
BIP39 标准编号 :词表中的单词编号是 1-2048 (从 1 开始)
Python 列表索引 :列表索引是 0-2047 (从 0 开始)
转换逻辑
如果 v^1988 的结果代表的是 BIP39 标准编号 (1-2048),那么:
BIP39 编号为 1 的单词 → 在列表中的索引是 0
BIP39 编号为 2048 的单词 → 在列表中的索引是 2047
因此需要 -1 来转换:lines[(v^1988)-1]
24.(填空)请分析检材2加密系统,该检材加密系统中陈某自白的录音最后修改时间为 (参考格式:2000-00-00 00:00:00) 分值:19
25.(填空)请分析检材2加密系统,陈某和李某共同出行的户外活动为 (参考格式:摄影) 分值:23
26.(填空)请分析检材2加密系统,陈某自白中的隐藏的“学习资料”所在服务器ip地址为 分值:26
剪映虽然没登录VIP但是好像可以直接用声音分离功能
python也可以,就是代码些许复杂,这里就不放出来了,不如直接剪映
27.(填空)请分析检材2加密系统,存放欠条的加密容器文件名为 (参考格式:蜂蜜锅底) 分值:23
28.(填空)请分析检材2加密系统,该容器欠条中赵某欠陈某多少虚拟币 (参考格式:0.524ETH) 分值:26
密码手机号在初赛里
3170010703,13170010703,一个普通分区,一个隐藏分区
29.(填空)请分析检材2加密系统,该检材中ubuntu光盘文件的系统内核版本号为 (参考格式:6.6.6) 分值:19
30.(单选)请分析检材2Linux系统,该系统的当前状态为 分值:23 A.Poweroff(S5) B.Sleep(S2) C.Hibernate(S4) D.Poweron(G0)
找到system.journal
1 journalctl --file system.journal --lines 10
31.(填空)请分析检材2Linux系统,该系统使用了什么阵列 (参考格式:zfs1) 分值:19
xw直接看到
32.(填空)请分析检材2Linux系统,系统自带记事本软件中记录的密码的未知位数有几位 (参考格式:1) 分值:23
Kali默认的应该是mousepad
chrome password : chewhaoN@%d%d%d%d
33.(填空)请分析检材2Linux系统,系统自带记事本内容缓存在重组后逻辑分区中的起始偏移地址为 (参考格式:0x0123456789) 分值:26
34.(填空)请分析检材2Linux系统,chrome浏览器插件的保护密码为 (参考格式:a@1) 分值:26
直接搜/home/haobei/.config/google-chrome/Default目录下的key字段,找到疑似是密文的部分
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 const CryptoJS = require ("crypto-js" );const argon2 = require ("argon2" );const targetHash = "$argon2id$v=19$m=16384,t=1,p=1$k6EZEDdQYyn+/0GlJtZGpg$hicAuwJorE73Moj+Po2Txda8hyoPPGYa" ;(async () => { console .log ("start" ); for (var i=0 ;i<10000 ;i++){ var password = "chewhaoN@" +String (i).padStart (4 , '0' ); try { var decryptedWordArray = CryptoJS .AES .decrypt ("U2FsdGVkX18Tb9IA8UF4TbpMQjOs4IqZBTIkldDlgn9vw1gIF9ltOirI/lf1SCGh9hAskbnb7cIsoJL6mNii7pQ1SDSt9R7vzF3Y+/d/fPtKXHMisjbQK/U6t+3wREAuoKQ4yZ24iuw+KZ6CW9bl6ULp3nVx0B8QpueW95sw0KOtmOMpmD19nO6gkFvMohcB" , password); var decryptedHex = decryptedWordArray.toString (CryptoJS .enc .Hex ); if (decryptedHex){ const isValid = await argon2.verify (targetHash, decryptedHex); if (isValid){ console .log (`\n解密成功,密码: ${password} ` ); process.exit (0 ); } } } catch (err) { } } console .log ("未找到" ); })();
35.(填空)请分析检材2Linux系统,chrome浏览器插件存放的令牌的名称为 (参考格式:abc) 分值:29
还是刚才000003.log这个文件
1 2 3 4 5 6 7 8 9 { "account" : "chenhaoren" , "encrypted" : true , "hash" : "58384e73-5c98-433d-87bc-165f7f0ddad6" , "index" : 1 , "secret" : "U2FsdGVkX1+eacsEnU0gCAZ1MQR8aoQKWZIH8oRlWkkdnsm0SrMfmXK98hBGaAqr" , "type" : "totp" }
36.(填空)请分析检材2Linux系统,该检材Linux系统浏览器插件存放的令牌在2022-05-12 00:54:10时的令牌为 (参考格式:123456) 分值:29
先解密TOTP的秘钥
1 2 3 const masterKeyHex = CryptoJS .AES .decrypt (encryptedMasterKey, password).toString (CryptoJS .enc .Hex );const totpSecret = CryptoJS .AES .decrypt (encryptedTotpSecret, masterKeyHex).toString (CryptoJS .enc .Utf8 );console .log ("TOTP密钥:" , totpSecret);
然后通过覆盖Data.now()模拟历史时间
1 2 3 4 5 const originalDateNow = Date .now ;Date .now = () => timestamp * 1000 ;const token = authenticator.generate (totpSecret);Date .now = originalDateNow;console .log (`token: ${token} ` );
注意先npm install crypto-js otplib
34-36题脚本解题
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 const CryptoJS = require ("crypto-js" );const argon2 = require ("argon2" );const { authenticator } = require ("otplib" );const encryptedMasterKey = "U2FsdGVkX18Tb9IA8UF4TbpMQjOs4IqZBTIkldDlgn9vw1gIF9ltOirI/lf1SCGh9hAskbnb7cIsoJL6mNii7pQ1SDSt9R7vzF3Y+/d/fPtKXHMisjbQK/U6t+3wREAuoKQ4yZ24iuw+KZ6CW9bl6ULp3nVx0B8QpueW95sw0KOtmOMpmD19nO6gkFvMohcB" ;const argon2Hash = "$argon2id$v=19$m=16384,t=1,p=1$k6EZEDdQYyn+/0GlJtZGpg$hicAuwJorE73Moj+Po2Txda8hyoPPGYa" ;const encryptedTotpSecret = "U2FsdGVkX1+eacsEnU0gCAZ1MQR8aoQKWZIH8oRlWkkdnsm0SrMfmXK98hBGaAqr" ;const targetTime = "2022-05-12 00:54:10" ;(async () => { let password = null ; for (let i = 0 ; i < 10000 ; i++) { const pwd = "chewhaoN@" + String (i).padStart (4 , '0' ); try { const decrypted = CryptoJS .AES .decrypt (encryptedMasterKey, pwd); const hex = decrypted.toString (CryptoJS .enc .Hex ); if (hex && await argon2.verify (argon2Hash, hex)) { password = pwd; console .log ("密码:" , password); break ; } } catch (e) {} } if (!password) { console .log ("失败" ); return ; } const masterKeyHex = CryptoJS .AES .decrypt (encryptedMasterKey, password).toString (CryptoJS .enc .Hex ); const totpSecret = CryptoJS .AES .decrypt (encryptedTotpSecret, masterKeyHex).toString (CryptoJS .enc .Utf8 ); console .log ("TOTP密钥:" , totpSecret); console .log ("\n步骤3: 计算历史令牌..." ); const timestamp = Math .floor (new Date (targetTime).getTime () / 1000 ); const originalDateNow = Date .now ; Date .now = () => timestamp * 1000 ; const token = authenticator.generate (totpSecret); Date .now = originalDateNow; console .log (`token: ${token} ` ); })();
37.(填空)请分析检材3,该操作系统版本号为 (参考格式:22.01.1) 分值:16
38.(填空)请分析检材3,该主机名为 (参考格式:app-server-2025) 分值:16
39.(填空)请分析检材3,该ens33网卡IP地址为 (参考格式:192.168.1.1) 分值:19
40.(单选)请分析检材3,操作系统登录使用了第三方身份验证,该技术为 分值:19 A.pam_pwdfile B.pam_ldap C.Google Auth D.pam_krb5
搜一下,/etc目录里面的这个是
41.(单选)请分析检材3,该身份验证的加密算法为? 分值:23 A.Bcrypt B.MD5 C.DES D.AES
42.(填空)请分析检材3,该保存king用户密码的文件名为? (参考格式:shadow) 分值:23
43.(填空)请分析检材3,尝试爆破king用户,其密码为(king字母加3个数字)? (参考格式:king123) 分值:23
1 2 3 4 5 6 7 import bcrypthash_str = "$2a$10$V/8GUI5aTNSnbFodPjP7Zu6vCFSXmvdd9oKHGtWv/vbT3Q4LLTCcW" for num in range (1000 ): password = f"king{num:03d} " if bcrypt.checkpw(password.encode(), hash_str.encode()): print (f"密码: {password} " ) break
44.(填空)请分析检材3,该WEB-API配置的 MySQL 数据库服务器地址为 (参考格式:192.168.1.1) 分值:23
45.(填空)请分析检材3,其中用于 WEB-API 测试的流量包文件名为 (参考格式:abc.txt) 分值:19
46.(填空)请分析检材3流量包,统计其中 admin 用户成功登录的次数为 (参考格式:1) 分值:23
过滤code == 200
点点发现前三个有登录成功的返回
47.(填空)请分析检材3流量包,找出用户最后一次查看的商品型号为 (参考格式:kk-123) 分值:23
继续往下翻就有
48.(填空)请分析检材3WEB-API,该容器镜像ID为(前六位) (参考格式:abc123) 分值:19
找到三个config.v2.json
vscode看一下,d4cb开头的那个文件夹是web_api的docker镜像文件
49.(单选)请分析检材3WEB-API,该容器的核心服务编程语言为 分值:19 A.JAVA B.PHP C.NODEJS D.C#
启动命令中有exec node index.js
50.(填空)请分析检材3WEB-API,该容器所用域名为 (参考格式:qq.com) 分值:23
根据前面test.pcap中的访问IP进行搜索
51.(填空)请分析检材3WEB-API,该容器日志文件名(access_log)为 (参考格式:abc.txt) 分值:23
有提示access_log
52.(填空)请分析检材3WEB-API,该容器的FLAG2的接口URL为 (参考格式:/aaa/bbb/ccc) 分值:23
直接搜flag2
53.(填空)请分析检材3WEB-API,该容器的服务运行状态的接口URL为 (参考格式:/aaa/bbb) 分值:23
54.(单选)请分析检材3WEB-API,该容器中访问FLAG2接口后,会提示需要在什么调试器下运行 分值:23 A.GDB B.Frida C.rr D.Treace
55.(填空)请分析检材3WEB-API,该容器的admin用户的登录密码为 (参考格式:abc123) 分值:23
前面pcap已经有了
56.(填空)请分析检材3WEB-API,该容器的数据库内容被SO所加密,该SO文件名为 (参考格式:abc.txt) 分值:19
直接只在这个文件夹里面搜索
57.(单选)请继续分析上题SO文件,该文件的编译器类型为 分值:19 A.VC B.DELPHI C.GCC D.VB
58.(单选)请继续分析上题SO文件,在SO文件的encrypt函数中,该加密算法为 分值:23 A.DES B.AES-128 C.AES-192 D.AES-256
很明显是256
59.(填空)请继续分析上题SO文件,尝试分析getAeskey函数,该KEY值为 (参考格式:abasdcdefghijgasdsdfsdfqwesazada) 分值:29
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 136 137 """ 恢复 getAeskey() 函数生成的AES密钥 基于完整的C伪代码还原 """ def recover_aes_key (xmmword_2050 ): """ 根据反编译的 getAeskey() 函数逻辑恢复AES密钥 参数: xmmword_2050: 16字节的初始值 (bytes) 返回: (key1, key2): 两个16字节的密钥 """ int64_constant_values = [ 0xF00000002 , 0x1C00000000 , 0x900000005 , 0xC0000001F , 0x300000014 , 0x1000000019 , 0xE00000008 , 0x1600000001 , 0x60000001B , 0x120000000D , 0x40000001E , 0xA00000018 , 0xB0000001A , 0x110000001D , 0x1700000015 , ] v27_val = 19 mem_region_v11_parts = [0 ] * 9 constants_as_dwords = [] for val64 in int64_constant_values: constants_as_dwords.append(val64 & 0xFFFFFFFF ) constants_as_dwords.append((val64 >> 32 ) & 0xFFFFFFFF ) constants_as_dwords.append(v27_val & 0xFFFFFFFF ) full_dword_view = mem_region_v11_parts + constants_as_dwords v9_data = bytearray (96 ) if not isinstance (xmmword_2050, bytes ) or len (xmmword_2050) != 16 : raise ValueError("xmmword_2050 必须是16字节的bytes对象" ) v9_data[0 :16 ] = xmmword_2050 v9_data[16 :32 ] = xmmword_2050 v0_current_byte = 35 for v1_loop_idx in range (32 ): v9_data[32 + v1_loop_idx] = v0_current_byte & 0xFF v1_after_increment = v1_loop_idx + 1 if v1_after_increment == 32 : break idx_for_v11_access = v1_after_increment + 8 v9_lookup_offset = full_dword_view[idx_for_v11_access] if not (0 <= v9_lookup_offset < len (v9_data)): raise IndexError(f"v9_lookup_offset {v9_lookup_offset} 越界" ) v0_current_byte = v9_data[v9_lookup_offset] v28_py_indices = [-1 ] * 32 v2_counter = 0 current_idx_for_v28_array = 7 while True : if not (0 <= current_idx_for_v28_array < len (v28_py_indices)): raise IndexError(f"current_idx_for_v28_array {current_idx_for_v28_array} 越界" ) v28_py_indices[current_idx_for_v28_array] = v2_counter v2_counter += 1 if v2_counter == 32 : break idx_for_v11_access_v28loop = v2_counter + 8 current_idx_for_v28_array = full_dword_view[idx_for_v11_access_v28loop] for j_loop_idx in range (32 ): permutation_source_offset = v28_py_indices[j_loop_idx] if not (0 <= permutation_source_offset < 32 ): raise IndexError(f"置换源偏移 {permutation_source_offset} 越界" ) byte_to_permute = v9_data[32 + permutation_source_offset] v9_data[64 + j_loop_idx] = byte_to_permute v10_buffer = bytearray (32 ) for k_loop_idx in range (32 ): byte_from_permuted = v9_data[64 + k_loop_idx] v10_buffer[k_loop_idx] = byte_from_permuted ^ 0x44 v6_loaded_16_bytes = v10_buffer[0 :16 ] v7_loaded_16_bytes_buffer = bytearray (16 ) for i in range (4 ): dword_val = full_dword_view[i] v7_loaded_16_bytes_buffer[i*4 + 0 ] = (dword_val >> 0 ) & 0xFF v7_loaded_16_bytes_buffer[i*4 + 1 ] = (dword_val >> 8 ) & 0xFF v7_loaded_16_bytes_buffer[i*4 + 2 ] = (dword_val >> 16 ) & 0xFF v7_loaded_16_bytes_buffer[i*4 + 3 ] = (dword_val >> 24 ) & 0xFF key1 = bytes (v6_loaded_16_bytes) key2 = bytes (v7_loaded_16_bytes_buffer) return key1, key2 def main (): xmmword_input = input ("xmmword_2050: " ).strip() try : if len (xmmword_input) == 32 and all (c in '0123456789abcdefABCDEF' for c in xmmword_input): big_int = int (xmmword_input, 16 ) xmmword_2050 = big_int.to_bytes(16 , 'little' ) else : big_int = int (xmmword_input) xmmword_2050 = big_int.to_bytes(16 , 'little' ) if len (xmmword_2050) != 16 : print (f"错误: 需要16字节,但得到了 {len (xmmword_2050)} 字节" ) return print (f"\n使用的 xmmword_2050 (hex): {xmmword_2050.hex ()} " ) print (f"ASCII表示: {xmmword_2050} " ) key1, key2 = recover_aes_key(xmmword_2050) print ("\n" + "=" * 60 ) print ("恢复的AES密钥:" ) print ("=" * 60 ) print (f"密钥1 (aeskey_0): {key1.hex ()} " ) print (f"密钥1 ASCII: {key1.decode('ascii' , errors='replace' )} " ) print () print (f"密钥2 (xmmword_4190): {key2.hex ()} " ) print () print (f"完整密钥 (32字节): {(key1 + key2).hex ()} " ) except ValueError as e: print (f"错误: 输入格式无效 - {e} " ) except Exception as e: print (f"错误: {e} " ) if __name__ == "__main__" : main()
1 2 3 4 5 6 7 8 9 ============================================================ 恢复的AES密钥: ============================================================ 密钥1 (aeskey_0): 7a68616f686f6e677a68616f686f6e67 密钥1 ASCII: zhaohongzhaohong 密钥2 (xmmword_4190): 00000000000000000000000000000000 完整密钥 (32字节): 7a68616f686f6e677a68616f686f6e6700000000000000000000000000000000
1 zhaohongzhaohongzhaohongzhaohong
60.(填空)请继续分析上题SO文件,尝试分析get_flag1函数,该返回值为 (参考格式:abc123) 分值:26
61.(填空)请继续分析上题SO文件,尝试分析get_flag2函数,该返回值为 (参考格式:qiang) 分值:29
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 import structmem = bytearray (100 ) v8_offset = 0 mem[v8_offset:v8_offset+8 ] = struct.pack('<Q' , 0x484F5C1540464B41 ) v9_offset = 8 mem[v9_offset:v9_offset+3 ] = b'I@Z' mem[37 :45 ] = struct.pack('<Q' , 0x600000000 ) mem[45 :53 ] = struct.pack('<Q' , 0xA00000002 ) mem[53 :61 ] = struct.pack('<Q' , 0x700000004 ) mem[61 :69 ] = struct.pack('<Q' , 0x100000009 ) mem[69 :77 ] = struct.pack('<Q' , 0x500000008 ) print ("Memory layout:" )print (f"v8 (0-7): {mem[0 :8 ].hex ()} = {mem[0 :8 ]} " )print (f"v9 (8-10): {mem[8 :11 ].hex ()} = {mem[8 :11 ]} " )print (f"v10 (37-44): {mem[37 :45 ].hex ()} " )print (f"v11 (45-52): {mem[45 :53 ].hex ()} " )print (f"v12 (53-60): {mem[53 :61 ].hex ()} " )print (f"v13 (61-68): {mem[61 :69 ].hex ()} " )print (f"v14 (69-76): {mem[69 :77 ].hex ()} " )sequence = [0 ] * 12 sequence[0 ] = 64 print ("\n=== Loop 1 ===" )for v1 in range (11 ): v9_index = 2 * v1 + 12 byte_offset_in_v9 = v9_index * 2 addr = v9_offset + byte_offset_in_v9 + 1 print (f" v1={v1} : v9[{v9_index} ] at byte offset {byte_offset_in_v9} , +1 = addr {addr} " ) if addr + 4 <= len (mem): offset_val = struct.unpack('<i' , mem[addr:addr+4 ])[0 ] print (f" Read int at {addr} : {offset_val} " ) char_addr = v8_offset + offset_val if 0 <= char_addr < len (mem): char_val = mem[char_addr] sequence[v1 + 1 ] = char_val print (f" v8[{offset_val} ] = '{chr (char_val) if 32 <= char_val < 127 else f'\\x{char_val:02x} ' } '" ) print (f"\nSequence after loop 1: {['' .join([chr (b) if 32 <= b < 127 else f'\\x{b:02x} ' for b in sequence])]} " )print (f"Sequence bytes: {[f'{b:02x} ' for b in sequence]} " )v15 = [0 ] * 14 print ("\n=== Loop 2 ===" )for v3 in range (11 ): v9_index = 2 * v3 + 12 byte_offset_in_v9 = v9_index * 2 addr = v9_offset + byte_offset_in_v9 + 1 if addr + 4 <= len (mem): j = struct.unpack('<i' , mem[addr:addr+4 ])[0 ] print (f" v3={v3} : j={j} " ) if 0 <= j < 14 : v15[j] = v3 print (f"\nv15 mapping: {v15} " )reordered = [0 ] * 11 print ("\n=== Loop 3 ===" )for k in range (11 ): source_idx = v15[k] + 1 reordered[k] = sequence[source_idx] print (f" k={k} : v15[{k} ]={v15[k]} , source_idx={source_idx} , char='{chr (sequence[source_idx]) if 32 <= sequence[source_idx] < 127 else f'\\x{sequence[source_idx]:02x} ' } '" ) print (f"\nReordered: {'' .join([chr (b) if 32 <= b < 127 else f'\\x{b:02x} ' for b in reordered])} " )result = bytearray () print ("\n=== Loop 4 (XOR 0x27) ===" )for m in range (11 ): xored = reordered[m] ^ 0x27 result.append(xored) print (f" m={m} : {reordered[m]:02x} ^ 27 = {xored:02x} ('{chr (xored) if 32 <= xored < 127 else f'\\x{xored:02x} ' } ')" ) print (f"\n{'=' *50 } " )print (f"FINAL FLAG2: {result.decode('ascii' , errors='replace' )} " )print (f"{'=' *50 } " )
1 FINAL FLAG2: flaf2{hong}
62.(填空)请继续分析上题SO文件,尝试分析decrypt函数,该密文dnJXwBR4qc+1Y4WB6ZxR0A==的明文为 (参考格式:abc123) 分值:29
63.(填空)请分析检材3数据库,在 products 表中,统计商品型号的种类数量(例如以 ZK、CW 等为前缀的型号) (参考格式:1) 分值:26
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 import refrom Crypto.Cipher import AESfrom Crypto.Util.Padding import unpadimport base64with open ('products.ibd' , 'rb' ) as f: data = f.read() all_enc = re.findall(rb'([A-Za-z0-9+/]{16,}==)' , data) def decrypt (enc_b64, key, iv ): try : cipher = AES.new(key, AES.MODE_CBC, iv) decrypted = unpad(cipher.decrypt(base64.b64decode(enc_b64)), 16 ) return decrypted.decode('utf-8' ) except : return None pattern = re.compile (r'([a-z]+)-\d+' , re.IGNORECASE) prefixes = set () for i in all_enc: decrypted = decrypt(i.decode('utf-8' ), b'zhaohongzhaohongzhaohongzhaohong' , b'0123456789012345' ) if decrypted: match = pattern.search(decrypted) if match : prefixes.add(match .group(1 )) print (f"种类: {sorted (prefixes)} " )print (f"共 {len (prefixes)} 种" )
64.(填空)请分析检材3数据库,在 products 表中,统计型号为 “ZK” 且颜色为灰色的商品的数量 (参考格式:10) 分值:26
上一道题智能分析到一部分内容,全部的还是得把数据库启动起来看
在本地启动了一个mysql docker用来获取数据
1 2 3 4 5 6 7 8 9 10 docker run -d \ --name mysql-forensic \ -v /mnt/ssd/forensic/sql:/var/lib/mysql \ 这里直接把数据库目录导出来,然后启动docker的时候直接挂载成卷,这样docker能直接读取,就不用复制了 -e MYSQL_ALLOW_EMPTY_PASSWORD=yes \ -p 3307:3306 \ mysql:8.0 \ --skip-grant-tables docker exec mysql-forensic mysqldump product_db > product_db_backup.sql
然后写个脚本吧.sql转换成.xlsx
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 import reimport pandas as pdfrom pathlib import Pathdef parse_sql_inserts (sql_file ): with open (sql_file, 'r' , encoding='utf-8' ) as f: content = f.read() create_table_pattern = r'CREATE TABLE `(\w+)` \((.*?)\) ENGINE=' tables_structure = {} for match in re.finditer(create_table_pattern, content, re.DOTALL): table_name = match .group(1 ) table_def = match .group(2 ) column_pattern = r'`(\w+)`\s+(?:int|varchar|text|timestamp)' columns = re.findall(column_pattern, table_def) tables_structure[table_name] = columns insert_pattern = r'INSERT INTO `(\w+)` VALUES (.*?);' tables_data = {table: [] for table in tables_structure.keys()} for match in re.finditer(insert_pattern, content, re.DOTALL): table_name = match .group(1 ) values_str = match .group(2 ) row_pattern = r'\(([^)]+)\)' rows = re.findall(row_pattern, values_str) for row in rows: values = [] current_value = '' in_quotes = False for char in row + ',' : if char == "'" and (not current_value or current_value[-1 ] != '\\' ): in_quotes = not in_quotes current_value += char elif char == ',' and not in_quotes: value = current_value.strip().strip("'" ) if value == 'NULL' : value = None values.append(value) current_value = '' else : current_value += char if table_name in tables_data: tables_data[table_name].append(values) return tables_structure, tables_data def save_to_excel (tables_structure, tables_data, output_file ): with pd.ExcelWriter(output_file, engine='openpyxl' ) as writer: for table_name, columns in tables_structure.items(): if table_name in tables_data and tables_data[table_name]: df = pd.DataFrame(tables_data[table_name], columns=columns) sheet_name = table_name[:31 ] df.to_excel(writer, sheet_name=sheet_name, index=False ) def main (): sql_files = list (Path('.' ).glob('*.sql' )) if not sql_files: return sql_file = sql_files[0 ] print (f"正在处理SQL文件: {sql_file} " ) output_file = sql_file.stem + '.xlsx' try : tables_structure, tables_data = parse_sql_inserts(sql_file) save_to_excel(tables_structure, tables_data, output_file) print (f"Excel文件已保存为: {output_file} " ) except Exception as e: import traceback traceback.print_exc() if __name__ == '__main__' : main()
然后再写一个解密脚本
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 import pandas as pdfrom pathlib import Pathfrom Crypto.Cipher import AESfrom Crypto.Util.Padding import unpadimport base64KEY = b'zhaohongzhaohongzhaohongzhaohong' IV = b'0123456789012345' def decrypt_aes_cbc (encrypted_data ): if not encrypted_data or pd.isna(encrypted_data): return encrypted_data try : encrypted_bytes = base64.b64decode(encrypted_data) cipher = AES.new(KEY, AES.MODE_CBC, IV) decrypted_bytes = unpad(cipher.decrypt(encrypted_bytes), AES.block_size) return decrypted_bytes.decode('utf-8' ) except Exception as e: print (f"解密失败 '{encrypted_data} ': {e} " ) return f"[解密失败: {encrypted_data} ]" def main (): excel_files = list (Path('.' ).glob('*.xlsx' )) if not excel_files: print ("当前目录下无xlsx文件" ) return excel_file = excel_files[0 ] try : df = pd.read_excel(excel_file, sheet_name=0 ) print (f"原始数据形状: {df.shape} " ) print (f"列名: {df.columns.tolist()} \n" ) decrypt_columns = df.columns[1 :7 ] decrypt_rows = range (0 , min (335 , len (df))) decrypted_count = 0 for row_idx in decrypt_rows: for col in decrypt_columns: original_value = df.at[row_idx, col] decrypted_value = decrypt_aes_cbc(original_value) if original_value != decrypted_value: df.at[row_idx, col] = decrypted_value decrypted_count += 1 output_file = excel_file.stem + '_decrypted.xlsx' df.to_excel(output_file, index=False , engine='openpyxl' ) print (f"解密后的文件已保存为: {output_file} " ) except Exception as e: print (f"错误: {e} " ) import traceback traceback.print_exc() if __name__ == '__main__' : main()
65.(填空)请分析检材3数据库,在 products 表中,统计型号为 “ZK” 的总销售额(金额只保留整数部分,不进行四舍五入) (参考格式:10000) 分值:26
66.(填空)请分析检材4,该检材的系统版本号为 (参考格式:1.1.1) 分值:16
67.(填空)请分析检材4,该检材的lan口ip为 分值:19
搜ipaddr
仿真后:
68.(填空)请分析检材4,该检材Overlayfs分区的大小为多少KB (参考格式:123) 分值:23
这个题应该是必须要仿真,df命令是实时计算出来的
先安装qemu
1 sudo apt install qemu-system-x86 qemu-system-arm qemu-utils
把E01转换成RAW
1 ewfexport -t raw -u 检材4-路由器.E01
1 2 3 4 5 6 7 8 9 10 qemu-system-aarch64 \ -m 512M \ -cpu cortex-a57 \ -M virt \ -bios /usr/share/qemu-efi-aarch64/QEMU_EFI.fd \ -drive file=raw.raw,format=raw,snapshot=on,if =none,id =hd0 \ 注意这里的raw.raw,改成刚才导出来的raw文件 -device virtio-blk-device,drive=hd0 \ -netdev user,id =net0,hostfwd=tcp::8080-:80,hostfwd=tcp::2222-:22 \ -device virtio-net-device,netdev=net0 \ -nographic
选第一个,进来即可
69.(填空)请分析检材4,该检材中VPN网络私钥为 (参考格式:Abc@123) 分值:23
1 SLkCLyRhrkWIFgJWfEd0B7s99FYWJf9PUV+scj3Vw3U=
70.(填空)请分析检材4,嫌疑人交代其开发了一款专门用于收集其售出摄像头信息的服务程序。请问该摄像头信息收集服务程序编译器版本为? (参考格式:1.1.1) 分值:23
前面搜openwrt搜出来了gcc
或者看仿真后把程序拿出来(仿真取出文件方法在下一题)
71.(填空)请分析检材4,该摄像头信息收集程序支持的运行参数(命令行参数)数量为多少 (参考格式:1) 分值:26
需要从qemu中把这个程序弄出来,这里采用共享文件夹方法
先使用halt把qemu关机
然后使用如下参数的启动方式:start_qemu.sh
1 2 3 4 5 6 7 8 9 10 11 qemu-system-aarch64 \ -m 512M \ -cpu cortex-a57 \ -M virt \ -bios /usr/share/qemu-efi-aarch64/QEMU_EFI.fd \ -drive file=raw.raw,format=raw,snapshot=on,if =none,id =hd0 \ -device virtio-blk-device,drive=hd0 \ -netdev user,id =net0,hostfwd=tcp::8080-:80,hostfwd=tcp::2222-:22 \ -device virtio-net-device,netdev=net0 \ -virtfs local ,path=./qemu_share,mount_tag=host0,security_model=none,id =host0 \ 注意这里的qemu_share文件夹,这个是宿主机的共享文件夹,需要先创建 -nographic
然后,在/mnt创建一个文件夹/mnt/host
再挂载
1 mount -t 9p -o trans=virtio,version=9p2000.L,msize=262144 host0 /mnt/host
然后cp ~/password_collector /mnt/host
这样就有了
两个参数
72.(多选)请分析检材4,该摄像头信息收集程序使用了什么算法进行加密 分值:23 A.MD5 B.AES C.BASE64 D.DES
main函数里有这两个
73.(填空)请分析检材4,该摄像头信息收集程序所使用的数据库文件名为 (参考格式:abc.txt) 分值:23
74.(多选)请分析检材4,该摄像头信息收集程序收集了以下哪些摄像头信息? 分值:26 A.IP 地址 B.摄像头密码 C.备注信息 D.电话号码
这题没有collected.txt文件,被删除了,且被重新填充了,没找到怎么做
75.(填空)请分析检材5,该检材的包名为 (参考格式:aaa.bbb.ccc) 分值:19
76.(填空)请分析检材5,该检材的签名证书 MD5 值为 (参考格式:202cb962ac59075b964b07152d234b70) 分值:19
1 7B1963B70FBAC57A50836E9A044D0029
77.(多选)请分析检材5,在尝试抓包登录 APP 时,登录请求中提交的参数包括:(请使用比武U盘中提供的智能家居账号密码进行登录抓包) 分值:23 A.devicename B.password C.id D.flag
78.(填空)请分析检材5,通过抓包分析登录请求,获取到的 flag 参数的值为 (参考格式:abc123asd56) 分值:23
1 2 3 4 5 6 7 8 9 Java .perform (function ( ) { let c = Java .use ("e1.c" ) c["a" ].implementation = function (str ) { console .log (`c.a is called: ${str} ` ) let result = this ["a" ](str) console .log (`c.a result: ${result} ` ) return result } })
前十位
79.(填空)请分析检材5,该 APK 登录请求中携带了一个远程调证 ID,分析该请求并提取该 ID,统计其长度为(请提取该 ID 并在比武平台中进行调证,准备进入下一阶段分析,可参考比武 U 盘中的手册) (参考格式:1) 分值:23
80.(填空)请分析检材5,在登录成功后,应用会跳转至 “欢迎使用 forensix” 界面。该界面对应的 Activity 类的完整类名为 (参考格式:com.bb.cc.ee.ff) 分值:26
1 2 3 4 5 6 7 8 9 10 11 12 Java .perform (function ( ) { globalThis.ga = function ( ) { Java .choose ("android.app.Activity" , { onMatch : function (a ) { if (a.mResumed && a.mResumed .value ) { console .log (a.getClass ().getName ()); } }, onComplete : function ( ) {} }); }; });
1 com.forensix.cam.activity.c75e3a8b2d
81.(填空)请分析检材5,分析上述 Activity 类后,发现其内部定义的 TAG 常量值为: (参考格式:999) 分值:26
找到com.forensix.cam.activity.c75e3a8b2d
82.(填空)请结合互联网分析APP调证检材,该检材系统版本号为(完成调证后,可参考比武 U 盘中的手册,在云实验室中继续完成取证任务) (参考格式:1.1) 分值:19
无检材
83.(填空)请结合互联网分析APP调证检材,该检材系统内FLAG值为(完成调证后,可参考比武 U 盘中的手册,在云实验室中继续完成取证任务) (参考格式:123456) 分值:23
无检材
84.(多选)请综合分析,陈某进行了那些操作 分值:23 A.VC加密Linux系统 B.VC加密Windows系统 C.VC加密文件 D.VC加密系统容器
VC加密了Windows 分区3,加密文件为我的手机号
85.(单选)请综合分析,陈某没有使用过以下那种方式安装数据库 分值:23 A.编译安装 B.包管理器安装 C.容器安装 D.单文件
UUID镜像是Debian,通过apt管理,docker有一个mysql的容器,路由器的数据库是文件
86.(多选)请综合分析,陈某使用过以下那些系统 分值:23 A.Windows B.MacOS C.Debian D.CentOS E.Fedora
87.(单选)请综合分析,以下说法正确的是 1.陈某将正确的助记词藏在了Linux中 2.陈某将正确的助记词藏在了windows中 3.陈某电子数据中保留了孙某的欠条 4.陈某电子数据中保留了王某的欠条 5.陈某使用JAVA搭建后台接口 6.陈某和“香格里拉大酒店”有关 分值:26 A.1245 B.2356 C.146 D.246 E.1235
正确的助记词应该是那个图片的隐写,应该是在Windows中
欠条在前面的我的手机号加密文件中有,王某
后台是用Node搭建的
香格里拉大酒店在初赛中有
88.(单选)请综合分析,陈某现有电子数据没有以下那个Linux内核版本 分值:29 A.4.14-arm B.6.6-arm C.4.15-x64 D.6.8-x64
Android 手机的 Linux 内核版本为 4.14-arm.
Ubuntu 服务器的 Linux 内核版本为 6.8-x64.
OpenWRT 的 Linux 内核版本为 6.6-arm.
89.(填空)请综合分析,陈某做为壁纸的邪影芳灵原图的sm3值为 分值:19
1 2 3 4 5 6 7 8 9 python3 -c " from gmssl import sm3 with open('tf11willow1.jpg', 'rb') as f: data = f.read() sm3_hash = sm3.sm3_hash(list(data)) print(sm3_hash) " )
1 0300a48e6acefef6ebc6ff64b957b42880febb66b5c807c7e3d7d3c3ccad2661
90.(填空)请结合分析,陈某的真实GitHub密码为 (参考格式:Abc123) 分值:19
这个大小跟最新的那个不一样