夜深人静之时,我独自栖息在宾馆之中,身边只有一台智能电视和其他智能家具,那么是时候打开 Wireshark 了,别问我想做什么,换作是你们也会这么做。
但很快我惊讶的发现有大量来自 2046 端口的 UDP 流量,这是一个非标准端口,我完全不知道它是干什么的,看来只能手动分析了。
起初,我看着面前的智能电视,我以为是电视的流量,但对视频流量来说我抓取流量里数据包的长度似乎又太小了,差不多也就只有视频一帧大小的样子。
这些 UDP 数据包的目标地址不是我的 IP 地址,而我也不需要进行 ARP 欺骗,因为它发向了所有人。在仔细分析后,我发现这些都是 组播 数据包,这也就是说这些数据包是由一台设备发出由多台设备同时接收的。另外,我还注意到了一点,那就是这些数据包全部都拥有相同的长度(634 字节)。
现在我决定写一个 Python 脚本来保存并分析这些数据。首先,我们需要接收这些组播数据包,下列代码中的组播地址 234.0.0.2
是我从 Wireshark 中抓取出来的。
import socket import struct s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) s.bind(('', 2046)) mreq = struct.pack("4sl", socket.inet_aton("234.0.0.2"), socket.INADDR_ANY) s.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq) while True: data = s.recv(2048) print(data)
在此之前,我也使用过 binascii 来将输出转换为十六进制,这样更容易读取字节数。在盯着屏幕上控制台里闪过上千行后,我注意到所有数据包的前 15 个字节都是一样的,而这些相同的字节可能就是在表示所使用的协议或者数据包/命令 ID。
在花了相当长的时间后,我才尴尬的发现每个数据包结尾的字符串都为 LAME3.91UUUUUUU
,我猜这应该就是 MPEG 音频数据包。但当我将其中一个数据包保存为 test.mp3 后竟然无法使用 mplayer 播放,而使用 file
命令却只能识别为 test.mp3: data
。这数据包显然存的都是数据啊,我希望的是 file
命令能识别出它是MPEG 音频数据,没办法我只好重新在写另一个 Python 脚本来增加偏移量保存数据。这回我会将要保存为 test1
文件的偏移 1 个字节,将 test2
文件偏移 2 个字节,以此类推,代码如下:
data = s.recv(2048) for i in range(25): open("test{}".format(i), "wb+").write(data[i:])
然后执行命令 file test*
,这回我们发现在偏移 8 个字节后的数据终于被识别为了 MPEG 音频数据。
$ file test* test0: data test1: UNIF v-16624417 format NES ROM image test10: UNIF v-763093498 format NES ROM image test11: UNIF v-1093499874 format NES ROM image test12: data test13: TTComp archive, binary, 4K dictionary test14: data test15: data test16: UNIF v-1939734368 format NES ROM image test17: UNIF v-1198759424 format NES ROM image test18: UNIF v-256340894 format NES ROM image test19: UNIF v-839862132 format NES ROM image test2: UNIF v-67173804 format NES ROM image test20: data test21: data test22: data test23: DOS executable (COM, 0x8C-variant) test24: COM executable for DOS test3: UNIF v-1325662462 format NES ROM image test4: data test5: data test6: data test7: data test8: MPEG ADTS, layer III, v1, 192 kbps, 44.1 kHz, JntStereo test9: UNIF v-2078407168 format NES ROM image
while True: data = s.recv(2048) sys.stdout.buffer.write(data[8:])
现在我们需要做的就是不断的抓取数据包,在偏移 8 个字节后将数据保存下来,而这个保存下来的文件也应当可以直接进行播放了。
在知道这些数据包是音频后,另一个问题也就随之而来,这些音频到底是什么?是与我房间智能电视相关的数据?还是与酒店系统相关的东西?不乱猜,让我们来听听到底是什么吧。
$ python3 listen_2046.py > test.mp3 * wait a little to get a recording * ^C $ mplayer test.mp3 MPlayer (C) 2000-2016 MPlayer Team 224 audio & 451 video codecs Playing test.mp3. libavformat version 57.25.100 (external) Audio only file format detected. ===== Starting playback... A: 3.9 (03.8) of 13.0 (13.0) 0.7%
啊嘞?完全不敢相信,我花费大量时间探索的东西,竟然是电梯间的背景音乐。哦好吧,不过我现在至少可以在房间里听这些音乐了。
*原文: gkbrk ,FB小编xiaix编译,转自须注明来自FreeBuf黑客与极客(FreeBuf.COM)