作为一个渣渣,带着去看各路神仙打架的想法报名了这次的“巅峰极客”CTF比赛,7.21第一场线上赛果然从头水到尾。。。
为了方便之后巩固,把近几天学习大佬们的writeup过程中总结整理的内容记录下来,第一次写成博客。
我只是个搬运工,以下是众大佬们的writeup:
1. warmup - 100pt
首先拿到一张图片warmup.bmp,用Stegsolve打开:
1 | java -jar Stegsolve.jar |
经大佬们发现,RGB三个通道的LSB都是明显有数据在的(我眼瞎,当时翻来覆去好几遍真没看出来):
分别查看各个通道的LSB,发现了存放的数据是用Ook!和brainfuck加密的:
分别将三块数据保存出来,用这个网站在线解密,得到以下三部分内容,拼起来就是flag:
- flag{db640436-
- 7839-4050-8339
- -75a972fc553c
flag{db640436-7839-4050-8339-75a972fc553c}
2. loli - 150pt
拿到一张图片1.png,看起来像二维码,用工具扫描,得到一个提示255:
根据另一个提示0xFF,将1.png放到WinHex中,0xFF异或整个文件,在得到的文件末尾看到字符串“black and white”:
用binwalk查看得到的文件,发现其中包含了一个图片:
根据隐藏图片的偏移,用WinHex将图片提取出来,能够看到,图片中,按照行来看,以8个像素点(黑/白)为一组,每一组之间用白点来分隔,根据前面“black and white”提示,不难联想到应该是二进制流转换成字符:
参考各大佬的writeup,写出脚本如下:
1 | from PIL import Image |
打开得到的res.txt,看到flag:
flag{e0754197-e3ab-4d0d-b98f-96174c378a34}
3. flows - 200pt
拿到一个pcap包,用wireshark打开,发现是USB协议。
按照协议排序,一个个点击查看包内容,发现有个包(95)里面疑似有tips:
将数据另存到txt中,打开可以看到两个提示:
继续查看包,发现两个长度比较大的包很可疑(55和74):
分别将数据另存出来,用010打开,看到这两个文件头都是D4C3B2A1,就是pcap文件:
修改后缀为.pcap,用wireshark打开,有效数据存放在leftover capture data这里:
用wireshark自带的tshark把leftover capture data的内容提取出来:
【tshark命令行详细参见这里】
1 | tshark -r pack55.pcap -T fields -e usb.capdata > pack55.txt |
接下来就需要从txt文件中过滤出键盘击键和鼠标相关的流量:
【这里主要参考这位大佬的博客以及这个博客】
键盘数据包的数据长度为8个字节。每次key stroke都会产生一个keyboard event usb packet(所以第一个tips所说第一个字节为02表示按下了Left Shift键)
Byte1
|--bit0: Left Control 是否按下,按下为1 |--bit1: Left Shift 是否按下,按下为1 |--bit2: Left Alt 是否按下,按下为1 |--bit3: Left GUI 是否按下,按下为1 |--bit4: Right Control 是否按下,按下为1 |--bit5: Right Shift 是否按下,按下为1 |--bit6: Right Alt 是否按下,按下为1 |--bit7: Right GUI 是否按下,按下为1
Byte2 暂不清楚,有的地方说是保留位
Byte3-Byte8 这六个为普通按键,击键信息集中在第3个字节鼠标数据包的数据长度为4个字节。鼠标移动时表现为连续性,与键盘击键的离散性不一样,不过实际上鼠标动作所产生的数据包也是离散的
Byte1 代表按键,当取0x00时,代表没有按键、为0x01时,代表按左键,为0x02时,代表当前按键为右键
Byte2 可以看成是一个signed byte类型,其最高位为符号位,当这个值为正时,代表鼠标水平右移多少像素,为负时,代表水平左移多少像素
Byte3 与第二字节类似,代表垂直上下移动的偏移
第一个包pack55.txt为键盘数据包,需要按照对应关系将键盘按键输出出来,根据第一个tips,注意第一个字节为02表示按了shift键,在大佬的脚本基础上稍作修改,脚本如下:
1 | mappings = { 0x04:"a", 0x05:"b", 0x06:"c", 0x07:"d", 0x08:"e", |
第二个包pack74.txt为鼠标数据包,按照第二个tips,只关注第一个字节,猜测01表示0,02表示1,将其提取出来,脚本如下:
1 | import re |
分别运行以上两个脚本,得到两个字符串,拼起来就是flag了:
- flag{u5b_key
- bo4rd_m0use}
flag{u5b_keybo4rd_m0use}