BEGIN_PAYLOAD
20260822
漏洞概要
- 漏洞类型:缓冲区溢出
- 危害:RCE
- 三星手机中的基带组件存在缓冲区溢出漏洞,通过异常的SETUP消息可导致任意代码执行
三星Exynos基带
手机架构
来看一下手机架构

左下红色框住的芯片是基带芯片,这是本文章研究的对象
基带
如下图简要概述了连接处理器(CP)和应用处理器 (AP)之间的通信过程。
AP运行在linux内核上,运行Android OS,开启了各种程序和服务与CP进行交互。
- 无线接口层守护程序(RILD)是一个运行在AP上的程序,为调制解调器提供一个接口
- CP引导守护程序(CBD)在基带处理器中加载固件镜像
- 远程文件系统(RFS)存储调制解调器的配置,允许调制解调器访问Android OS

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

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允许发送方决定字段的长度,这个长度可以”如任意”长,由于定义长度可用的位数有限,所以通常会有界限

GSM呼叫流程
GSM呼叫建立过程:
- 移动台(手机)通过向基站发送一个“告警”消息来发送呼叫。该消息包含了被叫方的电话号码。
- 基站(BS)将该告警消息发送给移动交换中心(MSC),以便联系到对方并路由呼叫。
- 如果被叫方处于可用状态并且路由正确,移动交换中心会向基站发送一个”呼叫进行中”的消息,然后基站会向手机发送一个确认消息。
- 然后,移动交换中心(MSC)向基站发送一个“建立”消息,其中包含被叫方的电话号码。
- 基站将该“建立”消息发送给手机,然后手机向基站发送一个确认消息。
- 此时,呼叫被视为“已连接”,手机和被叫方可以开始通信了。
视频
在分析之前接下来先看如下视频:
固件下载
https://samfw.com/firmware/SM-G973F/PAK
找到版本为G973FXXU3ASG8,下载包含 CP 文件的对应固件包
我这里保存好了,进行分享
https://1024terabox.com/s/1Wg5G2CMMUwSSEqdEAYSm4Q

也可以直接从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截图,注意:偏移和官方不同

| 段 |
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


动态分析
编译 Shannon ModKit
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 
执行以下命令创建快照,在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)的基本呼叫建立消息的十六进制表示,生成一些能导致崩溃的输入数据

从一个正常的输入语料库,变异,可以看到已经跑出了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进行解析

对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
|
在 Ghidra 启动页选择 File -> Install Extensions...,选择 dist/ShannonLoader*.zip,重启 Ghidra
创建新的Ghidra project,导入modem.bin
Import 窗口中确认 Loader 自动显示为 Samsung Shannon Modem Binary。若只显示 Raw Binary,说明扩展没有安装成功,或导入的不是以 TOC\x00 开头的完整镜像
先不要运行Auto Analyze
打开 Window -> Script Manager,把ShannonBaseband/reversing/ghidra/scripts 加入脚本目录,运行 ShannonTraceEntry.py。脚本出现在 Shannon 分类下

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

分析完成后运行 ShannonRename.py

根据官方的截图暴露的函数名,可以定位到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来分配内存)。

查看第 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 的最大值。

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

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

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

OTA漏洞利用
由于没有对应漏洞的设备,这里就不分析了。
简单说下,怎么搭建利用环境。
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