-
-
[原创]BrakTooth学习笔记
-
发表于: 2023-4-15 16:22 14081
-
学习论文BRAKTOOTH: Causing Havoc on Bluetooth Link Manager via Directed Fuzzing的一些补充
开源的渗透测试工具Ubertooth One使用的无线收发器CC2400决定了它不支持低功耗蓝牙BLE 2M PHY,也不支持经典蓝牙的EDR2和EDR3,现阶段固件实现也不支持协议Fuzzing。
BrakTooth使用Espressif ESP32,它支持蓝牙双模,射频IP不知道是自研IP还是采用CEVA官方的射频Ripple IP,如果是Ripple IP,它不支持低功耗蓝牙BLE 2M PHY,BLE Coded PHY需要由蓝牙IP提供BLE FEC支持,蓝牙IP不知道是采用CEVA版本8(BT 4.2)还是版本9(BT 5.0)的蓝牙IP。
实现Controller的MCU指令集采用Cadence收购Tensilica的Xtensa,只用了标量单元(矢量单元侧重DSP,与CEVA的DSP竞争),需要编写ghidra-xtensa处理器插件进行反编译。ABI使用寄存器窗口,与Sparc的实现类似,VMP使用的寄存器轮转与之也非常类似。
由于CEVA蓝牙IP低功耗版本有某些版本的Controller源码流出,重点关注其经典蓝牙IP的Controller逆向。L3 UMAC(Controller)与L2 LMAC(BP)用Exchange Memory进行通信,LMAC固件CEVA官方ROM固化,相关指令集和ROM Patch未知,理论上有了物理层和链路层寄存器的定义和描述后,可以自己实现LMAC而不用官方实现的LMAC。逆向蓝牙厂商以静态库或ROM的方式实现的Controller,需要对EM(Exchange Memory)寄存器读写和链路层寄存器读写进行手动标注,版本不同相关寄存器也有差异,需要猜测。比如对BrakTooth的ROM Patch框架中的源码reversed_ld_page_em_init函数进行标注如下(不一定对):
推荐基于CEVA蓝牙IP相对比较好实现蓝牙渗透工具的蓝牙芯片:低功耗蓝牙有ON Semiconductor的RSL10/RSL15、Dialog的DA14531和Bouffalo Lab的BL702;蓝牙双模有Bouffalo Lab的BL618/BL606P和Beken的BK3288/Bk7256。
/
*
*
*
Frame
Format
*
-
0000x
: Do
not
use.
*
-
00010
: Master connect.
*
-
00011
: Slave connect.
*
-
00100
: Page.
*
-
00101
: Page scan.
*
-
00110
: Master page response.
*
-
00111
: Slave page response.
*
-
01000
: Inquiry.
*
-
01001
: Inquiry response.
*
-
01010
: Do
not
use.
*
-
01011
: Do
not
use.
*
-
011xx
: Do
not
use.
*
-
10xxx
: Do
not
use.
*
-
11000
: Master Broadcast.
*
-
11001
: Broadcast Scan.
*
-
11010
: Master Access window.
*
-
11011
: Slave Access window
1.
*
-
11100
: Slave Access window
2.
*
-
11101
: Do
not
use.
*
-
1111x
: Do
not
use
*
/
#define EM_BT_CS_FMT_MST_CONNECT 0x02
#define EM_BT_CS_FMT_SLV_CONNECT 0x03
#define EM_BT_CS_FMT_PAGE 0x04
#define EM_BT_CS_FMT_PAGE_SCAN 0x05
#define EM_BT_CS_FMT_MST_PAGE_RSP 0x06
#define EM_BT_CS_FMT_SLV_PAGE_RSP 0x07
#define EM_BT_CS_FMT_INQUIRY 0x08
#define EM_BT_CS_FMT_INQ_RSP 0x09
#define EM_BT_CS_FMT_MST_BCST 0x18
#define EM_BT_CS_FMT_BCST_SCAN 0x19
#define EM_BT_CS_FMT_MST_ACC_WIN 0x1A
#define EM_BT_CS_FMT_SLV_ACC_WIN1 0x1B
#define EM_BT_CS_FMT_SLV_ACC_WIN2 0x1C
#define TX_LM_BUF_PTR (*((uint32_t *)0x3ffb23c2))
#define TX_PTR (*((uint32_t *)0x3ffb23ba))
#define TX_ACL_BUF_PTR (*((uint32_t *)0x3ffb23c0))
#define TX_PHEADER (*((uint32_t *)0x3ffb23be))
#define TX_HEADER (*((uint32_t *)0x3ffb23bc))
#define TX_DESCPTR (*((uint32_t *)0x3ffb1e0a))
#define ACL_DM_PRIO_CNTL (*((uint32_t *)0x3ffb1e50))
#define SCO_DM_PRIO_CNTL (*((uint32_t *)0x3ffb1e52))
#define FR_CNTL (*((uint32_t *)0x3ffb1dee))
#define PWR_CNTL (*((uint32_t *)0x3ffb1e04))
#define BDADDR0 (*((uint32_t *)0x3ffb1df8))
#define BDADDR1 (*((uint32_t *)0x3ffb1dfa))
#define BDADDR2 (*((uint32_t *)0x3ffb1dfc))
#define BCH0 (*((uint32_t *)0x3ffb1dfe))
#define BCH1 (*((uint32_t *)0x3ffb1e00))
#define RXMAXBUF_BCH2 (*((uint32_t *)0x3ffb1e02))
#define TXRX_CNTL (*((uint32_t *)0x3ffb1e06))
#define ACL_TX_STAT (*((uint32_t *)0x3ffb1e4c))
#define WIN_CNTL (*((uint32_t *)0x3ffb1e08))
#define BIT_OFF (*((uint32_t *)0x3ffb1df0))
#define CLK_OFF0 (*((uint32_t *)0x3ffb1df2))
#define CLK_OFF1 (*((uint32_t *)0x3ffb1df4))
#define LINK_CNTL (*((uint32_t *)0x3ffb1df6))
#define ACL_RX_STAT (*((uint32_t *)0x3ffb1e4e))
uint32_t reversed_ld_page_em_init(void)
{
uint8_t bVar1;
char cVar2;
int
iVar3;
ushort
*
puVar4;
int
iVar5;
ushort
*
puVar6;
ushort
*
puVar7;
ushort
*
puVar8;
iVar5
=
ld_page_env;
bVar1
=
*
(uint8_t
*
)(ld_page_env
+
0x41
);
iVar3
=
(uint)bVar1
*
0x66
;
/
/
FR_CNTL
puVar4
=
(ushort
*
)(&FR_CNTL
+
iVar3);
/
/
PWR_CNTL
puVar8
=
(ushort
*
)(&PWR_CNTL
+
iVar3);
/
/
em_bt_frcntl_format_setf(EM_BT_CS_FMT_PAGE)
/
/
FORMAT
=
FRCNTL[
0
:
4
]
0x
f f e
0
=
0b
1111
1111
1110
0000
/
/
4
:Page
*
puVar4
=
*
puVar4 &
0xffe0
|
4
;
/
/
em_bt_bdaddr0_setf
*
(uint16_t
*
)(&BDADDR0
+
iVar3)
=
*
(uint16_t
*
)(iVar5
+
0x28
);
/
/
em_bt_bdaddr1_setf
*
(uint16_t
*
)(&BDADDR1
+
iVar3)
=
*
(uint16_t
*
)(iVar5
+
0x2a
);
/
/
em_bt_bdaddr2_setf
*
(uint16_t
*
)(&BDADDR2
+
iVar3)
=
*
(uint16_t
*
)(iVar5
+
0x2c
);
/
/
em_bt_bch0_setf
*
(uint16_t
*
)(&BCH0
+
iVar3)
=
*
(uint16_t
*
)(iVar5
+
0x44
);
/
/
em_bt_bch1_setf
*
(uint16_t
*
)(&BCH1
+
iVar3)
=
*
(uint16_t
*
)(iVar5
+
0x46
);
/
/
em_bt_rxmaxbuf_bch2_pack
*
(ushort
*
)(&RXMAXBUF_BCH2
+
iVar3)
=
(ushort)
*
(uint8_t
*
)(iVar5
+
0x48
) &
3
;
/
/
em_bt_pwrcntl_txpwr_setf
*
puVar8
=
(ushort)rwip_rf[
44
] |
*
puVar8 &
0xff00
;
/
/
TXRX_CNTL
puVar6
=
(ushort
*
)(&TXRX_CNTL
+
iVar3);
/
/
em_bt_txrxcntl_txeir_setf
*
puVar6
=
*
puVar6 &
0xfff7
;
/
/
ACL_TX_STAT
puVar7
=
(ushort
*
)(&ACL_TX_STAT
+
iVar3);
/
/
em_bt_acltxstat_txtog_setf
*
puVar7
=
*
puVar7 &
0x7fff
;
/
/
em_bt_acltxstat_waitack_setf
*
puVar7
=
*
puVar7 &
0xfbff
;
/
/
em_bt_acltxstat_lasttxseqn_setf
*
puVar7
=
*
puVar7 &
0xfffe
;
/
/
em_bt_acltxstat_lasttxack_setf
*
puVar7
=
*
puVar7 &
0xfffd
;
/
/
em_bt_acltxstat_fcrc_setf
*
puVar7
=
*
puVar7 &
0xdfff
;
/
/
em_bt_acltxstat_fnak_setf
*
puVar7
=
*
puVar7 &
0xefff
;
/
/
em_bt_pwrcntl_fh_en_setf
*
puVar8
=
*
puVar8 &
0x7fff
|
0x8000
;
/
/
em_bt_wincntl_pack
*
(uint16_t
*
)(&WIN_CNTL
+
iVar3)
=
0x30
;
/
/
em_bt_bitoff_pack
*
(uint16_t
*
)(&BIT_OFF
+
iVar3)
=
0
;
/
/
em_bt_clkoff0_setf
*
(uint16_t
*
)(&CLK_OFF0
+
iVar3)
=
*
(uint16_t
*
)(iVar5
+
0x3c
);
/
/
em_bt_clkoff1_setf
*
(uint16_t
*
)(&CLK_OFF1
+
iVar3)
=
0
;
/
/
em_bt_txrxcntl_rxthr_setf
*
puVar6
=
*
puVar6 &
0x1fff
;
/
/
LINK_CNTL
puVar7
=
&LINK_CNTL
+
(uint)bVar1
*
0x33
;
/
/
em_bt_linkcntl_aknena_setf
*
puVar7
=
*
puVar7 &
0x7fff
;
/
/
em_bt_linkcntl_afhena_setf
*
puVar7
=
*
puVar7 &
0xbfff
;
/
/
em_bt_linkcntl_whdsb_setf
*
puVar7
=
*
puVar7 &
0xefff
;
/
/
em_bt_txrxcntl_txcrypt_setf
*
puVar6
=
*
puVar6 &
0xfffc
;
/
/
em_bt_txrxcntl_rxcrypt_setf
*
puVar6
=
*
puVar6 &
0xfcff
;
/
/
em_bt_txrxcntl_txbcry_setf
*
puVar6
=
*
puVar6 &
0xfffb
;
/
/
em_bt_txrxcntl_rxbcry_setf
*
puVar6
=
*
puVar6 &
0xfbff
;
/
/
em_bt_txrxcntl_stopmod_setf
*
puVar6
=
*
puVar6 &
0xff7f
;
cVar2
=
*
(char
*
)(iVar5
+
0x54
);
/
/
em_bt_linkcntl_acledr_setf
*
puVar7
=
*
puVar7 &
0xf7ff
;
if
(cVar2
=
=
'\0'
) {
iVar5
=
((uint)
*
(uint8_t
*
)(iVar5
+
0x41
) &
0x7f
)
*
0x14
;
/
/
em_bt_txheader_pack
*
(uint16_t
*
)(&TX_HEADER
+
iVar5)
=
0x390
;
/
/
em_bt_txpheader_pack
*
(uint16_t
*
)(&TX_PHEADER
+
iVar5)
=
0x92
;
/
/
em_bt_txaclbufptr_pack
*
(uint16_t
*
)(&TX_ACL_BUF_PTR
+
iVar5)
=
0
;
/
/
em_bt_txlmbufptr_pack
*
(uint16_t
*
)(&TX_LM_BUF_PTR
+
iVar5)
=
0x262c
;
/
/
em_bt_txptr_pack
*
(uint16_t
*
)(&TX_PTR
+
iVar5)
=
0
;
hook_ld_page_em_init(iVar5);
/
/
em_bt_txdescptr_setf
*
(short
*
)(&TX_DESCPTR
+
iVar3)
=
(short)iVar5
+
0x23ba
;
}
else
{
/
/
em_bt_txdescptr_pack
*
(uint16_t
*
)(&TX_DESCPTR
+
iVar3)
=
0
;
}
if
(false) {
(
*
*
(code3
*
*
)(r_plf_funcs_p
+
0x14
))(
"(((uint16_t)aclincpriostep << 13) & ~((uint16_t)0x0000E000)) == 0"
,
"ld_page.c"
,
0xa33
);
}
if
(false) {
(
*
*
(code3
*
*
)(r_plf_funcs_p
+
0x14
))(
"(((uint16_t)aclminprio << 8) & ~((uint16_t)0x00001F00)) == 0"
,
"ld_page.c"
,
0xa34
);
}
if
(false) {
(
*
*
(code3
*
*
)(r_plf_funcs_p
+
0x14
))(
"(((uint16_t)accurrentprio << 0) & ~((uint16_t)0x0000001F)) == 0"
,
"ld_page.c"
,
0xa36
);
}
/
/
ACL_DM_PRIO_CNTL
/
/
aclincpriostep
=
ACL_DM_PRIO_CNTL[
13
:
15
]
0xa33
/
/
aclminprio
=
ACL_DM_PRIO_CNTL[
8
:
12
]
0xa34
/
/
reserved_05_07
=
ACL_DM_PRIO_CNTL[
5
:
7
](????aclconflict)
0xa35
/
/
aclcurrentprio
=
ACL_DM_PRIO_CNTL[
0
:
4
]
0xa36
/
/
em_acldmpriocntl_pack
*
(uint16_t
*
)(&ACL_DM_PRIO_CNTL
+
iVar3)
=
0x2808
;
/
/
SCO_DM_PRIO_CNTL
/
/
scoincpriostep
=
SCO_DM_PRIO_CNTL[
13
:
15
]
/
/
scominprio
=
SCO_DM_PRIO_CNTL[
8
:
12
]
/
/
reserved_05_07
=
SCO_DM_PRIO_CNTL[
5
:
7
](????scoconflict)
/
/
scocurrentprio
=
SCO_DM_PRIO_CNTL[
0
:
4
]
/
/
em_scodmpriocntl_pack
*
(uint16_t
*
)(&SCO_DM_PRIO_CNTL
+
iVar3)
=
0
;
/
/
em_bt_frcntl_pack
*
puVar4
=
0x5704
;
return
0x5704
;
}
/
*
*
*
Frame
Format
*
-
0000x
: Do
not
use.
*
-
00010
: Master connect.
*
-
00011
: Slave connect.
*
-
00100
: Page.
*
-
00101
: Page scan.
*
-
00110
: Master page response.
*
-
00111
: Slave page response.
*
-
01000
: Inquiry.
*
-
01001
: Inquiry response.
*
-
01010
: Do
not
use.
*
-
01011
: Do
not
use.
*
-
011xx
: Do
not
use.
*
-
10xxx
: Do
not
use.
*
-
11000
: Master Broadcast.
*
-
11001
: Broadcast Scan.
*
-
11010
: Master Access window.
*
-
11011
: Slave Access window
1.
*
-
11100
: Slave Access window
2.
*
-
11101
: Do
not
use.
*
-
1111x
: Do
not
use
*
/
#define EM_BT_CS_FMT_MST_CONNECT 0x02
#define EM_BT_CS_FMT_SLV_CONNECT 0x03
#define EM_BT_CS_FMT_PAGE 0x04
#define EM_BT_CS_FMT_PAGE_SCAN 0x05
#define EM_BT_CS_FMT_MST_PAGE_RSP 0x06
#define EM_BT_CS_FMT_SLV_PAGE_RSP 0x07
#define EM_BT_CS_FMT_INQUIRY 0x08
#define EM_BT_CS_FMT_INQ_RSP 0x09
#define EM_BT_CS_FMT_MST_BCST 0x18
#define EM_BT_CS_FMT_BCST_SCAN 0x19
#define EM_BT_CS_FMT_MST_ACC_WIN 0x1A
#define EM_BT_CS_FMT_SLV_ACC_WIN1 0x1B
#define EM_BT_CS_FMT_SLV_ACC_WIN2 0x1C
#define TX_LM_BUF_PTR (*((uint32_t *)0x3ffb23c2))
#define TX_PTR (*((uint32_t *)0x3ffb23ba))
#define TX_ACL_BUF_PTR (*((uint32_t *)0x3ffb23c0))
#define TX_PHEADER (*((uint32_t *)0x3ffb23be))
#define TX_HEADER (*((uint32_t *)0x3ffb23bc))
#define TX_DESCPTR (*((uint32_t *)0x3ffb1e0a))
#define ACL_DM_PRIO_CNTL (*((uint32_t *)0x3ffb1e50))
#define SCO_DM_PRIO_CNTL (*((uint32_t *)0x3ffb1e52))
#define FR_CNTL (*((uint32_t *)0x3ffb1dee))
#define PWR_CNTL (*((uint32_t *)0x3ffb1e04))
#define BDADDR0 (*((uint32_t *)0x3ffb1df8))
#define BDADDR1 (*((uint32_t *)0x3ffb1dfa))
#define BDADDR2 (*((uint32_t *)0x3ffb1dfc))
#define BCH0 (*((uint32_t *)0x3ffb1dfe))
#define BCH1 (*((uint32_t *)0x3ffb1e00))
#define RXMAXBUF_BCH2 (*((uint32_t *)0x3ffb1e02))
#define TXRX_CNTL (*((uint32_t *)0x3ffb1e06))
#define ACL_TX_STAT (*((uint32_t *)0x3ffb1e4c))
#define WIN_CNTL (*((uint32_t *)0x3ffb1e08))
#define BIT_OFF (*((uint32_t *)0x3ffb1df0))
#define CLK_OFF0 (*((uint32_t *)0x3ffb1df2))
#define CLK_OFF1 (*((uint32_t *)0x3ffb1df4))
#define LINK_CNTL (*((uint32_t *)0x3ffb1df6))
#define ACL_RX_STAT (*((uint32_t *)0x3ffb1e4e))
uint32_t reversed_ld_page_em_init(void)
{
uint8_t bVar1;
char cVar2;
int
iVar3;
ushort
*
puVar4;
int
iVar5;
ushort
*
puVar6;
ushort
*
puVar7;
ushort
*
puVar8;
iVar5
=
ld_page_env;
bVar1
=
*
(uint8_t
*
)(ld_page_env
+
0x41
);
iVar3
=
(uint)bVar1
*
0x66
;
/
/
FR_CNTL
puVar4
=
(ushort
*
)(&FR_CNTL
+
iVar3);
/
/
PWR_CNTL
puVar8
=
(ushort
*
)(&PWR_CNTL
+
iVar3);
/
/
em_bt_frcntl_format_setf(EM_BT_CS_FMT_PAGE)
/
/
FORMAT
=
FRCNTL[
0
:
4
]
0x
f f e
0
=
0b
1111
1111
1110
0000
/
/
4
:Page
*
puVar4
=
*
puVar4 &
0xffe0
|
4
;
/
/
em_bt_bdaddr0_setf
*
(uint16_t
*
)(&BDADDR0
+
iVar3)
=
*
(uint16_t
*
)(iVar5
+
0x28
);
/
/
em_bt_bdaddr1_setf
*
(uint16_t
*
)(&BDADDR1
+
iVar3)
=
*
(uint16_t
*
)(iVar5
+
0x2a
);
/
/
em_bt_bdaddr2_setf
*
(uint16_t
*
)(&BDADDR2
+
iVar3)
=
*
(uint16_t
*
)(iVar5
+
0x2c
);
/
/
em_bt_bch0_setf
*
(uint16_t
*
)(&BCH0
+
iVar3)
=
*
(uint16_t
*
)(iVar5
+
0x44
);
/
/
em_bt_bch1_setf
*
(uint16_t
*
)(&BCH1
+
iVar3)
=
*
(uint16_t
*
)(iVar5
+
0x46
);
/
/
em_bt_rxmaxbuf_bch2_pack
*
(ushort
*
)(&RXMAXBUF_BCH2
+
iVar3)
=
(ushort)
*
(uint8_t
*
)(iVar5
+
0x48
) &
3
;
/
/
em_bt_pwrcntl_txpwr_setf
*
puVar8
=
(ushort)rwip_rf[
44
] |
*
puVar8 &
0xff00
;
/
/
TXRX_CNTL
puVar6
=
(ushort
*
)(&TXRX_CNTL
+
iVar3);
/
/
em_bt_txrxcntl_txeir_setf
*
puVar6
=
*
puVar6 &
0xfff7
;
/
/
ACL_TX_STAT
puVar7
=
(ushort
*
)(&ACL_TX_STAT
+
iVar3);
/
/
em_bt_acltxstat_txtog_setf
*
puVar7
=
*
puVar7 &
0x7fff
;
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!