Object Exchange(obex) 蓝牙对象交换协议

流量概览

wireshark打开(需要将配置文件profile切换成蓝牙):

image-20250703094158144

查看流量包属性, 可以看到抓包的系统信息和接口信息:

image-20250703094457856

接口只有一个TCP@127.0.0.1:24352, 可能是通过工具进行抓包再通过tcp端口进行流量转发到wireshark

查看蓝牙设备, 找到本地适配器, 即抓包的设备蓝牙信息, 可以看到抓包机器的名字为INFERNITYのPC:

image-20250703095347333

再看协议分级, 发现占比最多的obex协议:

image-20250703095040752

在流量的最后也发现了obex的传输流量:

image-20250703095113018

数据恢复

过滤obex:

1
obex

image-20250703095737626

发现传输数据

Rcvd Connect代表收到连接请求, Sent Success代表发送成功

之后的每个Rcvd OBEX fragment都是数据帧, 对于大文件, obex会将文件数据拆分成帧进行传输

在传输n个帧之后接收方会发送一个确认包, 确认这次发送的包已经收到

在66帧之后发现接收方的确认包Rcvd Put contiune, 可以看出发送的内容是yuji.jpg:

image-20250703100359515

对于没有发送完的数据, 会重复上面的过程, 直到发送完毕Rcvd final:

image-20250703100513243

提取发送的文件可以考虑将每一个fragment提取出来再拼接

1
tshark -r .\obex.pcapng -Y "obex" -T fields -e "data.data" > data.txt

提取出来的是所有fragment的十六进制文本, 如果使用linux可以使用xxd进行转换, 或者使用010或者winhex手动操作

1
tshark -r .\obex.pcapng -Y "obex" -T fields -e "data.data" | xxd -r yuji.jpg

最后得到的文件使用010打开:

image-20250703101044241

截至ffd8之前的数据是obex协议的头部信息, 直接去除后, jpg文件的头部也被修改, ffd8ffe0被修改成ffd8ffe1, 将数据修改回去就能得到原始图片(理论上):

image-20250703101307901

但是, 由于不知名原因, 这里提取出来的数据有一部分缺失, 导致图片显示有问题, 于是采用了另外一种过滤方法

上面提到每次发送完毕, 接收方都会发送确认包确认收到, 在wireshark中会自动解析发送的是哪些包:

image-20250703102628155

实际上Rcvd Put continue包长度只有326, 但是wireshark进行了自动解析, 会显示这次发送接收的数据内容:

image-20250703102740221

也就是说提取Rcvd Put continue包中obex.header.value.byte_sequence中的数据就可以了:

1
tshark -r .\obex.pcapng -Y "obex.opcode==0x02" -T fields "obex.header.value.byte_sequence" | xxd -r yuji.jpg

同时检查了一下, jpg头部的ffd8ffe1并不会影响图片的解析和显示, 但是会影响010的模板加载, 所以这里我还是把1改成了0, 在文件尾部发现压缩包:

image-20250703103647118

其余内容

后面提取flag的过程不属于流量分析了

根据压缩包的提示, 解压密码是传输数据的电脑的名字, 上面看过了是INFERNITYのPC, 直接解压得到一张图片:

image-20250703111737344

从图像上看没有信息, 猜测是数据放到像素里了, 写个脚本把像素提出来:

1
2
3
4
5
6
7
8
from PIL import Image

img = Image.open("flag.png")
pix = img.load()

for y in range(img.height):
for x in range(img.width):
print(pix[x, y])

打印出来发现每单个像素rgb值是相同的:

image-20250703115613064

修改一下脚本, 只输出r:

1
2
3
4
5
6
7
8
from PIL import Image

img = Image.open("flag.png")
pix = img.load()

for y in range(img.height):
for x in range(img.width):
print(pix[x, y][0])

得到的十进制数直接以二进制数据形式转字符:

image-20250703115834327

找到flag:

image-20250703115852015