// RESEARCH_TRANSMISSION ID: CVE_2020_25279

CVE-2020-25279 分析复现

三星手机中的基带组件存在缓冲区溢出漏洞,通过异常的SETUP消息可导致任意代码执行

BEGIN_PAYLOAD 20260822

漏洞概要

  • 漏洞类型:缓冲区溢出
  • 危害:RCE
  • 三星手机中的基带组件存在缓冲区溢出漏洞,通过异常的SETUP消息可导致任意代码执行

三星Exynos基带

手机架构

来看一下手机架构

image-20260822104053694

左下红色框住的芯片是基带芯片,这是本文章研究的对象

基带

如下图简要概述了连接处理器(CP)和应用处理器 (AP)之间的通信过程。

AP运行在linux内核上,运行Android OS,开启了各种程序和服务与CP进行交互。

  • 无线接口层守护程序(RILD)是一个运行在AP上的程序,为调制解调器提供一个接口
  • CP引导守护程序(CBD)在基带处理器中加载固件镜像
  • 远程文件系统(RFS)存储调制解调器的配置,允许调制解调器访问Android OS

image-20260822104246910

三星的基带软件(Shannon)在ARM Cortex-R7 CPU上运行。

Cortex-R7介绍

Cortex-R7极大扩展了R系列内核的性能范围,时钟速度可超过1GHz,性能达到3.77DMIPS/MHz。Cortex-R7上的11级流水线现在增强了错误管理功能,以及改进的分支预测功能。多核配置也有多种不同选项:锁步、对称多重处理和不对称多重处理。Cortex-R7还配有一个完全集成的通用中断控制器(GIC)来支持复杂的优先级中断处理。

image-20260822105157023

Shannon系统

Shannon是一个闭源的实时操作系统,运行在ARM Cortex-R7上。

Shannon在平台抽象层(PAL)中实现了其基本功能,这一层包含内存管理、任务同步等底层功能。PAL可以被视为一个包含小型libc库的微内核。

Shannon的PAL实现了一个任务调度器,该调度器根据Shannon RTOS的约束条件对任务执行优先级进行排序。

GSM

在Amat Cama的A Walk with Shannon演讲中,讲述了某个版本Shannon系统中存在漏洞

https://github.com/msuiche/OPCDE/blob/master/2018/Kenya/Amat%20Cama%20-%20A%20Walk%20With%20Shannon-%20A%20walkthrough%20of%20a%20PWN2OWN%20Baseband%20exploit.pdf

基带中的这些漏洞源于部分消息中允许的可变数据长度,尤其标签-长度-值(TLV)格式。TLV允许发送方决定字段的长度,这个长度可以”如任意”长,由于定义长度可用的位数有限,所以通常会有界限

image-20260822111856082

GSM呼叫流程

GSM呼叫建立过程:

  1. 移动台(手机)通过向基站发送一个“告警”消息来发送呼叫。该消息包含了被叫方的电话号码。
  2. 基站(BS)将该告警消息发送给移动交换中心(MSC),以便联系到对方并路由呼叫。
  3. 如果被叫方处于可用状态并且路由正确,移动交换中心会向基站发送一个”呼叫进行中”的消息,然后基站会向手机发送一个确认消息。
  4. 然后,移动交换中心(MSC)向基站发送一个“建立”消息,其中包含被叫方的电话号码。
  5. 基站将该“建立”消息发送给手机,然后手机向基站发送一个确认消息。
  6. 此时,呼叫被视为“已连接”,手机和被叫方可以开始通信了。

视频

在分析之前接下来先看如下视频:

固件下载

https://samfw.com/firmware/SM-G973F/PAK

找到版本为G973FXXU3ASG8,下载包含 CP 文件的对应固件包

我这里保存好了,进行分享

https://1024terabox.com/s/1Wg5G2CMMUwSSEqdEAYSm4Q

image-20260822004534152

也可以直接从ShannonFirmware仓库,得到对应文件

https://github.com/grant-h/ShannonFirmware/raw/master/modem_files/CP_G973FXXU3ASG8_CP13372649_CL16487963_QB24948473_REV01_user_low_ship.tar.md5.lz4

FirmWire

https://github.com/FirmWire/FirmWire

使用这个专门针对基带模拟的项目

根据项目的文档介绍

可以得到以下步骤:

1
2
3
git clone https://github.com/FirmWire/FirmWire.git
cd FirmWire
git clone https://github.com/FirmWire/panda.git

将CP_*那个文件复制到FirmWire目录下

然后构建镜像

1
docker build -t firmwire .

启动容器

1
2
3
4
5
export FIRMWIRE_DIR="$(pwd)"
docker run --rm -it \
-v "$FIRMWIRE_DIR:/firmwire" \
-w /firmwire \
firmwire:latest bash

FirmWire 动态运行时可以直接使用 CP 外层文件,这里简单手动拆包吧

1
2
3
4
5
6
7
CP=/firmwire/CP_G973FXXU3ASG8_CP13372649_CL16487963_QB24948473_REV01_user_low_ship.tar.md5.lz4
mkdir -p /firmwire/static/asg8
cd /firmwire/static/asg8
lz4 -d "$CP" cp.tar.md5
tar -xf cp.tar.md5
lz4 -d modem.bin.lz4 modem.bin
xxd -g1 -l 0xc0 modem.bin
1
2
3
4
5
6
7
8
9
10
11
12
13
root@18225d60a1a3:/firmwire/static/asg8# xxd -g1 -l 0xc0 modem.bin
00000000: 54 4f 43 00 00 00 00 00 00 00 00 00 00 00 00 00 TOC.............
00000010: 00 80 00 40 10 04 00 00 00 00 00 00 05 00 00 00 ...@............
00000020: 42 4f 4f 54 00 00 00 00 00 00 00 00 20 04 00 00 BOOT........ ...
00000030: 00 00 00 40 40 1e 00 00 d5 97 ad 57 01 00 00 00 ...@@......W....
00000040: 4d 41 49 4e 00 00 00 00 00 00 00 00 60 22 00 00 MAIN........`"..
00000050: 00 00 01 40 a0 79 54 02 3f b1 20 ef 02 00 00 00 ...@.yT.?. .....
00000060: 56 53 53 00 00 00 00 00 00 00 00 00 00 9c 54 02 VSS...........T.
00000070: 00 00 80 47 60 f6 5d 00 04 e5 29 07 03 00 00 00 ...G`.]...).....
00000080: 4e 56 00 00 00 00 00 00 00 00 00 00 00 00 00 00 NV..............
00000090: 00 00 60 45 00 00 10 00 00 00 00 00 04 00 00 00 ..`E............
000000a0: 4f 46 46 53 45 54 00 00 00 00 00 00 00 aa 07 00 OFFSET..........
000000b0: 00 00 00 00 00 56 08 00 00 00 00 00 05 00 00 00 .....V..........

这里使用官方的TOC截图,注意:偏移和官方不同

image-20260822010315313

TOC 项偏移 文件偏移 加载地址 大小
BOOT 0x20 0x420 0x40000000 0x1e40
MAIN 0x40 0x2260 0x40010000 0x25479a0
VSS 0x60 0x2549c00 0x47800000 0x5df660
NV(元数据项) 0x80 0 0x45600000 0x1000

提取出MAIN

1
dd if=modem.bin of=modem_main_asg8.bin bs=1 skip=$((0x2260)) count=$((0x25479a0)) status=progress

导入modem_main_asg8.bin到ida,处理器选择 ARM little-endian;把段加载地址设为TOC 的 0x40010000

image-20260822014800136

image-20260822014258721

动态分析

编译 Shannon ModKit

1
make -C modkit/shannon

afl++安装

1
apt-get install afl++

启动固件

1
./firmwire.py ./modem.bin

FirmWire支持自动识别调制解调器,进行解压,并选择合适的加载器和运行工具

1
./firmwire.py https://github.com/grant-h/ShannonFirmware/raw/master/modem_files/CP_G973FXXU3ASG8_CP13372649_CL16487963_QB24948473_REV01_user_low_ship.tar.md5.lz4

通过之前描述的GSM建立过程

异常的建立消息是基站发送给手机的,下面是生成呼叫建立的python代码,电话号码采用BCD格式进行编码

创建语料库

1
2
3
mkdir -p fuzz_input

python3 -c 'import binascii; print (binascii.unhexlify("303030303030303030303030303030303030030403339001214365C2870A0033").decode("latin-1"))'> fuzz_input/call_setup

解释这个字节流的各个部分:

  • 3030303030303030:被叫方的二进制编码的十进制(BCD)格式号码。
  • 3030303030303030:主叫方的二进制编码的十进制(BCD)格式号码。
  • OB:承载能力字段的长度。
  • 04:承载能力,表示这是一个呼叫建立消息。
  • 0333:音频承载能力,表示语音。
  • 9001:无线电信道要求,表示全速率业务信道。
  • 214365C287:IAS(ASCII)格式的被叫方号码,在这种情况下是214365。
  • OA:被叫方地址字段的长度。
  • 0033:被叫方地址类型,表示这是被叫方号码的扩展。
  • 33:被叫方号码的扩展,在这种情况下是3。

基带冷启动较慢,使用QEMU加速快照

这里选一个明显的地址0x4054df83 image-20260822015858200

执行以下命令创建快照,在0x4054df83创建一个名为gsm_fuzz_base的快照,同时对固件的gsm_cc(呼叫控制)任务进行分类

1
python3 -u ./firmwire.py --snapshot-at 0x4054df83,gsm_fuzz_base --fuzz-triage gsm_cc --fuzz-input /firmwire/fuzz_input/ "$FIRMWARE"

有如下字段,快照创建成功

1
2
3
4
5
6
[38.55591][BTL] pal_SmSetEvent+0x9e1 (0x4054df83) 0b10: [../../../VARIANT/PALVar/Platform_EV/PAL/BackTraceLog/src/pal_BackTraceLog.c] - [BTL] btlExtLogProcTimerHandler called
[WARN] firmwire.emulator.firmwire: Cannot save lambda-based breakpoint handlers. Removing <function FirmWireEmu._bp_firmwire_<lambda>_1079304066 at 0x7f2e816e0550> @ 0x4054df82 from snapshot...
[INFO] firmwire.emulator.snapshot: Taking snapshot gsm_fuzz_base to /firmwire/CP_G973FXXU3ASG8_CP13372649_CL16487963_QB24948473_REV01_user_low_ship.tar.md5.lz4_workspace/snapshots.qcow2 (reason: Snapshot at command line)
[INFO] firmwire.emulator.snapshot: Saving snapshot auxiliary data to /firmwire/CP_G973FXXU3ASG8_CP13372649_CL16487963_QB24948473_REV01_user_low_ship.tar.md5.lz4_workspace/gsm_fuzz_base.snapinfo
[INFO] firmwire.emulator.snapshot: Snapshotting QEMU state...
[INFO] firmwire.emulator.snapshot: Snapshot completed!

模糊测试

来进行模糊测试

1
afl-fuzz -i fuzz_input -o fuzz_out -m none  -U -- python3 -u ./firmwire.py --restore-snapshot gsm_fuzz_base --fuzz gsm_cc --fuzz-input @@ ./CP_G973FXXU3ASG8_CP13372649_CL16487963_QB24948473_REV01_user_low_ship.tar.md5.lz4

afl++会使用来自基站收发台(BST)的基本呼叫建立消息的十六进制表示,生成一些能导致崩溃的输入数据

image-20260822083040297

从一个正常的输入语料库,变异,可以看到已经跑出了14个crash

1
python3 -u ./firmwire.py --restore-snapshot gsm_fuzz_base --fuzz-triage gsm_cc --fuzz-input fuzz_out/crashes/id\:000000\,sig\:06\,src\:000358\,time\:8481467\,op\:havoc\,rep\:16 ./CP_G973FXXU3ASG8_CP13372649_CL16487963_QB24948473_REV01_user_low_ship.tar.md5.lz4

可以看到已经崩溃

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
[0.11470][CC] 0x416f9d30 pal_MsgReceiveMbx(CC (23)) - PALMsg<0x2a3c, MTI (aa) -> MM (20), 153 bytes>
[0.11490][CC] 0x40e36f17 0b101: [../../../HEDGE/NASL3/CC/Code/Src/cc_Main.c] - ------------------------- CC TASK ----------------------------
[0.11529][CC] 0x40e369fd 0b10: [../../../HEDGE/NASL3/CC/Code/Src/cc_Main.c] - cc_UpdStackId :CcCurrentStackId: 0
[0.11576][CC] 0x408ae5bd 0b101: [../../../HEDGE/NASL3/CC/Code/Src/cc_MsgDescription.c] - cc_MapSubTypeToMessageNum SubType = 0x5
[0.11622][CC] 0x408ae689 [PROTOCOL][../../../HEDGE/NASL3/CC/Code/Src/cc_MsgDescription.c] - [NAS] CC SETUP
[0.11724][CC] 0x40e36bad 0b101: [../../../HEDGE/NASL3/CC/Code/Src/cc_Main.c] - [StackNo] 0
[0.11756][CC] 0x40e36c2f 0b100: [../../../HEDGE/NASL3/CC/Code/Src/cc_Main.c] - CC <== <RADIO MSG> SETUP_IND
[0.11799][CC] 0x40e36de1 0b1010: [../../../HEDGE/NASL3/CC/Code/Src/cc_Main.c] - PRIVACY! MT message : SETUP
[0.11848][CC] 0x406d6d33 0b10: [../../../PSS/StackService/CNS/DbgSap/Code/Src/ns_ServiceHandlerDmCommon.c] - ns_UpdateCommonSignalingInfo length : 2
[0.11915][CC] 0x406d6da5 0b10: [../../../PSS/StackService/CNS/DbgSap/Code/Src/ns_ServiceHandlerDmCommon.c] - ns_UpdateCommonSignalingInfo direction = 6 / P_E: 0
[0.11948][CC] 0x406d6e9d 0b10: [../../../PSS/StackService/CNS/DbgSap/Code/Src/ns_ServiceHandlerDmCommon.c] - ignore BT MSG at privacyEnable is false
[0.12010][CC] 0x406d6d33 0b10: [../../../PSS/StackService/CNS/DbgSap/Code/Src/ns_ServiceHandlerDmCommon.c] - ns_UpdateCommonSignalingInfo length : 137
[0.12061][CC] 0x406d6da5 0b10: [../../../PSS/StackService/CNS/DbgSap/Code/Src/ns_ServiceHandlerDmCommon.c] - ns_UpdateCommonSignalingInfo direction = 4 / P_E: 0
[0.12239][CC] 0x40e36d8d 0b100: [../../../HEDGE/NASL3/CC/Code/Src/cc_Main.c] - Displaying Received Message Contents
[0.12647][CC] 0x40e301d3 0b1: [../../../HEDGE/NASL3/CC/Code/Src/cc_PduCodec.c] - cc_SetErrorDecoder - > Error Code = 12352
[0.12714][CC] 0x40e35e29 0b1: [../../../HEDGE/NASL3/CC/Code/Src/cc_Main.c] - IE unknown in msg: ERROR -> Msg 773 cc_DetermineErrorDecodeRadioMsg - cc_CodecResult[CcCurrentStackId] = 12352 !!!
[0.12744][CC] 0x40e35e45 0b1: [../../../HEDGE/NASL3/CC/Code/Src/cc_Main.c] - When a message is received that IE unknown element, that message shall be ignored,
[0.12782][CC] 0x40e33239 0b100: [../../../HEDGE/NASL3/CC/Code/Src/cc_PduCodec.c] -
------------- Displaying Information Elements -----------
[0.12815][CC] 0x40e3264f 0b100: [../../../HEDGE/NASL3/CC/Code/Src/cc_PduCodec.c] - Received SETUP From Network
[0.12843][CC] 0x40e32669 0b100: [../../../HEDGE/NASL3/CC/Code/Src/cc_PduCodec.c] - 2 Mandatory IE ->...[24.008]-9.3.23.2
[0.12872][CC] 0x40e32685 0b100: [../../../HEDGE/NASL3/CC/Code/Src/cc_PduCodec.c] - BearerCapabilityOne -> ...
[0.12990][CC] 0x40e33285 0b100: [../../../HEDGE/NASL3/CC/Code/Src/cc_PduCodec.c] -
-----------------------
[0.13028][CC] 0x409a569f 0b101: [../../../HEDGE/NASL3/CC/Code/Src/cc_MtCallEstablishment.c] - Entering cc_DecodeSetupIndMsg....[24.008] - 5.2.2...
[0.13121][CC] 0x409a5785 0b10: [../../../HEDGE/NASL3/CC/Code/Src/cc_MtCallEstablishment.c] - TransactionId -> 9
[0.13232][CC] 0x40e3936b 0b100: [../../../HEDGE/NASL3/CC/Code/Src/cc_Main.c] - Bearer 1 Capability ->.....
[0.13290][CC] 0x40e39549 0b100: [../../../HEDGE/NASL3/CC/Code/Src/cc_Main.c] - Network Transfer Capability -> CC_NTWK_SPEECH_BEARER
[0.13346][CC] 0x409a5ac1 0b10: [../../../HEDGE/NASL3/CC/Code/Src/cc_MtCallEstablishment.c] - Accept MT call, Call Session Number -> 0
[0.13372][CC] 0x409a5af3 0b101: [../../../HEDGE/NASL3/CC/Code/Src/cc_MtCallEstablishment.c] - Ti -> 9
[0.13393][CC] 0x409a5b15 0b10: [../../../HEDGE/NASL3/CC/Code/Src/cc_MtCallEstablishment.c] - cc_CsvtCallSupport = 1, GapiData.CallType1 = 1
[0.13417][CC] 0x409a5b65 0b101: [../../../HEDGE/NASL3/CC/Code/Src/cc_MtCallEstablishment.c] - No Bearer 2 Capabilities in cc_DecodeSetupIndMsg
[0.13444][CC] 0x4099e7bf 0b100: [../../../HEDGE/NASL3/CC/Code/Src/cc_GapiIntfManagement.c] - Repeat Indicator -> CC_INVALID_REPEAT_INDICATOR
[0.13468][CC] 0x409a5b99 0b100: [../../../HEDGE/NASL3/CC/Code/Src/cc_MtCallEstablishment.c] - No Low Layer Compatibility 1 in cc_DecodeSetupIndMsg
[0.13491][CC] 0x409a5bc1 0b100: [../../../HEDGE/NASL3/CC/Code/Src/cc_MtCallEstablishment.c] - No Low Layer Compatibility 2 in cc_DecodeSetupIndMsg
[0.13514][CC] 0x409a5be5 0b100: [../../../HEDGE/NASL3/CC/Code/Src/cc_MtCallEstablishment.c] - No High Layer Compatibility 1 in cc_DecodeSetupIndMsg
[0.13538][CC] 0x409a5c09 0b100: [../../../HEDGE/NASL3/CC/Code/Src/cc_MtCallEstablishment.c] - No High Layer Compatibility 2 in cc_DecodeSetupIndMsg
[0.13562][CC] 0x409a5e17 0b100: [../../../HEDGE/NASL3/CC/Code/Src/cc_MtCallEstablishment.c] - Signal Ind Present -> CC_NS_FALSE
[0.13590][CC] 0x409a5e4b 0b100: [../../../HEDGE/NASL3/CC/Code/Src/cc_MtCallEstablishment.c] - Network Supports Multi Calll -> CC_NS_FALSE
[0.13610][CC] 0x409a5e6d 0b100: [../../../HEDGE/NASL3/CC/Code/Src/cc_MtCallEstablishment.c] - No Valid Calling Party Number in cc_DecodeSetupIndMsg
[0.13632][CC] 0x409a5e9d 0b100: [../../../HEDGE/NASL3/CC/Code/Src/cc_MtCallEstablishment.c] - No Valid Called Party Number in cc_DecodeSetupIndMsg
[0.13653][CC] 0x409a5edd 0b100: [../../../HEDGE/NASL3/CC/Code/Src/cc_MtCallEstablishment.c] - No Valid Called Party Sub address Given in cc_DecodeSetupIndMsg
[0.13674][CC] 0x409a5f11 0b101: [../../../HEDGE/NASL3/CC/Code/Src/cc_MtCallEstablishment.c] - Cause of No CLI -> 255
[0.13693][CC] 0x409a5f4b 0b101: [../../../HEDGE/NASL3/CC/Code/Src/cc_MtCallEstablishment.c] - No Valid Facility Message sent in cc_DecodeSetupIndMsg
[0.13714][CC] 0x409a5f7f 0b101: [../../../HEDGE/NASL3/CC/Code/Src/cc_MtCallEstablishment.c] - No Valid Redirecting Party Number In cc_DecodeSetupIndMsg
[0.13735][CC] 0x409a5fab 0b101: [../../../HEDGE/NASL3/CC/Code/Src/cc_MtCallEstablishment.c] - No Priority Given in cc_DecodeSetupIndMsg
[0.13753][CC] 0x409a5fdd 0b101: [../../../HEDGE/NASL3/CC/Code/Src/cc_MtCallEstablishment.c] - No Progress Indicator Given in cc_DecodeSetupIndMsg
[0.13771][CC] 0x409a600b 0b101: [../../../HEDGE/NASL3/CC/Code/Src/cc_MtCallEstablishment.c] - Alerting Pattern -> 255
[0.13804][CC] 0x409a507f 0b101: [../../../HEDGE/NASL3/CC/Code/Src/cc_MtCallEstablishment.c] - Entering cc_CheckBearerCompatibility function
[0.13837][CC] 0x407af425 0b101: [../../../HEDGE/NASL3/BC/Code/Src/bc_utilities.c] - [bc_create_bearer]
[0.13854][CC] 0x407af481 0b100: [../../../HEDGE/NASL3/BC/Code/Src/bc_utilities.c] - Created Bearer with Id = 0.
[0.13878][CC] 0x407af831 0b101: [../../../HEDGE/NASL3/BC/Code/Src/bc_utilities.c] - Reading octet BC_OCTET_3 = 0x00
[0.13894][CC] 0x407af831 0b101: [../../../HEDGE/NASL3/BC/Code/Src/bc_utilities.c] - Reading octet BC_OCTET_3a = 0x3f
[0.13907][CC] 0x407af831 0b101: [../../../HEDGE/NASL3/BC/Code/Src/bc_utilities.c] - Reading octet BC_OCTET_3b = 0x12
[0.13919][CC] 0x407af831 0b101: [../../../HEDGE/NASL3/BC/Code/Src/bc_utilities.c] - Reading octet BC_OCTET_3c = 0x00
[0.13930][CC] 0x407af831 0b101: [../../../HEDGE/NASL3/BC/Code/Src/bc_utilities.c] - Reading octet BC_OCTET_3d = 0x01
[0.13940][CC] 0x407af831 0b101: [../../../HEDGE/NASL3/BC/Code/Src/bc_utilities.c] - Reading octet BC_OCTET_3e = 0x00
[0.13951][CC] 0x407af831 0b101: [../../../HEDGE/NASL3/BC/Code/Src/bc_utilities.c] - Reading octet BC_OCTET_3f = 0x00
[0.13963][CC] 0x407af831 0b101: [../../../HEDGE/NASL3/BC/Code/Src/bc_utilities.c] - Reading octet BC_OCTET_4 = 0xc0
[0.13973][CC] 0x407af831 0b101: [../../../HEDGE/NASL3/BC/Code/Src/bc_utilities.c] - Reading octet BC_OCTET_5 = 0x04
[0.13984][CC] 0x407af831 0b101: [../../../HEDGE/NASL3/BC/Code/Src/bc_utilities.c] - Reading octet BC_OCTET_5a = 0xff
[0.13994][CC] 0x407af831 0b101: [../../../HEDGE/NASL3/BC/Code/Src/bc_utilities.c] - Reading octet BC_OCTET_6 = 0xf4
[0.14005][CC] 0x407af831 0b101: [../../../HEDGE/NASL3/BC/Code/Src/bc_utilities.c] - Reading octet BC_OCTET_7 = 0xff
[0.14021][CC] 0x407af555 0b100: [../../../HEDGE/NASL3/BC/Code/Src/bc_utilities.c] - Setting BC_LENGTH_OF_BEARER (0) = 0x57
[0.14038][CC] 0x409a513f 0b1: [../../../HEDGE/NASL3/CC/Code/Src/cc_MtCallEstablishment.c] - Invalid RAT Mode
[0.14051][CC] 0x409a515f 0b100: [../../../HEDGE/NASL3/CC/Code/Src/cc_MtCallEstablishment.c] - CcRatMode = 3
[0.14077][CC] 0x407b0349 0b101: [../../../HEDGE/NASL3/BC/Code/Src/bc_utilities.c] - Checking BC compatibility for bearer 0 on RAT RAT?
[0.14091][CC] 0x407b039d 0b100: [../../../HEDGE/NASL3/BC/Code/Src/bc_utilities.c] - ITC speech OK.
[0.14102][CC] 0x407b03ef 0b100: [../../../HEDGE/NASL3/BC/Code/Src/bc_utilities.c] - BC compatibility OK
[0.14114][CC] 0x407af49f 0b100: [../../../HEDGE/NASL3/BC/Code/Src/bc_utilities.c] - bc_destroy_bearer(0).
[0.14134][CC] 0x409a4cdd 0b101: [../../../HEDGE/NASL3/CC/Code/Src/cc_MtCallEstablishment.c] - cc_PerformBearerNegotiation
[0.14149][CC] 0x407af425 0b101: [../../../HEDGE/NASL3/BC/Code/Src/bc_utilities.c] - [bc_create_bearer]
[0.14157][CC] 0x407af481 0b100: [../../../HEDGE/NASL3/BC/Code/Src/bc_utilities.c] - Created Bearer with Id = 0.
[0.14166][CC] 0x407af831 0b101: [../../../HEDGE/NASL3/BC/Code/Src/bc_utilities.c] - Reading octet BC_OCTET_3 = 0x00
[0.14174][CC] 0x407af831 0b101: [../../../HEDGE/NASL3/BC/Code/Src/bc_utilities.c] - Reading octet BC_OCTET_3a = 0x3f
[0.14181][CC] 0x407af831 0b101: [../../../HEDGE/NASL3/BC/Code/Src/bc_utilities.c] - Reading octet BC_OCTET_3b = 0x12
[0.14189][CC] 0x407af831 0b101: [../../../HEDGE/NASL3/BC/Code/Src/bc_utilities.c] - Reading octet BC_OCTET_3c = 0x00
[0.14197][CC] 0x407af831 0b101: [../../../HEDGE/NASL3/BC/Code/Src/bc_utilities.c] - Reading octet BC_OCTET_3d = 0x01
[0.14204][CC] 0x407af831 0b101: [../../../HEDGE/NASL3/BC/Code/Src/bc_utilities.c] - Reading octet BC_OCTET_3e = 0x00
[0.14211][CC] 0x407af831 0b101: [../../../HEDGE/NASL3/BC/Code/Src/bc_utilities.c] - Reading octet BC_OCTET_3f = 0x00
[0.14219][CC] 0x407af831 0b101: [../../../HEDGE/NASL3/BC/Code/Src/bc_utilities.c] - Reading octet BC_OCTET_4 = 0xc0
[0.14227][CC] 0x407af831 0b101: [../../../HEDGE/NASL3/BC/Code/Src/bc_utilities.c] - Reading octet BC_OCTET_5 = 0x04
[0.14235][CC] 0x407af831 0b101: [../../../HEDGE/NASL3/BC/Code/Src/bc_utilities.c] - Reading octet BC_OCTET_5a = 0xff
[0.14242][CC] 0x407af831 0b101: [../../../HEDGE/NASL3/BC/Code/Src/bc_utilities.c] - Reading octet BC_OCTET_6 = 0xf4
[0.14250][CC] 0x407af831 0b101: [../../../HEDGE/NASL3/BC/Code/Src/bc_utilities.c] - Reading octet BC_OCTET_7 = 0xff
[0.14258][CC] 0x407af555 0b100: [../../../HEDGE/NASL3/BC/Code/Src/bc_utilities.c] - Setting BC_LENGTH_OF_BEARER (0) = 0x55
[0.14271][CC] 0x407af6b3 0b1: [../../../HEDGE/NASL3/BC/Code/Src/bc_utilities.c] - Element BC_FIXED_NW_USER_RATE not present
[0.14285][CC] 0x407af49f 0b100: [../../../HEDGE/NASL3/BC/Code/Src/bc_utilities.c] - bc_destroy_bearer(0).
[0.14302][CC] 0x409a5017 0b1: [../../../HEDGE/NASL3/CC/Code/Src/cc_MtCallEstablishment.c] - BC1 Length -> 87
[ERROR] firmwire.vendor.shannon.hooks: FATAL ERROR (CC): from 0x4054f415 [pal_PlatformMisc.c:146 - Fatal error: PAL_MEM_GUARD_CORRUPTION
../../../VARIANT/PALVar/Platform_EV/PAL/MemoryInterface/src/pal_MemInterface.c Li]
Aborted

发送了153字节的样本

1
2
root@18225d60a1a3:/firmwire# wc fuzz_out/crashes/id\:000000\,sig\:06\,src\:000358\,time\:8481467\,op\:havoc\,rep\:16
0 3 153 fuzz_out/crashes/id:000000,sig:06,src:000358,time:8481467,op:havoc,rep:16

静态分析

跟之前解CP_*一样的分析流程,这里更加详细

这里使用这个项目:ShannonBaseband

使用reversing/modem下的parse_modem.py可以对modem.bin进行解析

image-20260822134033626

对script目录下的文件进行解释

  • ShannonLoader:解析 Shannon 的 TOC、MPU 和 scatter-load 信息,把裸 modem.bin 映射到正确的地址空间。
  • ShannonTraceEntry.py:识别 trace/debug 数据,避免自动分析把调试数据当成代码。
  • ShannonRename.py:根据字符串和交叉引用启发式地给函数重命名。

需要准备Ghidra10.3.3和JDK17

1
sudo pacman -S jdk17-openjdk
1
2
wget https://github.com/NationalSecurityAgency/ghidra/releases/download/Ghidra_10.3.3_build/ghidra_10.3.3_PUBLIC_20230829.zip
unzip -q ghidra_10.3.3_PUBLIC_20230829.zip

添加环境变量

1
2
3
export JAVA_HOME=/usr/lib/jvm/java-17-openjdk
export GHIDRA_INSTALL_DIR=$PWD/ghidra_10.3.3_PUBLIC
export GRADLE_USER_HOME=/tmp/shannon-gradle

构建 ShannonLoader

1
2
cd ShannonBaseband/reversing/ghidra/ShannonLoader
./gradlew

之后会在dist生成ShannonLoader*.zip

之后就可以启动Ghidra了

我这里配置我当前环境的启动

1
2
3
4
5
6
7
8
9
10
11
GHIDRA_USER_HOME=/tmp/ghidra-user-10.3.3
mkdir -p "$GHIDRA_USER_HOME"
env -u WAYLAND_DISPLAY \
GDK_BACKEND=x11 \
LIBGL_ALWAYS_SOFTWARE=1 \
_JAVA_AWT_WM_NONREPARENTING=1 \
PATH=/usr/lib/jvm/java-17-openjdk/bin:$PATH \
JAVA_TOOL_OPTIONS="-Duser.home=$GHIDRA_USER_HOME -Djava.awt.headless=false" \
./ghidra_10.3.3_PUBLIC/support/launch.sh fg jdk Ghidra '' \
'-Dsun.java2d.xrender=false -Dsun.java2d.opengl=false -Dsun.java2d.pmoffscreen=false -Dsun.java2d.uiScale=1' \
ghidra.GhidraRun
  1. 在 Ghidra 启动页选择 File -> Install Extensions...,选择 dist/ShannonLoader*.zip,重启 Ghidra

  2. 创建新的Ghidra project,导入modem.bin

  3. Import 窗口中确认 Loader 自动显示为 Samsung Shannon Modem Binary。若只显示 Raw Binary,说明扩展没有安装成功,或导入的不是以 TOC\x00 开头的完整镜像image-20260822151009544

  4. 先不要运行Auto Analyze

  5. 打开 Window -> Script Manager,把ShannonBaseband/reversing/ghidra/scripts 加入脚本目录,运行 ShannonTraceEntry.py。脚本出现在 Shannon 分类下image-20260822151836444

    image-20260822152237967

  6. 执行 Analysis -> Auto Analyze...,取消勾选 Non-returning Functions - Discovered,再开始分析。要求取消这一项,否则 log_printf 可能被错误识别为不返回,造成后续反汇编损坏

    image-20260822152315660

  7. 分析完成后运行 ShannonRename.py

image-20260822154858124

根据官方的截图暴露的函数名,可以定位到cc_DecodeSetupIndMsg

但是我这里跳转cc_DecodeSetupIndMsg失败了,可能没有命名好,我这里的函数名是cc_MtCallBlockStatu

在这个函数中,有一个cc_GetNsCallTypefromNtwkCallType函数的调用。该函数接受三个参数:Transfer Capability 作为第一个参数, bearer capability pointer 作为第二个参数,bearer capability length 作为第三个参数。之后,它调用了一个名为 FUN_040158f6() 的函数,该函数再调用 pal_MemInterface__address (Shannon 拥有 PAL 区域,该区域提供了对内存管理功能的接口,在该区域中,pal_MemInterface__address来分配内存)。

image-20260822162928518

查看第 162 行代码:首先会检查是否存在 bearer capability 1( local_4c ),然后会获取长度( local_ca )以及指针,这些数值会被存储在变量中,并作为参数传递给 cc_GetNsCallTypefromNtwkCallType 。Transfer Capability 的值在Bearer Capability 编码的第 3 个字节中,以 3 位二进制数表示。查看第 176 行代码,通过使用值 7( 00000111 )对无 bearer capability 中的第一个字节进行掩码操作,来获取这 3 个字节的值。无bearer capability 的长度是一个直接作为参数传递的值,无需检查是否超过了 16 的最大值。

3GPP TS 24.008 SETUP message content table, the Bearer capability information element has a length of 3–16 octets

在函数 cc_GetNsCallTypefromNtwkCallType 中,首先会检查第一个参数 param_1 (Transfer Capability)的值是否不等于 1,如果是,则会返回相应的 CallType 代码。在本例中,该值为 1,因此会调用 thunk_FUN_040158f6 (第 34 行),并将攻击者控制的长度值作为参数传递给 pal_MemInterface__address 。注意,还会额外分配两个字节用于后续存储 IE 标识符(对于承载能力 1 的情况为 04)以及缓冲区的大小

image-20260822163910135

调用 pal_MemInterface__address 函数来分配缓冲区空间

image-20260822163929923

之后,所有数据都会被复制到缓冲区中,使用 FUN_408c6852 进行复制。需要注意的是,在复制过程中并没有发生缓冲区溢出问题,因为复制的字节数与传递给内存分配函数的数据量是一致的。不过,此时创建的缓冲区超出了文档中规定的限制。因此,当固件中的其他函数处理这些数据时,可能会基于错误的假设来估计缓冲区的容z量,从而导致漏洞被触发

image-20260822164039983

OTA漏洞利用

由于没有对应漏洞的设备,这里就不分析了。

简单说下,怎么搭建利用环境。

  • 首先我们需要使用YateBTS搭建一个基站,需要一个BladeRF,配合YateBTS搭建基站。

  • 然后根据SIM卡所在的国家/地区来配置YateBTS。

  • 之后启动Yate。

  • 发送payload漏洞利用

Reference

https://cveawg.mitre.org/api/cve/CVE-2020-25279

https://locus-x64.github.io/blog/cve-2020-25279

https://github.com/FirmWire/FirmWire

https://github.com/grant-h/ShannonBaseband

https://www.youtube.com/watch?v=wkWUU8820ro&list=PLH15HpR5qRsXE_4kOSy_SXwFkFQre4AV_&index=35

https://i.blackhat.com/USA-20/Wednesday/us-20-Hernandez-Emulating-Samsungs-Baseband-For-Security-Testing.pdf?_sp=5cd2b0d2-922b-40f1-beef-0bbf26b90bbc.1787299460917&_gl=1*82h9bj*_gcl_au*MTUxNjIzMDM1NC4xNzg3Mjk4NTIy*_ga*MTA4NjY2NzM3OS4xNzg3Mjk4NTIz*_ga_K4JK67TFYV*czE3ODcyOTg1MjIkbzEkZzEkdDE3ODcyOTk0NTIkajYwJGwwJGgw

EOF CHECKSUM_OK

// EXTERNAL_CHANNEL

COMMENTS