说明
185 道题目(9 题未解出)
物联网取证 3、15、17、20、30、31、32、33
服务器取证 24

手机取证
1. 分析黄志远phone.E01检材,黄志远手机总共安装了多少款短视频应用?[答案格式:1]
apk 分析里面,4 个。

2. 分析黄志远phone.E01检材,黄志远手机安装的龙虾应用的包名是什么?[答案格式:com.xxx.ui]
很明显就是这个gptos.intelligence.assistant

3. 接上题,首次打开应用的时间是?[答案格式:2021-01-11-01:11:44]
这个很熟悉了,直接搜索包名,选择 data 目录下的,shared_prefs 文件,里面可以找到

时间戳转化一下1776397998058
2026-04-17-11:53:18
4. 分析黄志远phone.E01检材,黄志远使用此应用攻击过多少台主机?[答案格式:1]
查看包名目录下的文件

挨个翻看并没有发现任何 ip 或者攻击记录等等,所以答案是 0
5. 分析黄志远phone.E01检材,黄志远使用哪款应用控制了其PC的agent工具[答案格式:wechat]
火眼分析出来的这个 discord,查看一下,应该就是

6. 分析黄志远phone.E01检材,黄志远使用这款应用的版本是多少?[答案格式:111.1]
在 apk 分析里面找一下
311.2

7. 分析黄志远phone.E01检材,接上题,登录的用户名是什么?[答案格式:wwww1234]
test901234

8. 分析黄志远phone.E01检材,该应用与pc端agent的配对码是什么?[答案格式:ABC456]
依旧找到 data 目录下的文件,翻一翻

在这里找到了聊天记录

隐藏其他列,复制一下,内容太多。尝试搜索一下 code
**第一个搜到的就是 here's your pairing **3EXEQ5R8

9. 分析黄志远phone.E01检材,该应用共对几个ip进行扫描?[答案格式:5]
这个继续在聊天记录里面,先搜索扫描二字,192.168.1.16 192.1681.10,找到了两个
**但是bot 始终处于 **未配对 / 未执行命令 的状态
后续 bot 只是在 枚举自身命令源码**,没有真正跑** <span class="ne-text">nmap</span>或返回端口信息
因此****目前还没有完成任何一次有效扫描


**扫描的 IP 只有一个:**192.168.61.135

从这行命令可以确认(标准的 Kali 渗透测试端口扫描行为)
** **terminal: "nmap -sS -sV -sC -O -p- -T4 192.168.6..."
10. 分析黄志远phone.E01检材,该应用总共调用了几个暴力破解工具?[答案格式:[1]
两个(都在终端执行的记录这里 )
hydra 爆破密码

Gobuster 目录暴力枚举

11. 分析黄志远phone.E01检材,黄志远使用其内部通联工具进行沟通,其账号的登陆密码是多少? [答案格式:123456]
内部通联工具应该是这个 social_chat_app,因为很多人手机上都有这个,名字也像是

这个题目,先去看了看相关的数据库文件,发现是加密的

shared_prefs 里面有类似数据库的密码,但是不对
Pgs-dbw1776839203359Good


看了其他人手机的检材,偶然看到了这个
仿照格式 s-dbw1776839203359Goo,拿这个试一试成功进去了,可能证明其他人的数据库密码也是这样的

可以看到信息是加密了

这里有用户** id :usr_heiked**
密码** hash :fc29eb768c139c05c0bfcb697d9b26d194878a66451b3ab91b202e9710874a63**
**盐值:**a3f8d9c2e1b4h7g6k9m2n5p8q1r4t7w

密码就需要爆破了。这里我看格式是纯数字,遵循着由简入难的原则,先试一试 6、7、8 位纯数字
让 ai 写一个脚本,尝试不同哈希拼接方式。
import hashlib
import sys
import time
TARGET_HASH = "fc29eb768c139c05c0bfcb697d9b26d194878a66451b3ab91b202e9710874a63"
SALT = "a3f8d9c2e1b4h7g6k9m2n5p8q1r4t7w"
def h(data: bytes) -> str:
return hashlib.sha256(data).hexdigest()
def d(data: bytes) -> bytes:
return hashlib.sha256(data).digest()
strategies = [
("SHA256(pwd+salt)", lambda p: h(p.encode() + SALT.encode())),
("SHA256(salt+pwd)", lambda p: h(SALT.encode() + p.encode())),
("SHA256(pwd)", lambda p: h(p.encode())),
("SHA256(hex SHA256(pwd+salt))", lambda p: h(h(p.encode()+SALT.encode()).encode())),
("SHA256(raw SHA256(pwd+salt))", lambda p: h(d(p.encode()+SALT.encode()))),
("SHA256(hex SHA256(salt+pwd))", lambda p: h(h(SALT.encode()+p.encode()).encode())),
("SHA256(raw SHA256(salt+pwd))", lambda p: h(d(SALT.encode()+p.encode()))),
("MD5(pwd+salt)", lambda p: hashlib.md5(p.encode()+SALT.encode()).hexdigest()),
("MD5(salt+pwd)", lambda p: hashlib.md5(SALT.encode()+p.encode()).hexdigest()),
]
total_checked = 0
start_time = time.time()
从1位到8位依次尝试
digit_lengths = [
(1, 10), # 0-9
(2, 100), # 00-99
(3, 1000), # 000-999
(4, 10000), # 0000-9999
(5, 100000), # 00000-99999
]
已尝试过6位,跳过
digit_lengths.extend([
(7, 10_000_000), # 0000000-9999999
])
for digits, total in digit_lengths:
print(f"\n[*] 正在尝试 {digits} 位数字密码 (0~{10**digits-1})...")
for pwd_int in range(total):
password = f"{pwd_int:0{digits}d}"
for name, hash_func in strategies:
if hash_func(password) == TARGET_HASH:
elapsed = time.time() - start_time
print(f"\n[+] 找到密码!")
print(f"[+] 策略: {name}")
print(f"[+] 密码: {password}")
print(f"[+] 耗时: {elapsed:.2f}秒")
sys.exit(0)
total_checked += 1
if total_checked % 500000 == 0:
elapsed = time.time() - start_time
rate = total_checked / elapsed
print(f" 进度: {total_checked:,} 次, 耗时 {elapsed:.0f}秒, 速度 {rate:.0f} 次/秒", end="\r")
sys.stdout.flush()
print(f"\n[-] 1-7位数字密码穷举完成,共 {total_checked:,} 次尝试,未找到匹配密码")
尝试8位数字
print(f"\n[*] 正在尝试 8 位数字密码...")
for pwd_int in range(100_000_000):
password = f"{pwd_int:08d}"
for name, hash_func in strategies:
if hash_func(password) == TARGET_HASH:
elapsed = time.time() - start_time
print(f"\n[+] 找到密码!")
print(f"[+] 策略: {name}")
print(f"[+] 密码: {password}")
print(f"[+] 耗时: {elapsed:.2f}秒")
sys.exit(0)
total_checked += 1
if total_checked % 500000 == 0:
elapsed = time.time() - start_time
rate = total_checked / elapsed
print(f" 进度: {total_checked:,} 次, 耗时 {elapsed:.0f}秒, 速度 {rate:.0f} 次/秒", end="\r")
sys.stdout.flush()
elapsed = time.time() - start_time
print(f"\n[-] 全部穷举完成,共 {total_checked:,} 次尝试,耗时 {elapsed:.0f}秒,未找到匹配密码")
08164085

12.[答案格式:123456]12.分析黄志远phone.E01检材,黄志远一共发送过几个文件给代号军师的嫌疑人?[答案格式:1]
可以看到这里,黄志远和军师在聊天
看最后俩条黄志远发了 2 个文件

13. 分析方俊朗phone.E01检材,方俊郎手机总共安装了多少款理财应用?[答案格式:1]
4 个
京东金融,股参谋,东方财富,欧易。
最后一个没想到

14. 分析方俊朗phone.E01检材,方俊朗使用筛选优质客户的应用包名是什么?[答案格式:com.xxx.ui]
com.example.predictor

apk取证
1. 分析方俊朗phone.E01检材,筛选优质客户应用将用户查询记录存储在一个加密的本地数据库中。请问该加密数据库的文件名是什么?[答案格式:12_abc.db]
依旧复制包名,找到 data 目录下的 db 文件
social_chat.db

2. 分析方俊朗phone.E01检材,该应用使用了哪种密钥派生算法来生成数据库加密密钥?请写出完整的算法标识名称。[答案格式:DFBDSDFGG123]
用雷电 app 分析一下

发现有壳,脱壳试试

最常见的数据库加密是 KDF
**SQLCipher **默认就是 PBKDF2-HMAC-SHA1(密码, salt, 64000, 256bit)
| 用途 |
常见KDF |
| SQLCipher |
PBKDF2-HMAC-SHA1 (默认64k迭代)或SHA512(新版) |
| Jetpack Security (EncryptedFile) |
PBKDF2WithHmacSHA1 /SHA256 |
| 指纹/锁屏凭证派生 |
scrypt (较少,多见于自定义) |
可以看到是有 sqlcipher 的

搜索一下 kdf
找到了 PBKDF2WithHmacSHA256

3. 分析方俊朗phone.E01检材,该应用的密钥派生过程中使用了多少次迭代运算?[答案格式:345678]
10000

4. 分析方俊朗phone.E01检材,该应用检测动态调试工具时探测了哪个本地端口号?[答案格式:64321]
SecurityManager 类
27042

5. 分析方俊朗phone.E01检材,该应用密钥由多个"盐值片段"拼接后派生而来。请问第一个盐值片段的具体内容是什么?[答案格式:SAltsaltsalt]
第 2 题****加密算法那里点进去
有个 getsaltpart1,双击看一下

Pr3d1ct0r

6. 分析方俊朗phone.E01检材,当密钥派生过程出现异常时,应用会使用一个硬编码的备用密钥。请问该备用密钥的完整内容是什么?[答案格式:salt_dlefe_123_dfefaf]
一样的地方
f4ll8ack_k3y_2024_pr3d1ct0r

7. 分析方俊朗phone.E01检材,分析"优质客户预测"应用,该应用的安全检测模块通过检查一个特定的类名来判断设备是否安装了Hook框架。请问被检测的完整类名是什么?[答案格式:ru.foefn.DFeoagn.dfoandf.xoggdg]
在端口下面的代码就是
Xposed 是一个著名的 Android 逆向工程框架,经常用来 hook
isXposedDetected 这个看名字就知道是检测了

8. 分析方俊朗phone.E01检材,该应用在偏好设置文件中存储了一个密钥校验值。请问存储该校验值的键名(key)是什么?[答案格式:ab_dfefegad_cadfeg]
** 火眼找 data 目录下,发现匹配的**
db_integrity_check ,还有之前的迭代次数 10000

可以在 jadx 中搜索确认

9. 分析方俊朗phone.E01检材,该应用加密数据库中存储对话记录的数据表名是什么?[答案格式:liaotian_dfelge]
这个不太会,把 jadx 里的加密代码交给 ai,说还需要** apk SHA - 256 签名**
在 jadx 中可以自动提取出来

#! python
-- coding: utf-8 --
import hashlib
import binascii555555555555555555555555555
========================
从你截图 & 代码中提取的参数
========================
1️⃣ 应用签名 SHA-256(来自截图,已去冒号、小写)
SIGNATURE_HASH = (
"4f030268de5e58c26bb6eec54b1be7c0330dde2bf857ee2b3b26c50b25deb239"
)
2️⃣ 三个 Salt(硬编码在 KeyDeriver 中)
SALT_1 = "Pr3d1ct0r"
SALT_2 = "v2.0_release_S@lt"
SALT_3 = "X9kZ!qW3"
3️⃣ PBKDF2 参数
PBKDF2_ITERATIONS = 10000
KEY_LENGTH_BITS = 256
def derive_database_key():
"""
完全复现 KeyDeriver.deriveKey()
"""
# 拼接 seed(password)
combined_seed = SIGNATURE_HASH + SALT_1 + SALT_2 + SALT_3
# PBKDF2-HMAC-SHA256
key_bytes = hashlib.pbkdf2_hmac(
hash_name="sha256",
password=combined_seed.encode("utf-8"),
salt=SALT_1.encode("utf-8"),
iterations=PBKDF2_ITERATIONS,
dklen=KEY_LENGTH_BITS // 8 # 32 bytes
)
# 转成 hex(和 bytesToHex 完全一致)
final_key = binascii.hexlify(key_bytes).decode("utf-8")
return final_key
if name == "main":
db_key = derive_database_key()
print("=" * 60)
print("✅ 数据库加密密钥(HEX)")
print("=" * 60)
print(db_key)
print("=" * 60)
print("\n? 使用提示:")
print("• SQLCipher:")
print(f" PRAGMA key = \"x'{db_key}'\";")
print("• AES-256-CBC:")
print(f" Key = {db_key}")
93b16df295656676dd760e6dcfd71623e446b51c91b028ac84c88958fc3ad98b

**然后,将加密的数据库文件用 **DB Browser for SQLCipher 打开
输入口令即可

chat_records

10. 分析方俊朗phone.E01检材,该应用的密钥生成逻辑,该应用中的第三个盐值片段是通过逐字符拼接生成的。请问该片段拼接后的完整内容是什么?[答案格式:K8m!pQ2x]
** 这个简单, X9kZ!qW3 **

11. 分析方俊朗phone.E01检材,该应用使用了载荷在内存中直接加载而不在磁盘落地。若选手希望通过Frida动态拦截明文的DEX字节数组,应该Hook该应用壳的哪个私有方法?[答案格式:loadDexFromMemory]
这个看不懂题...
**不过其实可以蒙答案,根据题目要求的是方法,以及格式,可以搜一下 dex **
发现有很多匹配的方法,再搜索 dexfrom,就找到了

双击第二个,第一个明显不是、

12. 分析方俊朗phone.E01检材,分析应用的壳代码逻辑,其解密密钥由3个字符串片段混淆拼接而成。请通过静态分析,还原用于解密的3个片段拼接合并后的完整密钥明文。[答案格式:Ab6de_a8bc4d_a5b_345d]
这个就在上一题的代码上面
第一部分
对 U2gzbGxf 解码 base64 得到 Sh3ll_
第二部分
对{93, 33, 112, 117, 34, 99, 78, 90}每个字节异或 17 得到L0ad3r_K
第三部分
"!4202_y3").reverse().toString();
反转!4202_y3 得到3y_2024!
最终结果
<span class="ne-text">Sh3ll_L0ad3r_K3y_2024!</span>

13. 接上题,当选手尝试使用frida-dexdump等通用脱壳工具动态附加时,应用会立刻闪退。请分析该逻辑,写出该线程触发进程自杀所调用的完整Java系统方法签名。[答案格式:abcd.abcd.Abcdabc.abcd]
就在上一题代码上面
显示被检测到自我摧毁,退出
Log.e(TAG, "FATAL: Tracer detected! Self-destructing!");
System.exit(0);

java.lang.System.exit
java.lang是 Java 语言的核心包
所有 Java / Android 程序都自动带它
14. 分析方俊朗phone.E01检材,方俊朗使用其内部通联工具时,共加入过几个群?[答案格式:7]
这个其实在照片可以看出来是俩

15. 分析方俊朗phone.E01检材,方俊朗通过物联网设备漏洞,共获得多少用户信息?[答案格式:10]
这个肯定先看看数据库都有什么**(打开方式与密码获取和手机取证那里一样)**
浏览聊天记录发现被加密****AES-256-CBC(见第 20 题)

让 ai 写一个脚本解密
import base64
import re
from Crypto.Cipher import AES
enc_key_b64 = "bGx3iDfEn4O5kW+2hf0E594C+jcyE1aujg0RIE5DPMM="
enc_iv_b64 = "y1q+/i9a/85OsPry0WMffw=="
key = base64.b64decode(enc_key_b64)
iv = base64.b64decode(enc_iv_b64)
print(f"Key (hex): {key.hex()}")
print(f"IV (hex): {iv.hex()}")
print(f"Key length: {len(key)} bytes")
print(f"IV length: {len(iv)} bytes")
print()
def remove_pkcs7_padding(data):
if len(data) == 0:
return data
padding = data[-1]
if 1 <= padding <= 16 and all(b == padding for b in data[-padding:]):
return data[:-padding]
return data.rstrip(b'\x00').rstrip()
def try_decode_text(data):
cleaned = remove_pkcs7_padding(data)
try:
text = cleaned.decode('utf-8')
printable_count = sum(1 for c in text if c.isprintable() or c in '\n\r\t')
if len(text) > 0 and printable_count / len(text) > 0.8:
return text
except:
pass
return cleaned.hex()
with open('新建 文本文档.txt', 'r', encoding='utf-8') as f:
encrypted_lines = [line.strip() for line in f if line.strip()]
print(f"共 {len(encrypted_lines)} 行加密数据\n")
with open('decrypted_final.txt', 'w', encoding='utf-8') as out:
for i, line in enumerate(encrypted_lines, 1):
try:
cipher = AES.new(key, AES.MODE_CBC, iv)
encrypted_data = base64.b64decode(line)
decrypted = cipher.decrypt(encrypted_data)
result = try_decode_text(decrypted)
out.write(f"Line {i}: {result}\n")
if i <= 50 or i > 240:
print(f"Line {i}: {result}")
elif i == 51:
print("... (省略中间部分) ...")
except Exception as e:
error_msg = f"ERROR - {str(e)}"
out.write(f"Line {i}: {error_msg}\n")
print(f"Line {i}: {error_msg}")
print(f"\n解密完成!结果已保存到 decrypted_final.txt")
print(f"成功解密 {len(encrypted_lines)} 行数据")
32 个

16. 分析周文杰Image.zip检材,周文杰跟其犯罪团伙人员内部通联工具包名是?[答案格式:com.apt.app]
这个不多说了com.socialchat.social_chat_app

17. 分析周文杰Image.zip检材,内部通联app聊天数据库名称是?[答案格式:abc.db]
不多说social_chat.db

18. 分析周文杰Image.zip检材,内部通联app聊天数据库密码保存在哪个文件中?[答案格式:Abc.txt]
FlutterSharedPreferences.xml

19. 分析周文杰Image.zip检材,周文杰内部通联app聊天数据库密码是?[答案格式:123-abc]
s-dbw1776853545473Goo,解密一下

20. 分析周文杰Image.zip检材,内部通联app聊天数据使用的什么加密算法?[答案格式:ABCDEF]
{"enc_key": "yI0JZciWANMs+bKTuVM+LIjYKPDur2Z11R0X/YwzBA0=", "enc_iv": "ajPN2Pt4zFYG1dl9FrpK4Q=="}通过数据库提供的密钥,密文解码后是 32 字节,iv 解码后是 16 字节
** DES/3DES 的 CBC 模式 IV 固定是 8 字节,而这个的 IV 是 16 字节,这与 ****AES(128位分组)/CBC 模式**完全吻合,基本可以排除 DES/3DES。
由此可以确定是 AES-256-CBC(AES)

21. 分析周文杰Image.zip检材,内部通联app用户密码的盐值是?[答案格式:1234abcd]
a3f8d9c2e1b4h7g6k9m2n5p8q1r4t7w

22. 分析周文杰Image.zip检材,记录周文杰内部通联app登录密码提示的应用包名是?[答案格式:com.temp.app]
看一下 apk 分析,有个笔记本,看看数据库

看到提示,确定是提示应用com.jinghong.notebookkssjh

23. 分析周文杰Image.zip检材,内部通联app登录密码是?[答案格式:123abc]
上一道题已知****密码格式:2 字母+6 数字
密码 hash:5d85b77d7d6d1a76cd589c3ba21d1839b1dd28568e39f1d2facc3a1b7d2e8bcb
salt:a3f8d9c2e1b4h7g6k9m2n5p8q1r4t7w
那就可以进行爆破,然后****可以先试试手机取证的哈希逻辑——SHA256(hex SHA256(pwd+salt))
让 ai 写一个脚本,发现可以爆破出来
import hashlib
import string
import itertools
from concurrent.futures import ProcessPoolExecutor, as_completed
import multiprocessing
import time
target_hash = "5d85b77d7d6d1a76cd589c3ba21d1839b1dd28568e39f1d2facc3a1b7d2e8bcb"
salt = "a3f8d9c2e1b4h7g6k9m2n5p8q1r4t7w"
def crack_batch(args):
letter_pairs, target, salt_val = args
digits = '0123456789'
for letter_pair in letter_pairs:
for d1, d2, d3, d4, d5, d6 in itertools.product(digits, repeat=6):
password = letter_pair + d1 + d2 + d3 + d4 + d5 + d6
first_hash = hashlib.sha256((password + salt_val).encode()).hexdigest()
final_hash = hashlib.sha256(first_hash.encode()).hexdigest()
if final_hash == target:
return password
return None
def main():
letters = string.ascii_letters
all_letter_pairs = [''.join(combo) for combo in itertools.product(letters, repeat=2)]
num_workers = multiprocessing.cpu_count()
total_combinations = len(all_letter_pairs) * 1000000
print(f"[*] Target hash: {target_hash}")
print(f"[*] Salt: {salt}")
print(f"[*] Password format: 2 letters + 6 digits")
print(f"[*] Total combinations: {total_combinations:,}")
print(f"[*] Using {num_workers} CPU cores")
print(f"[*] Starting brute-force...\n")
chunk_size = max(1, len(all_letter_pairs) // num_workers)
chunks = []
for i in range(0, len(all_letter_pairs), chunk_size):
chunks.append(all_letter_pairs[i:i + chunk_size])
tasks = [(chunk, target_hash, salt) for chunk in chunks]
start_time = time.time()
completed_pairs = 0
with ProcessPoolExecutor(max_workers=num_workers) as exec