录音划分三大考点范围

APK 静态检测/风险报告

部署与基本操作

Docker部署

1
2
docker pull opensecurity/mobile-security-framework-mobsf
docker run -it -p 8000:8000 opensecurity/mobile-security-framework-mobsf
  • 默认登录账号:mobsf/mobsf

报告结构必须能看懂(这是核心考点,不是操作)

示例报告:https://pdfhost.io/v/6MK1oLU4y_MobSF_Sta%EE%80%80tic_Analysis_Report_Shar%EE%80%80eIT.pdf

  • App Security Score / Average CVSS Score:综合评分,分数越低风险越高,报告会标注等级(如 CRITICAL RISK / HIGH RISK)
    -

  • APP COMPONENTS:Activities、Services、Receivers、Providers 各自的总数,以及 Exported 数量——这一块和第3讲AllSafe里”不安全的服务”考点是同一个知识点:exported=true 的组件能被外部应用或adb直接调起,是攻击面
    -|435x357

  • APPLICATION PERMISSIONS:每条权限都标了等级——normal(普通,如 VIBRATE、ACCESS_NETWORK_STATE)、dangerous(危险,如 CAMERA、RECORD_AUDIO、READ_CONTACTS)、signature(签名级)。给你一个权限名,要能判断它属于哪一级、对应什么隐私/安全风险

  • CERTIFICATE INFORMATION:签名算法是否过时(比如SHA1withRSA存在碰撞风险)、是否v1/v2/v3签名齐全
    |534x251

  • Code Analysis:硬编码密钥、不安全加密API调用等——这块和作业3的”弱加密漏洞”是同一套逻辑,MobSF本质上是把你手动分析的东西自动扫出来

    给你截图,要能判断的问题类型

  • “这个风险条目属于Permission类还是Service类”

  • “为什么这个APP的Security Score这么低”

  • “Exported Activity为什么是风险点”

AllSafe漏洞靶场

靶场基本信息

  • 名称:Allsafe,GitHub:t0thkr1s/allsafe
  • 特点:不像CTF套壳题,更贴近真实APP的漏洞场景
  • 安装:adb install allsafe.apk

Frida环境搭建(录音反复强调的部分,必须背熟)

  1. Kali装frida客户端:pip install frida,frida --version验证版本
  2. 手机/模拟器端要装对应架构的frida-server(查看架构:adb shell getprop ro.product.cpu.abi)——版本必须和客户端一致,这是录音里明确点出的坑
  3. push到手机:adb push frida-server /data/local/tmp/
  4. adb shellsuchmod 755 frida-server./frida-server &——&让进程后台运行,shell断开后不会被杀掉

Hook代码万能公式(所有hook题的核心结构)

1
2
3
4
5
6
7
8
Java.perform(function () {
var 目标类 = Java.use("完整包名.类名");
目标类.目标方法.implementation = function (参数) {
// 记录/篡改逻辑
var result = this.目标方法(参数); // 可选:先调用原方法
return result; // 或直接返回篡改后的假值
};
});

Java.use()拿到目标类,.implementation =替换方法体——这是Frida hook Java方法的万能公式,几乎每道hook题都是这个结构

Root检测绕过Hook代码分析(含RootBeer类)

1
2
3
4
5
6
7
Java.perform(function () {
var RootBeer = Java.use("com.scottyab.rootbeer.RootBeer");
RootBeer.isRooted.implementation = function () {
console.log("[HOOK] isRooted() intercepted");
return false;
};
});

记RootBeer字符串

问题:

  1. 这段代码在干什么?对应AllSafe靶场里的哪个漏洞类型?

    Hook了RootBeer类的isRooted()方法,强制让它的返回值永远是false,对应AllSafe的Root Detection(Challenge 16)。

  2. 为什么直接return false就能绕过检测,而不需要知道RootBeer内部到底检测了什么(su文件、busybox、build tags等)?

    因为Hook拦截的是方法的最终返回值,不管内部逻辑多复杂,最后都要汇总成一个布尔值返回给调用方。只要在这个”出口”上做手脚,就能一次性绕过所有内部检测逻辑,不需要逐一理解每种检测手段。

  3. 如果把return false改成return true,运行结果会怎样?

    会让APP始终认为设备已root,如果APP有”检测到root就限制功能”的逻辑,反而会触发这个限制


弱加密Hook代码分析(含WeakCryptography类)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Java.perform(function () {
var WeakCryptography = Java.use("infosecadventures.allsafe.challenges.WeakCryptography");

WeakCryptography.encrypt.implementation = function (value) {
console.log("[WEAK CRYPTO] Hardcoded KEY: " + ____________); // 空1
var result = this.encrypt(value);
return result;
};

WeakCryptography.md5Hash.implementation = function (text) {
var result = ____________; // 空2
console.log("[WEAK CRYPTO] md5Hash output: " + result);
return result;
};
});[^1]


问题:

  1. 空1、空2分别应该填什么?

    WeakCryptography.KEY.value读取类的静态字段KEY的值 ,this.md5Hash(text)调用原始方法拿到真实计算结果,再打印出来

  2. 这段代码揭示了几种”弱加密”的具体表现?分别是什么?

    硬编码密钥——加密密钥被直接写死在代码里的静态字段中,可以被hook直接读出
    弱哈希算法——用MD5做敏感数据处理。

  3. 为什么用MD5做密码存储被认为是不安全的?

    MD5存在碰撞成本低、已有现成彩虹表的问题,可以通过预计算的哈希表快速反查出原文


弱随机数Hook代码分析(含randomNumber方法)

1
2
3
4
5
6
7
8
Java.perform(function () {
var WeakCryptography = Java.use("infosecadventures.allsafe.challenges.WeakCryptography");
WeakCryptography.randomNumber.implementation = function () {
var fake = "1337";
console.log("[WEAK CRYPTO] randomNumber() called -> returning fixed value: " + fake);
return fake;
};
});

问题:

  1. 这段代码和题目一的Hook套路相比,有什么本质区别?(提示:题目一是绕过检测,这题是什么目的?)

    题目一是验证”检测类”漏洞能否被绕过(篡改布尔判断结果);这题是验证”随机数生成本身是否可预测”,通过hook把原本应该”不可预测”的方法强行改成固定值,来演示如果攻击者能预测这个随机数生成逻辑会有什么后果。

  2. 如果这个randomNumber()原本是用来生成短信验证码或者Token的,固定返回值会带来什么安全后果?

    攻击者可以提前预测出下一个验证码/Token的值,从而绕过身份验证或话费/会话劫持


弱密码加密结合

  • 考点1(硬编码密钥):WeakCryptography.KEY.value能被直接读出来,说明加密密钥是写死在代码里的静态字段,
  • 考点2(弱哈希算法):MD5本身是不可逆的哈希算法,但用MD5做密码存储属于弱加密实践,因为MD5碰撞成本低、可被彩虹表暴力破解,
  • 考点3(弱随机数):randomNumber()被hook后返回固定值"1337",说明原本这个方法生成的随机数可预测,导致依赖随机数的安全机制可以被预测
  • 考点4:你的运行结果截图里能看到 this.encrypt(value) **先调用原始方法再返回,Hook不是替换掉原逻辑,而是在执行前后插入自己的监控/篡改代码

综合分析题Hook代码分析(含checkPIN类)

1
2
3
4
5
6
7
8
9
10
Java.perform(function () {
var MainActivity = Java.use("com.example.target.MainActivity");
var checkPin = MainActivity.checkPin;
checkPin.implementation = function (input) {
send("checkPin called with: " + input);
var result = checkPin.call(this, input);
send("original result: " + result);
return true;
};
});

问题:

  1. 这是针对什么类型的验证逻辑做的Hook?

    针对PIN码校验逻辑的绕过。

  2. checkPin.call(this, input)这一行的作用是什么?去掉这一行,对最终绕过效果有没有影响?

    这一行是先调用原始的checkPin方法,拿到真实的校验结果并通过send()打印出来,方便调试观察原始逻辑到底返回了什么。
    去掉这一行不影响最终绕过效果,但会丢失”原始校验到底对不对”这个调试信息

  3. 为什么最后不管result是什么,都要return true?

    因为不管用户输入的PIN对不对,只要最后统一返回true,APP就会认为校验永远通过,从而达到绕过PIN码验证的目的,篡改方法出口

结合你实际做过的题,按漏洞类型整理(19项里考过的这几个是重点):

漏洞类型 核心考点 Hook/绕过方式
Root检测(Challenge 16) RootBeer.isRooted() 只需要hook最终布尔返回值 return false
弱加密(Weak Cryptography) 三个子考点: ①硬编码密钥(WeakCryptography.KEY.value可直接读出) ②MD5弱哈希(可碰撞/彩虹表) ③弱随机数(randomNumber()返回值可预测,如固定值1337) hook encrypt/md5Hash/randomNumber 三个方法
不安全的服务 Service被导出(exported=true),能被adb直接startservice调起 adb shell am startservice -n 包名/Service类名
PIN绕过 Base64解码硬编码值,如NDg2Mw==4863 静态分析jadx即可,不一定要hook
WebView漏洞 XSS注入 <script>alert('12345')</script>;本地文件读取 file:///etc/hosts 说明WebView未禁用JS或未限制file协议
Firebase未授权访问 URL后加 /secret.json 直接读取数据库内容 说明Firebase规则未设置鉴权
SQL注入 payload 1' or 1=1 -- 工具drozer

给你一段Java代码判断漏洞类型,思路(考试大概率这么问):

  1. 看有没有硬编码的KEY/密码字符串 → 弱加密
  2. 看有没有isRooted/isDebuggerConnected这类布尔返回的检测方法 → 检测类绕过
  3. 看有没有WebView相关设置(setJavaScriptEnabled)→ WebView漏洞
  4. 看Service/Activity的android:exported属性 → 组件导出风险

IDA动态调试APK(第4讲,和so文件逆向结合)

  • 前提:手机Root + AndroidManifest.xml中debuggable=true
  • adb shell am start -D -n "包名/Activity" 启动调试模式
  • adb forward tcp:5005 jdwp:<pid> 转发Java层调试端口
  • Native层需要push对应架构的android_server,chmod 755后运行,再adb forward tcp:23946 tcp:23946

apktool/apksigner工具链(实验一二用到的)

1
2
3
java -jar apktool_2.6.0.jar d xxx.apk -o output_dir     # 反编译
java -jar apktool_2.6.0.jar b output_dir -o new.apk # 重打包
java -jar apksigner.jar sign --ks key1.jks new.apk # 签名(不签名装不上)
  • so文件分析要用IDA Pro,JNI函数命名规则:Java_包名_类名_方法名,靠这个规则在IDA里定位Native入口

无线渗透测试

WLAN帧结构基础(填空高发)

  • 帧分3类:管理帧、控制帧、数据帧(数据帧无子类型)
  • 控制帧3种子类型:RTS(请求发送)、CTS(清除发送)、ACK(确认)
  • FCS校验序列:32bit CRC

监控模式命令链(和实验四完全对应)

1
2
3
airmon-ng check kill          # 杀掉占用网卡的进程
iwconfig wlan0 mode monitor # 切换监听模式
airmon-ng start wlan0 # 启动监听

Bettercap三大攻击方式(录音点名必考)

攻击方式 命令 原理
ARP欺骗 set arp.spoof.targets <IP>arp.spoof on 伪造ARP响应,让目标流量转发经过攻击机
HTTP/HTTPS代理 http.proxy on / https.proxy on 中间人解密流量,https需要自签名证书,客户端要手动信任CA才能看到明文——你作业4做的就是这个,双机+kali+装CA证书流程
DNS欺骗 set dns.spoof.domains *set dns.spoof.ip <IP>dns.spoof on 伪造DNS响应,把域名解析到攻击者指定IP
  • 考点1:为什么必须先手动信任bettercap生成的CA证书才能看到明文——因为HTTPS的信任链依赖客户端系统信任的CA列表,bettercap的证书是自签名的,不在系统信任列表里,浏览器/APP会拒绝或警告;手动安装到手机的受信任凭据里之后,系统才会认为这个”中间人”证书合法,相当于让手机主动接受了一个不受官方CA机构认证的证书

  • 考点2:这本质上是中间人攻击(MITM)——bettercap伪装成网关,让手机的流量都先经过它解密再转发,这也是为什么必须和手机在同一个子网/网段

  • 考点3:抓到淘宝、百度这类真实HTTPS网站的流量说明——只要客户端愿意信任你的CA证书,HTTPS本身并不能防御中间人攻击,HTTPS防的是”网络路径上被动窃听”,而不是”客户端主动信任了错误的证书”这种场景,这是很多人容易搞混的概念,大题里如果问”为什么装了证书HTTPS还能被破解”,答案就在这
    给一条命令/脚本判断作用的思路

  • 看模块名前缀:arp.* → ARP欺骗;http.proxy/https.proxy → 代理拦截;dns.spoof.* → DNS欺骗

  • 顺序不能乱的原因:比如必须先 net.probe on 发现目标,再 set arp.spoof.targets,最后才能 arp.spoof on——没确定目标就直接欺骗会失败

  • HTTPS代理为什么装了CA证书还能被破解:HTTPS防的是被动窃听,不防客户端主动信任了错误的证书,这是中间人攻击(MITM)的本质,和你作业4的结论完全一致

**aircrack-ng字典攻击

1
aircrack-ng -w password.txt ctf.pcap
  • 前提是pcap里必须抓到完整的四次握手包(4-way handshake)
  • 为什么用字典而不暴力枚举:WPA-PSK的PBKDF2迭代次数高,暴力破解代价太大

隐藏SSID识别原理(简答高发)

  • 路由器只是不在信标帧(Beacon frame)里广播SSID,但客户端连接时的Probe Request/Response帧仍会携带SSID明文,用Wireshark抓包对比就能发现

[^1]:

实验

实验一:APK反编译/签名

  • apktool反编译命令:java -jar apktool_2.6.0.jar d xxx.apk -o output_dir
  • 重新打包命令:java -jar apktool_2.6.0.jar b output_dir -o new.apk
  • 为什么修改后的APK装不上——因为没签名,Android要求APK必须签名才能安装
  • apksigner签名命令:java -jar apksigner.jar sign --ks key1.jks --ks-key-alias <alias> new.apk
  • jks密钥库的作用:存放签名用的公私钥对
  • AndroidManifest.xml中关键字段(package、权限声明、组件导出属性 exported)
  • 对着 DDCTF-Easy 和 AliCrackme_1 这类 crackme,大概率会问:smali代码里哪一行是判断逻辑(比如if-eq/if-nez跳转),改哪个跳转能绕过校验

实验三:HOOK动态分析(Frida,rps.apk / ctf.py)

这是录音里花最多篇幅强调的部分,几乎是逐字对应实验步骤在划重点:

环境搭建流程(务必背熟,原文步骤基本就是考点):

  1. Kali装frida:pip install frida,frida --version验证安装
  2. 手机端(模拟器)装 frida-server,要选对应架构(真机arm/arm64,模拟器x86/x86_64)——版本要和frida客户端对上,这点录音里反复强调
  3. adb push 把frida-server传到手机
  4. adb shellsuchmod 755./frida-server &——&的作用是让进程后台运行,断开shell后不会被杀掉,这个考点原文明确点出来了

ctf.py 代码解读(逐行讲解,这是重点中的重点):

1
2
3
4
5
6
7
8
9
10
11
12
Java.perform(() => {   //确保代码在Java虚拟机环境准备好之后再执行,是Frida hook Java代码的固定写法
const MainActivity = Java.use('com.example.seccon2015.rock_paper_scissors.MainActivity');
const onClick = MainActivity.onClick;
onClick.implementation = function (v) { //:用自定义函数替换`onClick`的原始实现
send('onClick'); // 向Python端发消息,确认Hook触发
onClick.call(this, v); // 调用原始onClick逻辑,不破坏正常流程
this.m.value = 0; // Hook后修改成员变量m
this.n.value = 1; // Hook后修改成员变量n
// this.cnt.value = 999; // 被注释掉的部分——步骤8要求删掉这行
console.log('Done:' + JSON.stringify(this.cnt)); //打印当前`cnt`变量,确认篡改是否生效
};
});
  • 考点1:Java.use()获取类、.implementation = 替换方法实现,这是Frida Hook Java方法的标准套路,必须能讲清每一步作用
  • 考点2:为什么要先onClick.call(this, v)再改值——因为要保留原逻辑执行后再篡改结果,不能直接跳过原方法
  • 考点3:this.m/this.n/this.cnt 对应的是靶场APP(rock_paper_scissors)里Java源码的成员变量
  • 思考题:用Frida抓取任意APP通信数据——结合Bettercap做HTTPS中间人代理,配合手机安装自签名CA证书来解密流量

填空题

1. 在Kali上安装frida客户端的命令是 pip install ______,验证安装成功用 frida ______

答案:frida;–version

2. frida-server必须选择和手机/模拟器对应的______,常见的有真机的arm/arm64,模拟器的x86/x86_64。

答案:架构(CPU architecture)

3. 启动frida-server的完整命令链:adb shell______chmod 755 frida-server______

答案:su;./frida-server &

4. 在frida-server的启动命令末尾加 & 的作用是 ______。

答案:让进程在后台运行,这样shell断开连接后该进程不会被杀掉(结束/挂断)

5. Frida Hook Java方法的标准公式是:先用 ______ 获取目标类,再用 ______ 替换目标方法的实现。

答案:Java.use("完整包名.类名");.implementation = function(...) {...}


实验四:无线网络分析(airmon-ng / wireshark / aircrack-ng)

命令链(原文步骤,直接是考点):

1
2
3
4
5
airmon-ng                      # 启动查看网卡
airmon-ng check kill # 杀掉占用网卡的进程
iwconfig wlan0 mode monitor # 切换监听模式
airmon-ng start wlan0 # 开启监听
wireshark # 抓包分析
  • 考点1:为什么要check kill——避免NetworkManager等进程抢占网卡导致监听失败
  • 考点2:隐藏SSID的原理——路由器只是不在信标帧里广播SSID,但客户端连接时的Probe Request/Response帧里仍然会携带SSID明文,所以用Wireshark抓包对比”主机显示的SSID”和”Wireshark抓到的SSID”就能发现隐藏网络(这是实验目的里明确写的原理,很可能就是简答题
  • 考点3:破解思考题命令
1
aircrack-ng -w password.txt ctf.pcap

这条命令是用password.txt作为密码字典,对ctf.pcap抓包文件里的WPA/WPA2握手数据进行字典攻击破解,原理是把字典里每个候选密码通过PBKDF2算法和抓到的四次握手包做比对运算,匹配上就是真实密码。
如果破解不成功,最应该先检查:
①pcap文件里是否抓到了完整的四次握手包
密码是否真的在字典里

  • 考点4:“为什么要提供密码字典而不能暴力枚举”–(WPA-PSK的PBKDF2迭代次数高,暴力破解代价大,字典攻击更现实)

填空题

12. 进入监听模式的命令链:airmon-ng check ______iwconfig wlan0 mode ______airmon-ng ______ wlan0

答案:kill;monitor;start

13. 执行airmon-ng check kill的目的是 ______。

答案:杀掉可能占用无线网卡的进程(如NetworkManager、wpa_supplicant),避免它们抢占网卡导致监听模式启动失败或被自动切回managed模式

14. 破解WPA/WPA2密码的命令是:aircrack-ng -w ______ ______

答案:password.txt(字典文件);ctf.pcap(抓包文件)

15. 使用aircrack-ng破解握手包的前提条件是,pcap文件里必须抓到完整的 ______。

答案:四次握手包(4-way handshake)