当前位置: 首页 > article >正文

2026盘古石取证初赛(APK取证)

APK取证1.分析方俊朗phone.E01检材筛选优质客户应用将用户查询记录存储在一个加密的本地数据库中。请问该加密数据库的文件名是什么[答案格式12_abc.db]题目说了这边是筛选优质客户其实和手机取证最后一题一样的先打开方俊朗的app列表看看一看就是这一个软件我们可以看到包名为com.example.predictor根据这个包名我们去/data/data目录下进行搜索即可在/data/data下直接根据包名即可搜索到文件信息而在/data/app下根据包名搜索即可得到对应apk这对做APK取证很重要我们到这个目录之下题目问加密的本地数据库那肯定是去databases里边进行查找了定位到数据库就一个数据库文件点一下发现确实加密的所以文件名就是chat_history.db当然也可以去apk里边查找只是不太好找更适合作为验证项验证答案2.分析方俊朗phone.E01检材该应用使用了哪种密钥派生算法来生成数据库加密密钥请写出完整的算法标识名称。[答案格式DFBDSDFGG123]问我们这个密钥的派生算法了那自然需要来看看配置文件并分析一下这一个apk文件了先看看配置文件可以看到说是PBKDF2加密但这边只给了一个密钥版本不是密钥派生方法所以我们还是应该去apk查看像之前说的我们可以在/data/app下根据包名搜索即可得到对应apk提取出来放到雷电看看安装大概界面长这样子这边可以进行仿真查看发现有三条记录但是这三条记录意义不大因此这边我就不介绍如何仿真的手机apk了后边有需要再讲我们还是进jadx看看发现被加壳了雷电进行脱壳后打开真是层层加壳啊搜索PBKDF2后我们在0x76388f130000_0x658c.dex找到了关键KeyDeriver在这边我们看到了整个主密钥的派生方法获取三个盐值组合种子然后创建PBKDF2密钥当然对于本题来说核心的还是这一句SecretKeyFactory factory SecretKeyFactory.getInstance(PBKDF2WithHmacSHA256);这是获取PBKDF2密钥工厂的实例所以完整的算法标识名称是PBKDF2WithHmacSHA2563.分析方俊朗phone.E01检材该应用的密钥派生过程中使用了多少次迭代运算[答案格式345678]在上一题的配置文件/data/data/com.example.predictor/shared_prefs/app_config.xml可以看到这边写的很明确是进行了10000次迭代当然apk里也自然有对应的记录存在4.分析方俊朗phone.E01检材该应用检测动态调试工具时探测了哪个本地端口号[答案格式64321]后边的apk分析全部需要先脱壳再说这边既然说是本地端口号先搜一下127.0.0.1看看有没有收获过滤出来两个端口发现上边那条记录是Utils是 ConstraintLayout 库内部的调试基础设施帮助开发者理解和优化布局性能的所以很大概率是下边那一个这一个是SecurityManager的类在反调试反逆向做了关键很符合题目所说的检测动态调试工具看上述代码可以看出这就是一个为检测frida注入痕迹的而开的端口符合题意所以本题答案即为270425.分析方俊朗phone.E01检材该应用密钥由多个盐值片段拼接后派生而来。请问第一个盐值片段的具体内容是什么[答案格式SAltsaltsalt]我们在KeyDeriver已经看到了应用密钥是这样子多个盐值片段拼接后派生而来问第一个盐值片段写的很清楚就在下边所以答案是Pr3d1ct0r6.分析方俊朗phone.E01检材当密钥派生过程出现异常时应用会使用一个硬编码的备用密钥。请问该备用密钥的完整内容是什么[答案格式salt_dlefe_123_dfefaf]跟上边几题一样就在密钥派生这部分写了异常的备用密钥明文写在这边f4ll8ack_k3y_2024_pr3d1ct0r7.分析方俊朗phone.E01检材分析优质客户预测应用该应用的安全检测模块通过检查一个特定的类名来判断设备是否安装了Hook框架。请问被检测的完整类名是什么[答案格式ru.foefn.DFeoagn.dfoandf.xoggdg]题目已经说是和Hook框架相关了因此我们可以对这些Hook框架相关的关键词进行搜索过滤Xposed Class.forName Hook发现Xposed存在线索这是Android平台上最著名的Hook框架之一步入后马上就能看见安全检测模块正是通过加载类de.robv.android.xposed.XposedBridge来检测是否设备安装了Xposed框架这种Hook框架其实就在第四题的SecurityManager下边毕竟都是作为安全检测都在一起所以这一题的答案是de.robv.android.xposed.XposedBridge8.分析方俊朗phone.E01检材该应用在偏好设置文件中存储了一个密钥校验值。请问存储该校验值的键名key是什么[答案格式ab_dfefegad_cadfeg]我们在一开始的配置文件这边可以看到类似字段后边跟着一串值key的名字是db_integrity_check但不能确定这就是密钥检验值我们得在jadx里边确认一下搜索后可以在KeyDeriver找到它可以看到这边是获取了MD5算法实例后与key一起计算MD5散列值db_integrity_check, checksum明显是把密钥检验值checksum放到了keydb_integrity_check中所以本题答案是db_integrity_check9.分析方俊朗phone.E01检材该应用加密数据库中存储对话记录的数据表名是什么[答案格式liaotian_dfelge]题目已经指明了本题的目标是这个应用的加密数据库我们很容易就能在data路径下找到这个软件的/databases/chat_history.db但是不知道密码一下子打不开我们去jadx看看能不能找到相关线索发现确实是这边把生成的聊天记录加密存到了chat_records这个表所以答案即为这个当然了这数据库密码只是难搞但并非不能得到毕竟我们一早在apk第二题就找到了相关的配置文件在上文其实也定位到了密钥派生逻辑KeyDeriverPBEKeySpec spec new PBEKeySpec(combinedSeed.toCharArray(), salt1.getBytes(), PBKDF2_ITERATIONS, 256);上文也分析过了密钥是使用的PBKDF2WithHmacSHA256迭代了10000次最后的密钥长度为256bit即32字节完整流程是这样子String combinedSeed signatureHash salt1 salt2 salt3;主口令 签名证书SHA256 第一个盐值片段 第二个盐值片段 第三个盐值片段签名证书就是签名证书啊雷电分析里边直接就有其实4f030268de5e58c26bb6eec54b1be7c0330dde2bf857ee2b3b26c50b25deb239接下来是三段盐明显第一段盐是Pr3d1ct0r第三段是X9kZ!qW3第二段是三段字符串拼起来即v2.0_ net.sqlcipher.BuildConfig.BUILD_TYPE _Slt而中间这个双击就能跳转过去看值所以第二段盐是 v2.0_release_Slt所以主口令是4e1544532b5c88f9acec7a2f5ba79d09bb39a4709b9a9ec36e18c22f540f3270Pr3d1ct0rv2.0_release_SltX9kZ!qW3即可计算主密钥import hashlib signature_hash 4f030268de5e58c26bb6eec54b1be7c0330dde2bf857ee2b3b26c50b25deb239 salt1 Pr3d1ct0r salt2 v2.0_release_Slt salt3 X9kZ!qW3 combined_seed signature_hash salt1 salt2 salt3 key hashlib.pbkdf2_hmac( sha256, combined_seed.encode(utf-8), salt1.encode(utf-8), 10000, dklen32 ).hex() print(combined_seed , combined_seed) print(db_key , key) print(md5(db_key) , hashlib.md5(key.encode(utf-8)).hexdigest())得到密钥与md5值与配置文件中的md5检验值一致证明了密钥正确93b16df295656676dd760e6dcfd71623e446b51c91b028ac84c88958fc3ad98b用这个软件就能打开加密的数据库文件了打开就能发现表名确实是这一个chat_records不过这边我不知道为什么可视化的几个解密软件都不太对劲写了密码解不开但命令行的就能用同一个密码却能成功解密import hashlib import sqlite3 from pathlib import Path from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes PASSPHRASE 93b16df295656676dd760e6dcfd71623e446b51c91b028ac84c88958fc3ad98b def aes_cbc_decrypt(key, iv, ciphertext): cipher Cipher(algorithms.AES(key), modes.CBC(iv)) decryptor cipher.decryptor() return decryptor.update(ciphertext) decryptor.finalize() def decrypt_sqlcipher4_db(): input_db Path(chat_history.db) output_db Path(chat_history_plain.db) if not input_db.exists(): print([-] 未找到 chat_history.db) return data input_db.read_bytes() page_size 4096 reserve_size 80 usable_size page_size - reserve_size if len(data) % page_size ! 0: raise RuntimeError(数据库大小不是 4096 的整数倍) page_count len(data) // page_size print(f[] 数据库页数: {page_count}) file_salt data[:16] print([] SQLCipher 文件 salt:, file_salt.hex()) aes_key hashlib.pbkdf2_hmac( sha512, PASSPHRASE.encode(utf-8), file_salt, 256000, dklen32, ) print([] SQLCipher AES key:, aes_key.hex()) out bytearray() for page_no in range(1, page_count 1): start (page_no - 1) * page_size end page_no * page_size page data[start:end] iv page[usable_size:usable_size 16] if page_no 1: ciphertext page[16:usable_size] plaintext_part aes_cbc_decrypt(aes_key, iv, ciphertext) out bSQLite format 3\x00 out plaintext_part out b\x00 * reserve_size else: ciphertext page[:usable_size] plaintext_page aes_cbc_decrypt(aes_key, iv, ciphertext) out plaintext_page out b\x00 * reserve_size output_db.write_bytes(out) print(f[] 已生成明文数据库: {output_db}) return output_db def verify_plain_db(output_db): print([] 验证明文数据库...) conn sqlite3.connect(output_db) cur conn.cursor() cur.execute(SELECT name FROM sqlite_master WHERE typetable;) tables [row[0] for row in cur.fetchall()] print([] 表名:) for table in tables: print( , table) if chat_records in tables: print(\n[] chat_records 前5条记录:) cur.execute(SELECT * FROM chat_records LIMIT 5;) for row in cur.fetchall(): print( , row) conn.close() print([] 验证完成) def main(): try: output_db decrypt_sqlcipher4_db() verify_plain_db(output_db) except Exception as e: print(f[-] 解密失败: {e}) if __name__ __main__: main()所以附一个解密代码10.分析方俊朗phone.E01检材该应用的密钥生成逻辑该应用中的第三个盐值片段是通过逐字符拼接生成的。请问该片段拼接后的完整内容是什么[答案格式K8m!pQ2x]上边已经分析过了密钥生成逻辑在KeyDeriver密钥是三部分盐值第三部分就在这边所以拼起来就是X9kZ!qW3就好了11.分析方俊朗phone.E01检材该应用使用了载荷在内存中直接加载而不在磁盘落地。若选手希望通过Frida动态拦截明文的DEX字节数组应该Hook该应用壳的哪个私有方法[答案格式loadDexFromMemory]想要拦截明文的DEX字节数组肯定需要先搞明白这个壳对DEX字节数组的核心加载流程我们对原来未脱壳的进行解包把后缀从apk改成zip即可可以看到在assets路径下存在不寻常的payload.dat怀疑和壳加载过程有关搜索一下我们定位到了壳代码所在地可以看到很明确的Android应用保护方案大致流程如下attachBaseContext() - readAsset(payload.dat) //先读加密的Dex文件 - decrypt() //之后解密 - parseDexPayload() //解密payload内容 - initDexFromMemory() //把解密的存到内存里 - InMemoryDexClassLoader //合并到应用主ClassLoader所以可以看到应用将真实 DEX 解密到内存后是调用的私有方法initDexFromMemory因此如果使用 Frida 动态拦截明文 DEX 字节数组也应该HookinitDexFromMemory才对答案即为initDexFromMemory其参数就是解密后的明文DEX字节数组12.分析方俊朗phone.E01检材分析应用的壳代码逻辑其解密密钥由3个字符串片段混淆拼接而成。请通过静态分析还原用于解密的3个片段拼接合并后的完整密钥明文。[答案格式Ab6de_a8bc4d_a5b_345d]我们在上一题就找到了壳代码所在地ShellApplication在壳代码中可以看到即我们本题所需要的解密密钥三部分一个个解就好了首先是getKeyPart1()明显解base64U2gzbGxf得到第一段Sh3ll_继续分析第二段逐个与17异或即可xor_bytes [93, 33, 112, 117, 34, 99, 78, 90] result .join(chr(b ^ 17) for b in xor_bytes) print(result)得到第二段L0ad3r_K最后第三段只是反转而已3y_2024!拼起来得到最后答案是Sh3ll_L0ad3r_K3y_2024!13.接上题当选手尝试使用frida-dexdump等通用脱壳工具动态附加时应用会立刻闪退。请分析该逻辑写出该线程触发进程自杀所调用的完整Java系统方法签名。[答案格式abcd.abcd.Abcdabc.abcd]题目说了是使用dexdump等脱壳的时候会闪退的就在同一个地方我们可以看见这样子一个反dump方法可以看到调用的是lambdastartAntiDumperDaemon0方法明显看见了最后自杀是System.exit(0)来进行的进程自杀题目说了写完整Java系统方法签名所以答案是java.lang.System.exit(0);14.分析方俊朗phone.E01检材方俊朗使用其内部通联工具时共加入过几个群[答案格式7]终于是跳出刚刚那一个预测优质客户软件了步入了下一个软件内部通联工具从各个角度不管是看所有人都有这个软件也好排除法也好我们都很容易确定内部通联工具就是这一个com.socialchat.social_chat_app那这一题问的很明确加入过几个组很明显是要找这个软件的数据库依旧是同样的手法我们去/data/data/包名/databases来找即可看见聊天记录的数据库但是加密了在配置文件这边找到了对应的db_passwordstring nameflutter.db_passwordPgs-dbw1776826167125Good/string但是用这个password却无法解开这个db我们去看看apk的具体逻辑因为这个APP是Flutter应用所以真正的逻辑不在Java层在native文件才是解压apk找到它我们这边可以静态来逆向还原一些逻辑还看见了应用自带有SQLCipher库package:social_chat_app/data/database/database_helper.dart在字符串中可以看到这样子的一句还能看到截取之类的字符串但是并不清晰不明白是如何进行的还是得进行Frida的动态hook才行我不太会hook。。只能ai写一个脚本了其实Flutter AOT反编译也可以function waitForAppContext(callback) { let count 0; const timer setInterval(function () { Java.perform(function () { try { const ActivityThread Java.use(android.app.ActivityThread); const app ActivityThread.currentApplication(); if (app ! null) { clearInterval(timer); const ctx app.getApplicationContext(); console.log([] getApplicationContext ok); callback(ctx); return; } count; console.log([*] waiting for Application context... count); } catch (e) { count; console.log([*] waiting context error:, e); } if (count 30) { clearInterval(timer); console.log([-] still cannot get Application context); } }); }, 500); } setImmediate(function () { console.log([*] no-login social_chat.db decrypt hook loaded); Java.perform(function () { waitForAppContext(function (ctx) { try { const prefs ctx.getSharedPreferences(FlutterSharedPreferences, 0); let raw prefs.getString(flutter.db_password, null); console.log([] flutter.db_password , raw); if (raw null) { console.log([-] 没读到 flutter.db_password); console.log([-] 确认 XML 是否在 /data/user/0/com.socialchat.social_chat_app/shared_prefs/FlutterSharedPreferences.xml); return; } const realPassword raw.substring(2, raw.length - 1); console.log([] raw password , raw); console.log([] real password , realPassword); const dbPath /data/user/0/com.socialchat.social_chat_app/databases/social_chat.db; console.log([] db path , dbPath); forceLoadSqlcipher(); setTimeout(function () { waitForSqlcipherAndRun(dbPath, realPassword); }, 1000); } catch (e) { console.log([-] main logic error:, e); } }); }); });成功发现真实密码大致就是raw.substring(2, raw.length -1)所以密码是s-dbw1778570149492Goo解开后查看conversation即可发现加了技术部和话务组所以答案是2加了这俩群15.分析方俊朗phone.E01检材方俊朗通过物联网设备漏洞共获得多少用户信息[答案格式10]上一题我们已经解开了数据库这边一开始的思路是通过user里边的password_hash和password_salt进行爆破但显然不太能爆破出来因此我们这边不能仿真但是我们可以找到message加密逻辑可以直接解密其发送过的信息从user.config_data可以读到enc_key和enc_iv{enc_key: bGx3iDfEn4O5kW2hf0E594CjcyE1aujg0RIE5DPMM, enc_iv: y1q/i9a/85OsPry0WMffw}import base64 enc_key bGx3iDfEn4O5kW2hf0E594CjcyE1aujg0RIE5DPMM enc_iv y1q/i9a/85OsPry0WMffw key base64.b64decode(enc_key) iv base64.b64decode(enc_iv) print(len(key), key.hex()) print(len(iv), iv.hex())输出发现key是256bit的iv长16字节所以猜测是AES-256-CBC解密当然最关键的判断标准就是尝试解密发现成功了都成功了肯定是真的啊写脚本import argparse import base64 import csv import json import sqlite3 from pathlib import Path from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes def pkcs7_unpad(data: bytes) - bytes: if not data: return data pad data[-1] if 1 pad 16 and data[-pad:] bytes([pad]) * pad: return data[:-pad] return data def aes_cbc_decrypt_base64(cipher_b64: str, key: bytes, iv: bytes) - str: cipher_data base64.b64decode(cipher_b64) decryptor Cipher( algorithms.AES(key), modes.CBC(iv) ).decryptor() plain decryptor.update(cipher_data) decryptor.finalize() plain pkcs7_unpad(plain) return plain.decode(utf-8, errorsreplace) def get_key_iv(conn: sqlite3.Connection, user_id: str | None): conn.row_factory sqlite3.Row cur conn.cursor() if user_id: row cur.execute( SELECT id, config_data FROM user WHERE id ?, (user_id,) ).fetchone() else: row cur.execute( SELECT id, config_data FROM user LIMIT 1 ).fetchone() if not row: raise RuntimeError(user 表中没有找到用户记录) config_data row[config_data] if not config_data: raise RuntimeError(user.config_data 为空) config json.loads(config_data) key base64.b64decode(config[enc_key]) iv base64.b64decode(config[enc_iv]) print([] use user_id:, row[id]) print([] AES key:, key.hex()) print([] AES iv :, iv.hex()) return key, iv def convert_messages(input_db: Path, output_csv: Path, user_id: str | None): conn sqlite3.connect(input_db) conn.row_factory sqlite3.Row key, iv get_key_iv(conn, user_id) cur conn.cursor() rows cur.execute( SELECT * FROM message ORDER BY create_at ASC ).fetchall() if not rows: print([-] message 表为空) conn.close() return fieldnames list(rows[0].keys()) # 增加一列明文 if content_plain not in fieldnames: fieldnames.append(content_plain) output_rows [] for row in rows: item dict(row) cipher_content row[content] try: plain aes_cbc_decrypt_base64(cipher_content, key, iv) except Exception as e: plain f[DECRYPT_ERROR] {e} item[content_plain] plain output_rows.append(item) with output_csv.open(w, encodingutf-8-sig, newline) as f: writer csv.DictWriter(f, fieldnamesfieldnames) writer.writeheader() writer.writerows(output_rows) conn.close() print([] message 总数:, len(output_rows)) print([] 已导出:, output_csv) def main(): parser argparse.ArgumentParser() parser.add_argument( -i, --input, defaultsocial_chat_plain.db, help输入已经解密后的普通 SQLite 数据库 ) parser.add_argument( -o, --output, defaultmessages_plain.csv, help输出 CSV ) parser.add_argument( -u, --user-id, defaultNone, help指定 user.id不填则默认取 user 表第一条 ) args parser.parse_args() input_db Path(args.input) output_csv Path(args.output) if not input_db.exists(): raise FileNotFoundError(f找不到数据库文件: {input_db}) convert_messages(input_db, output_csv, args.user_id) if __name__ __main__: main()得到利用物联网获取了32户16.分析周文杰Image.zip检材周文杰跟其犯罪团伙人员内部通联工具包名是[答案格式com.apt.app]跟上边方俊朗的不能说大差不差吧只能说一模一样就是这一个apkcom.socialchat.social_chat_app填写包名即可17.分析周文杰Image.zip检材内部通联app聊天数据库名称是[答案格式abc.db]在data文件夹一路找即可还是跟刚刚一样就是这一个social_chat.db18.分析周文杰Image.zip检材内部通联app聊天数据库密码保存在哪个文件中[答案格式Abc.txt]依旧是差不多一样的根据应用数据目录中的偏好配置文件进行分析/shared_prefs/FlutterSharedPreferences.xml在 Flutter 应用中常见敏感配置会保存在该文件中所以密码就存在 FlutterSharedPreferences.xml文件中19.分析周文杰Image.zip检材周文杰内部通联app聊天数据库密码是[答案格式123-abc]就是18那个文件打开即可看见Pgs-dbw1776853545473Good但是我们刚刚在14题已经明确了密码应该是s-dbw1776853545473Goo才对俩软件hash一样逻辑肯定也一样实在不放心完全可以拿这个解密试试看能解就是密码成功所以本题答案的密码就是s-dbw1776853545473Goo20.分析周文杰Image.zip检材内部通联app聊天数据使用的什么加密算法?[答案格式ABCDEF]也和15一样因为apk都是同一个加密手法也一样都是AES-256-CBC我看答案写AES好像也算对了实在不放心可以用15的同款脚本尝试解密解密数据库也可以拿之前第九题的脚本跑能解密出一套完整的可读文字自然是正确的说明和之前的一样的确是AES-256-CBC21.分析周文杰Image.zip检材内部通联app用户密码的盐值是[答案格式1234abcd]上两题已经说明了密码s-dbw1776853545473Goo解密db文件a3f8d9c2e1b4h7g6k9m2n5p8q1r4t7w得到密码盐22.分析周文杰Image.zip检材记录周文杰内部通联app登录密码提示的应用包名是[答案格式com.temp.app]根据题目意思很明显存在有一个app里边记录了周文杰内部通联app登录密码的提示我们在/data/data/目录中排查其他可疑 App发现两个记事本类应用com.wenying.notebook com.jinghong.notebookkssjh一个个看就好了在com.jinghong.notebookkssjh发现了记事本数据库NotePal.db提取一下preview_content 英文2 数字6所以该笔记明显是登录密码提示因此记录周文杰内部通联 App 登录密码提示的应用包名为com.jinghong.notebookkssjh23.分析周文杰Image.zip检材内部通联app登录密码是[答案格式123abc]上一题已经说了是英文2数字6但是不知道是什么只能进行爆破好在我们21已经知道了用户名是zhouwenjie还知道了password的密码和salt利用hashcat爆破即可注意这边试了试发现是sha256(sha256(password salt)不只是单层的#!/bin/bash # 优化版使用hashcat的规则和组合模式 HASH5d85b77d7d6d1a76cd589c3ba21d1839b1dd28568e39f1d2facc3a1b7d2e8bcb SALTa3f8d9c2e1b4h7g6k9m2n5p8q1r4t7w echo 创建密码列表... # 生成所有可能的密码到文件 hashcat -a 3 ?l?l?d?d?d?d?d?d --stdout passwords.txt echo 计算哈希... # 使用Python快速计算 python3 -c import hashlib import sys salt $SALT target $HASH with open(passwords.txt, r) as f: for line in f: password line.strip() # 第一层哈希 h1 hashlib.sha256((password salt).encode()).hexdigest() # 第二层哈希 h2 hashlib.sha256(h1.encode()).hexdigest() if h2 target: print(f密码找到: {password}) with open(found.txt, w) as out: out.write(password) sys.exit(0) print(未找到密码) # 显示结果 if [ -f found.txt ]; then echo -e \n破解成功密码: $(cat found.txt) else echo -e \n未找到密码 fi # 清理 rm -f passwords.txt found.txt得到mb202623即本题答案24.分析周文杰Image.zip检材周文杰在内部通联app中删除了几条聊天记录[答案格式123]有了上一题这个密码就可以进行仿真登录了这边讲一下如何仿真apk先安装该软件然后将该文件夹复制到MT文件夹共享目录下接着在手机的MT管理器中左侧打开/storage/emulated/0/Pictures右侧打开/data/data这个时候长按这个左侧的文件夹复制到右边来全部选择复制并替换之后直接回到这边即可用户名是zhouwenjie密码是mb202623成功仿真进入成功仿真之后直接在里边找“已删除”即可数一数就能发现是6条25.分析周文杰Image.zip检材聊天数据库中显示聊天数据删除的是哪个字段?[答案格式ab_cd]这题可能有点争议吧因为如果问的是整个对话删除的情况那字段是is_deleted如果是问的个别聊天记录删除情况那就是extra_val这边可以对照看见已经删除的内容已删除的还会存在数据库里26.分析林小婉手机检材发现有个应用隐藏了很多信息目前已经找到这个应用它的程序名称是[答案格式微信]因为给了附件直接省略找程序这一步了from androguard.core.apk import APK apk APK(1778310207366_9eee4f1c.apk) print(apk.get_package()) print(apk.get_app_name()) print(apk.get_main_activity()) print(apk.get_files())看看基础信息package: com.jinritoutiao.news appname: 今日头条 main activity: com.jinritoutiao.news.MainActivity assets/vault_data.jth2所以是今日头条当然雷电可以直接一眼看见就是了27.分析林小婉手机检材这个应用有一个安全加密的PIN码它是多少[答案格式12345678]题目问PIN码那就直接搜索PIN看看反编译后可见 PIN 校验逻辑大致如下salt JinriPIN_Salt_ expected 7e881d49322271f3dd4fa24846a5cc53d1e0506b46007caa4b27f1416b27b54c algorithm PBKDF2WithHmacSHA256 iterations 10000 keyLength 256所以也就是说这边我们的程序不是直接保存 PIN而是将用户输入的 PIN 进行 PBKDF2-HMAC-SHA256 计算再和固定 hash 比较由于 PIN 长度还写死了限制为 8 位可以写脚本爆破import hashlib expected 7e881d49322271f3dd4fa24846a5cc53d1e0506b46007caa4b27f1416b27b54c salt bJinriPIN_Salt_ for i in range(100000000): pin f{i:08d} h hashlib.pbkdf2_hmac( sha256, pin.encode(), salt, 10000, 32 ).hex() if h expected: print(pin) break运行得到20150412就是本题的答案了上边那一个代码可能不太能爆破太慢了可以结合女儿生日来减少大量范围从而好爆破很多import hashlib expected 7e881d49322271f3dd4fa24846a5cc53d1e0506b46007caa4b27f1416b27b54c salt bJinriPIN_Salt_ # 常见日期格式年月日、月日年、日月年 formats [{year:04d}{month:02d}{day:02d}, {month:02d}{day:02d}{year:04d}, {day:02d}{month:02d}{year:04d}] found False for year in range(2000, 2024): # 假设女儿生日在2000-2023之间 for month in range(1, 13): # 每月天数 if month in (1,3,5,7,8,10,12): day_max 31 elif month in (4,6,9,11): day_max 30 else: if (year % 4 0 and year % 100 ! 0) or (year % 400 0): day_max 29 else: day_max 28 for day in range(1, day_max 1): for fmt in formats: pin fmt.format(yearyear, monthmonth, dayday) h hashlib.pbkdf2_hmac(sha256, pin.encode(), salt, 10000, 32).hex() if h expected: print(pin) found True break if found: break if found: break if found: break28.分析林小婉手机检材这个应用隐藏的数据中每个标签数据里notes字段表示多少[答案格式事项]题目说这个应用隐藏了数据那我们先看看加密或隐藏的内容在哪里解包apk发现了assets路径下存在有一个奇怪的文件怀疑是加密文件对此在jadx进行搜索在这边我们发现了主密钥的生成逻辑password Jinritoutiao_Master_Key_2024_Secret salt JinriSalt_2024 algorithm PBKDF2WithHmacSHA256 iterations 65536 keyLength 256使用AES/GCM/NoPadding加密算法密钥派生PBKDF2算法迭代65536次包含7个数据类可以看到密钥都写在里边了硬编码根据代码可以看到前边12是IV最后16是Tag中间是密文最后32位检验值观察一下这个加密文件文件头为JTH3所以要跳开这个所以文件结构可以整理为前 6 字节magic/version 第 6 到 18 字节IV12 字节 中间部分ciphertext 倒数 48 到倒数 32 字节GCM tag16 字节 最后 32 字节校验值解密脚本如下from pathlib import Path from cryptography.hazmat.primitives.ciphers.aead import AESGCM import hashlib import json data Path(apk_extract/assets/vault_data.jth2).read_bytes() key hashlib.pbkdf2_hmac( sha256, bJinritoutiao_Master_Key_2024_Secret, bJinriSalt_2024, 65536, 32 ) iv data[6:18] tag data[-48:-32] ciphertext data[18:-48] plaintext AESGCM(key).decrypt(iv, ciphertext tag, None) Path(vault_decrypted.json).write_bytes(plaintext) j json.loads(plaintext.decode(utf-8)) print(json.dumps(j, ensure_asciiFalse, indent2))解密后得到 vault_decrypted.json可以看到里边有很多关键词在解密后的 JSON 中多个数据结构都存在notes字段例如{ id: 1, name: 陈志远私人钱包, notes: 老板私人钱包 }可以看到大概就是备注的意思搜索备注发现UI 渲染代码VaultScreenKt真把notes作为备注说明程序在界面上把notes显示为“备注”。所以答案为备注29.分析林小婉手机检材这个应用隐藏的数据中文件备份服务器的IP地址是多少[答案格式192.168.1.1]在解密后的vault_decrypted.json中搜索文件备份服务器即可可以看到c2字段中有如下数据因此文件备份服务器 IP 为192.168.1.20030.分析林小婉手机检材发现内部通联中财神撤回了一条消息这个消息的内容是[答案格式盘古石杯。]内部通联依旧回到之前的social软件太熟了这边就不细说了先找数据库再找密码还是一样掐头去尾密码是s-dbw1776826167125Goo确实有财神还是跟刚刚一样的流程先去除数据库密码再转csv文件过滤财神成功找到了撤回的那条消息“把23年10月到24年6月的账本整理一下发给我。”31.分析林小婉手机检材发现了账本账本打开密码是什么[答案格式按实际填写]继续查看解密后的vault_decrypted.json问账本的密码看看有没有账本和密码的内容还真发现一条和龙腾项目账本相关的记录{ id: 7, website: 龙腾项目账本, username: , password: DragonTeng2024#$, notes: 账单复合.png打开密码 }同时在core字段中也有交叉印证{ id: 6, category: 龙腾四海项目, title: 核心账本数据, content: 龙腾项目账本DragonTeng2024#$, notes: 密码藏在账单复合.png图片中需用LSB隐写提取 }两处都指向同一个密码因此账本打开密码为DragonTeng2024#$

相关文章:

2026盘古石取证初赛(APK取证)

APK取证1.分析方俊朗phone.E01检材,筛选优质客户应用将用户查询记录存储在一个加密的本地数据库中。请问该加密数据库的文件名是什么?[答案格式:12_abc.db]题目说了这边是筛选优质客户,其实和手机取证最后一题一样的,先…...

Go语言安全编码实践:常见漏洞与防护

Go语言安全编码实践:常见漏洞与防护 1. 安全编码原则 安全编码是防止漏洞的根本,包括输入验证、输出编码、最小权限等原则。 2. 安全工具 package securityimport ("regexp""strings" )type Validator struct {emailRegex *regexp.R…...

SQLite Having 子句详解

SQLite Having 子句详解 SQLite 是一款轻量级的数据库管理系统,广泛应用于移动应用、桌面应用以及各种嵌入式系统。在 SQLite 中,HAVING 子句是一个非常重要的特性,它用于对 GROUP BY 子句的查询结果进行过滤。本文将详细介绍 SQLite 的 HAVING 子句,包括其用法、语法以及…...

抖音图片怎么去水印?2026实测免费去水印方法全盘点,这几款工具真好用

抖音图片怎么去水印?2026实测免费去水印方法全盘点,这几款工具真好用 刷抖音的时候,你有没有遇到过这种情况:看到一张超好看的图片,点保存,结果发现角落里多了一行「用户名」或者一个抖音 Logo,…...

Java的Random类

在Java中,java.util.Random 类是日常开发中最常用的伪随机数生成器。它基于线性同余算法生成随机数,只要给定相同的初始值(种子 seed),就能生成完全相同的随机数序列。 🎲 Random 类的基础使用 使用 Random…...

光子储层计算在无人机动态补偿中的创新应用

1. 深度光子储层计算在无人机动态补偿中的创新应用在无人机控制领域,传统PID控制器面对复杂流体环境时往往力不从心。当无人机在狭窄空间或近地面飞行时,地面效应、天花板效应以及湍流再循环等未建模动力学因素会导致显著的性能下降。我在参与某城市峡谷…...

2026绍兴本地GEO优化公司实测:服务规范与效果验证全解析

引言随着AI搜索算法的不断迭代,绍兴本地企业对GEO(生成式引擎优化)服务的需求日益增长。为了帮助这些企业在选择GEO优化服务商时做出明智决策,本测评以客观、中立的态度,基于EEAT原则(经验、专业性、权威性…...

如何在3分钟内完成Windows与Office智能激活:KMS_VL_ALL_AIO完全指南

如何在3分钟内完成Windows与Office智能激活:KMS_VL_ALL_AIO完全指南 【免费下载链接】KMS_VL_ALL_AIO Smart Activation Script 项目地址: https://gitcode.com/gh_mirrors/km/KMS_VL_ALL_AIO 还在为Windows操作系统和Office办公软件的正版激活而烦恼吗&…...

ElevenLabs账号被限频?紧急修复手册:3分钟绕过Rate Limit限制,解锁Pro级语音并发权限

更多请点击: https://intelliparadigm.com 第一章:ElevenLabs超写实语音生成教程 ElevenLabs 是当前业界领先的 AI 语音合成平台,其模型在语调自然度、情感表达力与跨语言一致性方面表现卓越。本章将指导你完成从 API 接入到高质量语音生成的…...

CSS 视图过渡完全指南

CSS 视图过渡完全指南 引言 CSS 视图过渡(View Transitions)是一个强大的新特性,它允许开发者创建平滑的页面过渡动画。本文将深入探讨视图过渡的各种用法和高级技巧。 基础概念回顾 什么是视图过渡 视图过渡 API 允许你在 DOM 状态变化时创建…...

v7上线首周,93%老用户没发现的隐藏指令——高阶提示工程实战手册,含12个未公开参数调用语法

更多请点击: https://intelliparadigm.com 第一章:Midjourney v7核心架构升级与隐性能力图谱 多模态融合推理引擎重构 Midjourney v7 引入了基于分层注意力对齐(Hierarchical Attention Alignment, HAA)的新型生成主干&#xff…...

Happy Island Designer完整指南:免费在线岛屿设计工具终极教程

Happy Island Designer完整指南:免费在线岛屿设计工具终极教程 【免费下载链接】HappyIslandDesigner "Happy Island Designer (Alpha)",是一个在线工具,它允许用户设计和定制自己的岛屿。这个工具是受游戏《动物森友会》(Animal C…...

抖音图片怎么去水印?2026实测去水印方法全整理,免费工具一并推荐

抖音图片怎么去水印?2026实测去水印方法全整理,免费工具一并推荐 每次在抖音刷到一张好看的图,长按保存下来却发现角落盖着一行"昵称抖音"水印,这种体验相信不少人都经历过。水印不影响欣赏还好,但如果想把图…...

抖音无水印下载神器:douyin-downloader完整指南,轻松保存高清视频

抖音无水印下载神器:douyin-downloader完整指南,轻松保存高清视频 【免费下载链接】douyin-downloader A practical Douyin downloader for both single-item and profile batch downloads, with progress display, retries, SQLite deduplication, and …...

LangChain+FAISS 向量数据库搭建轻量化 RAG 应用

📝 本章学习目标:本章聚焦企业轻量化落地,帮助读者快速掌握基于 LangChainFAISS 的私有化 RAG 开发流程。通过本章学习,你将从零搭建一套无需 GPU、无外网依赖、纯本地运行、代码极简、可直接上线的轻量化 RAG 应用。 一、引言&a…...

本地化AI代码助手部署指南:从模型选型到性能调优

1. 项目概述:一个面向开发者的本地化AI代码助手最近在GitHub上看到一个挺有意思的项目,叫“JPeetz/Hermes-Studio”。乍一看名字,可能会联想到希腊神话里的信使赫尔墨斯,或者某个设计软件。但点进去你会发现,这其实是一…...

数据库优化(八)MySQL 大小管理 ——东方仙盟金丹期

1查询整个mysql下数据库大小SELECTtable_schema AS db_name,ROUND(SUM(data_length index_length)/1024/1024,2) AS size_mb FROM information_schema.tables GROUP BY table_schema ORDER BY size_mb DESC;| db_name | size_mb | -------------------------…...

从0到1掌握Ansible:让自动化运维不再是梦想

最近在公司推进自动化运维的时候,发现很多同事对Ansible还是一知半解,要么就是简单用用,要么就是直接放弃。其实Ansible真的没那么复杂,我用了这么多年,今天就把我的实战经验分享给大家。 说实话,刚开始接…...

Resolink MCP:基于MCP协议与Playwright的AI浏览器自动化实践

1. 项目概述:当AI助手学会“动手”——Resolink MCP的浏览器自动化革命如果你和我一样,每天在Cursor、Claude这类AI编程助手的陪伴下写代码,那你一定遇到过这样的场景:你正和AI热烈讨论一个技术方案,突然需要去浏览器里…...

用PLC控制Labview自动运行

博图软件设置注意数据位正确下图为Labview读取CSV文件的位置测试数据如下图所示实现方法:在1分支内创建好条件,当PLC心跳为True那么就去跑True里面的流程(CSM框架)...

别再死磕外链了:用Python+搜索API实现Google SEO自动化内容生产

做Google SEO的人都有一个共同感受:越来越难了。 以前发发外链、堆堆锚文本就能上去,现在不行了。Google的算法从"匹配关键词"进化到了"匹配搜索意图"。外链权重从60%降到30%,内容质量成了核心排名因素。 但问题是&#…...

基于Helm与Kubernetes的以太坊节点自动化部署与运维实战

1. 项目概述:当以太坊遇见Kubernetes如果你和我一样,在区块链基础设施领域摸爬滚打多年,从早期手动编译客户端、配置systemd服务,到后来用Docker Compose编排节点,每一步都伴随着大量的重复劳动和运维痛点。当节点数量…...

AI应用着陆页模板:快速构建专业产品门户的实战指南

1. 项目概述:一个面向AI应用落地的着陆页模板 最近在折腾AI应用开发的朋友,估计都遇到过同一个问题:模型和算法好不容易调好了,后端API也搭起来了,但一到“怎么让用户用起来”这一步,就卡壳了。尤其是那个…...

codebase-digest:自动化代码库分析工具的设计原理与工程实践

1. 项目概述:当代码库变成“黑盒”,我们如何快速理解它?你有没有接手过一个庞大而陌生的代码库?面对成千上万的文件和错综复杂的依赖关系,那种感觉就像被扔进了一个没有地图的迷宫。传统的做法是,你得像考古…...

Alph:一键统一配置AI编程助手MCP服务器的命令行工具

1. 项目概述:告别手动配置的混乱时代 如果你和我一样,日常开发中同时用着 Cursor、Claude Code、Gemini CLI 这些 AI 编程助手,那你一定对下面这个场景深恶痛绝:每次想给它们接入一个新的 MCP 服务器,都得像个考古学家…...

国产替代之SFT1452-H与VBFB1251K参数对比报告

N沟道功率MOSFET参数对比分析报告一、产品概述SFT1452-H:安森美(onsemi)N沟道功率MOSFET,耐压250V,低导通电阻,ESD门极保护,符合无卤素标准。封装:IPAK (TO-251)。适用于通用开关应用…...

Photoshop AVIF插件实战:解锁下一代图像格式的完整解决方案

Photoshop AVIF插件实战:解锁下一代图像格式的完整解决方案 【免费下载链接】avif-format An AV1 Image (AVIF) file format plug-in for Adobe Photoshop 项目地址: https://gitcode.com/gh_mirrors/avi/avif-format 为Adobe Photoshop添加AVIF格式支持不再…...

告别重复点击!淘金币自动化脚本让你每天多出20分钟自由时间

告别重复点击!淘金币自动化脚本让你每天多出20分钟自由时间 【免费下载链接】taojinbi 淘宝淘金币自动执行脚本,包含蚂蚁森林收取能量,芭芭农场全任务,解放你的双手 项目地址: https://gitcode.com/gh_mirrors/ta/taojinbi …...

京东自动评价工具:3分钟解决购物评价难题的智能助手

京东自动评价工具:3分钟解决购物评价难题的智能助手 【免费下载链接】jd_AutoComment 自动评价,仅供交流学习之用 项目地址: https://gitcode.com/gh_mirrors/jd/jd_AutoComment 还在为购物后的评价烦恼吗?每次收到京东的"待评价"提醒&…...

算法将驱动一切:边缘AI智能体如何重塑智能系统

仓库装卸区的安全摄像头每天采集86400秒的视频数据。长途卡车上的车队远程信息记录仪在两次加油之间积累了数GB的行车影像。外科手术机器人的立体摄像头以每秒60帧的速度生成密集点云。所有这些数据都产生于数字世界与现实世界的交界处,但几乎没有任何一条被用于智能…...