首页
社区
课程
招聘
[原创]BrakTooth学习笔记
发表于: 2023-4-15 16:22 14025

[原创]BrakTooth学习笔记

2023-4-15 16:22
14025

学习论文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收购TensilicaXtensa,只用了标量单元(矢量单元侧重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)寄存器读写和链路层寄存器读写进行手动标注,版本不同相关寄存器也有差异,需要猜测。比如对BrakToothROM 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:40x 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:40x 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;

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

最后于 2023-4-16 14:43 被vasthao编辑 ,原因:
收藏
免费 0
支持
分享
最新回复 (1)
雪    币: 3070
活跃值: (30876)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
感谢分享
2023-4-15 22:39
1
游客
登录 | 注册 方可回帖
返回
//