本题所需知识点
ADB
当我们在PC上启动adb进程的时候,adb进程会在本地生成一对秘钥 adbkey 和 adbkey.pub根据弹框提示 The computer’s RSA key fingerprint is:xxx ,可以看出是一对RSA算法的秘钥,其中公钥是来发送给android设备的.
当你执行 adb shell 的时候,adb进程会将PC上的adbkey.pub发送给android设备;这个时候如果android上已经保存了这台PC的adbkey.pub ,则连接成功,如果没有保存则会出现弹框,当你点击允许之后android设备就会保存PC的 adbkey.pub
手机中会存储adb连接的公钥,要知道adb连接过几个设备只需要找到adb存储的公钥有几个就行
adb key存放位置:
android设备 : /data/misc/adb/adb_keys // 将PC的adbkey.pub 拷贝并且重命名而来
windows: C:\Users\Administrator.android\adbkey
Linux: ~/.android/adbkey
每行存储一个key
SIM卡
Android手机的SIM卡使用记录一般保存在data分区的telephony.db文件中,该文件也是SQLite数据库。表“sim_info”会记录使用过的SIM卡的ICCID、手机号等信息。
IOS的SIM卡使用记录一般保存在CellularUsage.db文件中,SIM卡历史记录保存在表“subscriber_info”中。
对盗取敏感信息类APP分析的一些小认识
这类APP将获取到的敏感信息打包成文件通过网络传输,在jadx中分析的时候可用查找关键词:
file:涉及到文件的操作,一定会涉及到FileInputStream、FileoutputStream两个函数
url、email:涉及网络传输,必须得有一个目的地,可能是url,也有可能是邮箱
在File相关函数中发现变量s0、u0,这两个变量是加密的,实际上能看到很多变量的值是加密的,说明APP作者不想让别人轻易看到这些内容,同时这些加密变量大量出现在FileOutputStream函数中
加解密在java中通常会引入Cipher
这个包,我们查找cipher这个包的用例,发现b.b.a下a函数
在打包文件的过程中发现多个该函数的用例,并调用了加密变量
在CyberChef尝试解密这些加密变量,解密成功
组织层级分析
7-10题是对手机加密容器data中的名单数据.xlsx进行层级的分析
观察表的结构就会发现:
被邀请人与邀请人构成指向关系
“邀请人”的值存在重复,“邀请人”与“姓名”也存在重复。
每行”姓名“都对应一个非空的”邀请人“值。所以root结点不是简单的无邀请人,而且表中可能不只有一个根结点。
这里考虑到使用有向树(https://baike.baidu.com/item/有向树/6919420)来处理数据
我采用pandas库来读取excel中的数据,networkx库来便捷化实现有向图
# 作者:WelK1n
# 时间:2024/10/14
import pandas as pd
import networkx as nx
# 读取 Excel 数据
file_path = "J:/名单数据.xlsx" # 请替换为实际的文件路径
data = pd.read_excel(file_path)
# 构建有向图
G = nx.DiGraph()
# 读取xlsx中的关键数据并创建图结点
for index, row in data.iterrows():
if pd.notna(row['邀请人']): # 确保邀请人不为空
name = row['姓名']
inviter = row['邀请人']
phone = row['手机号']
inviter_phone = row['邀请人手机号']
# 添加节点(确保唯一性)
G.add_node(phone, label=name) # 姓名对应手机号
G.add_node(inviter_phone, label=inviter) # 邀请人对应邀请人手机号
# 添加边
G.add_edge(inviter_phone, phone) # 从邀请人到被邀请人
# 递归函数来打印总层级关系树,统计层级和节点信息
def print_tree(node, graph, level=0, level_info=None):
indent = " " * (level * 4) # 控制缩进
name = graph.nodes[node]['label']
children = list(graph.successors(node))
child_count = len(children) # 子节点数量
result = f"{indent}- {name} (子节点数: {child_count})\n" # 打印当前节点和子节点数量
# 统计层级信息
if level not in level_info:
level_info[level] = {'nodes': [], 'leaf_count': 0, 'children_count': {}}
level_info[level]['nodes'].append(name) # 添加当前节点到层级信息
level_info[level]['children_count'][name] = child_count # 记录节点的子节点数量
if len(children) == 0: # 如果没有子节点,则为叶子节点
level_info[level]['leaf_count'] += 1 # 增加叶子节点计数
for neighbor in children:
result += print_tree(neighbor, graph, level + 1, level_info) # 递归调用并累加结果
return result
# 找到所有根节点(没有入边的节点)
root_nodes = [node for node in G.nodes if G.in_degree(node) == 0]
# 保存总层级关系树为“总层级关系树.txt”
with open('总层级关系树.txt', 'w', encoding='utf-8') as f:
for root in root_nodes:
f.write(print_tree(root, G, level_info={}))
# 统计层级数据
level_data = {}
for root in root_nodes:
level_info = {}
print_tree(root, G, level_info=level_info) # 获取每个根节点的层级信息
for level, info in level_info.items():
if level not in level_data:
level_data[level] = {'nodes': [], 'leaf_count': 0, 'children_count': {}}
level_data[level]['nodes'].extend(info['nodes']) # 添加该层所有节点
level_data[level]['leaf_count'] += info['leaf_count'] # 统计叶子节点总数
level_data[level]['children_count'].update(info['children_count']) # 统计每个节点的子节点数量
# 保存层级数据分析为“层级数据分析.txt”
with open('层级数据分析.txt', 'w', encoding='utf-8') as f:
for level in sorted(level_data.keys()):
# 对每个节点的下线(子节点)数量按降序排序
sorted_children = sorted(level_data[level]['children_count'].items(), key=lambda x: x[1], reverse=True)
nodes_info = [f"{node} (子节点数: {count})" for node, count in sorted_children]
nodes = ", ".join(nodes_info)
leaf_count = level_data[level]['leaf_count']
f.write(f"层级 {level + 1}: 节点数 = {len(level_data[level]['nodes'])},子节点数量 = {sorted_children}, 叶子节点数量 = {leaf_count}, 节点 = [{nodes}]\n")
# 5. 递归函数,从被邀请人出发向上查找邀请人,并打印层级关系
def search_inviter(node, graph, level=0):
indent = " " * (level * 4) # 控制缩进
name = graph.nodes[node]['label']
result = f"{indent}- {name}\n" # 打印当前节点
# 获取邀请人
parents = list(graph.predecessors(node)) # 邀请人在有向图中是前驱节点
if len(parents) > 0: # 如果有邀请人
inviter = parents[0]
result += search_inviter(inviter, graph, level + 1) # 递归调用
return result
# 找到所有被邀请人(即存在入边的节点)
invited_nodes = [node for node in G.nodes if G.out_degree(node) > 0]
# 保存被邀请人视角的层级关系为“被邀请人视角的层级关系.txt”
with open('被邀请人视角的层级关系.txt', 'w', encoding='utf-8') as f:
for invited in invited_nodes:
f.write(search_inviter(invited, G))
print("ok!")
生成两个txt文件:
总层级关系树.txt:树形记录上下级关系
层级数据分析.txt:针对不同层级,统计具体的数据。
节点数:统计本层级共有多少个节点
子节点数量:统计每层每个节点有多少子节点,就是邀请人有多少个被邀请人/下线,我这里采用了sort排序来降序输出子节点数量,即下线数量最多的人优先靠前。
叶子节点数量:我认为有分析价值,意味着一个人有几个没有下线的下线
节点:输出该层级的所有节点
被邀请人视角的层级关系.txt:从被邀请人视角出发,去看每一个被邀请人的上级,以及上级的上级
题目解析
检材处理
该镜像实际上是tar文件,使用压缩软件打开,可以直接解压出来
1.分析手机检材,请问此手机共通过adb连接过几个设备?[标准格式:3]
2
2.分析手机检材,机主参加考试的时间是什么时候?[标准格式:2024-06-17]
2024-08-23
3.分析手机检材,请问手机的蓝牙Mac地址是多少?[标准格式:12:12:12:12:12:12]
48:87:59:76:21:0f
4.分析手机检材,请问压缩包加密软件共加密过几份文件?[标准格式:3]
6
找到压缩包加密软件FileCompress,apk丢jadx分析
doZipSingleFileWithPassword()函数给压缩包设置密码1!8Da9Re5it2b3a.
X-ways浏览递归,搜索filecompress
用刚刚找到的密码成功解压这些加密压缩包
5.分析手机检材,请问机主的另外一个155的手机号码是多少?[标准格式:15555000555]
15599555555
6.分析手机检材,其手机存在一个加密容器,请问其容器密码是多少。[标准格式:abc123]
7.分析手机检材,接上问,其容器中存在一份成员名单,嫌疑人曾经误触导致表格中的一个成员姓名被错误修改,请确认这个成员的原始正确姓名?[标准格式:张三]
加密容器,文件大小过滤mod512,data就是加密容器
需要用TC模式解密
llzp.jpg放在这里就很可疑,实际上也是隐写了xlsx文件,但我分离出来的存在问题。希望大佬评论区讲解一下
还有一个取巧的办法(也容易弄巧成拙),office类软件都有一个记忆功能,打开office文档后会定位到上一次操作过的位置
这里打开后就是2414行,搜索陆陆的手机号发现实际叫陆俊梅
恢复表后,使用上文中的python脚本做层级分析就可以了
8.分析手机检材,接上题,请确认该成员的对应的最高代理人是谁(不考虑总部)?[标准格式:张三]
去看“被邀请人视角的层级关系.txt”
9.分析手机检材,请确认在该组织中,最高层级的层次是多少?(从总部开始算第一级)[标准格式:10]
12级
10.分析手机检材,请问第二层级(从总部开始算第一级)人员最多的人是多少人?[标准格式:100]
这道题的题目有点歧义,我认为是问第二层级下线人员最多的人是有多少个下线,所以这里答60人
11.分析手机检材,机主共开启了几款APP应用分身?[标准格式:3]
找到“隐空间”的包,里面有个fenshen.db(复现的时候龙信的工具到期了,没法直接贴图出来)
存在两个分身
12.分析手机检材,请问机主现在安装了几款即时通讯软件(微博除外)?[标准格式:]
除微博外两个
13.分析手机检材,请问勒索机主的账号是多少(非微信ID)?[标准格式:AB123CD45]
1836042664454131712
14.分析手机检材,接上问,请问机主通过此应用共删除了多少条聊天记录 ?[标准格式:2]
由上图,1条
15.分析手机检材,请问会盗取手机信息的APP应用包名是什么?[标准格式:com.lx.tt]
com.lxlxlx.luoliao
16.接上题,请问该软件作者预留的座机号码是多少?[标准格式:40088855555]
40085222666
w0和x0单独直接解密是不行的,查看用例后发现是连接在一起,解密后那一串数字应该就是电话号码了
17.接上题,恶意程序偷取数据的收件邮箱地址的gmail邮箱是多少?[标准格式:lx@gmail.com]
1304567895@gmail.com
18.接上题,恶意程序偷取数据的发件邮箱地址是多少?[标准格式:lx@gmail.com]
temp1234@gmail.com
定位package b.b.a.g;
查看aVar.a(str, "见附件", arrayList, arrayList2);
,该函数是发送邮件函数
加密的变量d解密后
19.接上题,恶意程序偷取数据的发件邮箱密码是多少?[标准格式:abc123]
qwer123456
加密变量e解密后就是密码
20.接上题,恶意程序定义收发件的地址函数是什么?[标准格式:a]
b