2018 巅峰极客CTF misc writeup
flows
拿到一个pcap包,用wireshark打开,发现是USB协议,尝试在kali下使用tshark提取,提取失败,发现异常。回到wireshark分析数据。在其中一个数据包中发现了tip
把字节分组以原始数据保存出来,得到两个tips
然后将数据包排序,把最大的两个数据导出为1.pcap和2.pcap,然后在kali下利用tshark将leftover capture data里的内容单独提取出来,命令如下:
tshark -r 1.pcap -T fields -e usb.capdata > 1.txttshark -r 2.pcap -T fields -e usb.capdata > 2.txt
参考:https://www.anquanke.com/post/id/85218 直接脚本将其中一个txt跑出来为: flag[u5b-key,Tips里提醒了shirt问题,则为: flag{u5b_key
附上脚本:(网站中给出的脚本有错误,定义mappings时\将后面的内容转义了,需要将”"转义一下”)
mappings = {0x04:"A", 0x05:"B", 0x06:"C", 0x07:"D", 0x08:"E", 0x09:"F", 0x0A:"G", 0x0B:"H", 0x0C:"I", 0x0D:"J", 0x0E:"K", 0x0F:"L", 0x10:"M", 0x11:"N",0x12:"O", 0x13:"P", 0x14:"Q", 0x15:"R", 0x16:"S", 0x17:"T", 0x18:"U",0x19:"V", 0x1A:"W", 0x1B:"X", 0x1C:"Y", 0x1D:"Z", 0x1E:"1", 0x1F:"2", 0x20:"3", 0x21:"4", 0x22:"5", 0x23:"6", 0x24:"7", 0x25:"8", 0x26:"9", 0x27:"0", 0x28:"n", 0x2a:"[DEL]", 0X2B:" ", 0x2C:" ", 0x2D:"-", 0x2E:"=", 0x2F:"[", 0x30:"]", 0x31:"\\", 0x32:"~", 0x33:";"}
nums = []
keys = open('1.txt')
for line in keys:
if line[0]!='0' or line[1]!='0' or line[3]!='0' or line[4]!='0' or line[9]!='0' or line[10]!='0' or line[12]!='0' or line[13]!='0' or line[15]!='0' or line[16]!='0' or line[18]!='0' or line[19]!='0' or line[21]!='0' or line[22]!='0':
continue
nums.append(int(line[6:8],16))
keys.close()
output = ""
for n in nums:
if n == 0 :
continue
if n in mappings:
output += mappings[n]
else:
output += '[unknown]'
print 'output :n' + output
第二个数据包为鼠标的数据,根据tips,只需要看第一个字节,将后面的字节删除,只保留第一字节,推测00为未点击,01为点击左键,02为点击右键。将txt整理好,去掉没有点击的00; 保留01和02,即左键与右键; 猜测应为左键为0,右键为1,所以将01替换为0,02替换为1,生成二进制字符串。
将两段flag拼接即可得到完整flag。
tips:第一个键盘数据包的脚本存在问题,根据tips应告示如果第一个字节为0x20就按下shift,但是脚本中无法识别第一个字节为0x20的字符,直接被忽略了,但是这里我们可以根据猜测货值直接打开txt文件手工判断也能得到flag。
warmup
注意看这张图一会会考脑洞。
拿到题目打开后是一张bmp格式的图片,由此想到LSB加密。LSB也就是最低有效位 (Least Significant Bit)。原理就是图片中的像数一般是由三种颜色组成,即三原色,由这三种原色可以组成其他各种颜色,例如在PNG图片的储存中,每个颜色会有8bit,LSB隐写就是修改了像数中的最低的1bit,在人眼看来是看不出来区别的,也把信息隐藏起来了。譬如我们想把’A’隐藏进来的话,如下图,就可以把A转成16进制的0×61再转成二进制的01100001,再修改为红色通道的最低位为这些二进制串。
既然是LSB加密,上神器stegsolve。下载地址: 密码: ckbb
打开之后,使用Stegsolve——Analyse——Frame Browser这个可以浏览三个颜色通道中的每一位,并没有发现什么有价值的信息。
之后,使用Stegsolve——Analyse——Data Extract分别提取三个颜色通道中的最低位,发现是brainfuck和Ook,在线解密:https://www.splitbrain.org/services/ook
将三段字符串拼接得到完整flag。
Loli
图片下载下来,根据题目hint,想到使用0xFF异或整个文件(这我也不知道怎么想到的。。看了wp才知道这样做),脚本如下:
#!/usr/bin/env python
# coding=utf-8
def xor():
with open('./1.png', 'rb') as f, open('xor.png', 'wb') as wf:
for each in f.read():
wf.write(chr(ord(each) ^ 0xff))
if __name__ == '__main__':
xor()
得到新的png文件
使用二进制编辑器观察尾部,看到提示“black and white”,以及“IEND”标识,这是png的文件尾部,暗示该文件中隐藏了一个png文件。
使用 foremost 命令直接提取或者直接手扣一个png
观察png文件,可以看到色块分为11列,每列隔行的色块永远是黑色,这说明应该横向读取图片,而列中的横长条由8个小色块组成,显然其代表的是一个字节的数据。
按上述思路使用脚本提取该信息:
import matplotlib.image as mpimg
res_str = []
res = []
def readpng():
png = mpimg.imread('./out.png')
yy, xx, depth = png.shape
for y in range(yy):
if y % 2 == 0:
for x in range(1, xx - 1, 9):
_str = "0b" + str(int(png[y][x][0])) + str(int(png[y][x + 1][0])) + str(int(png[y][x + 2][0])) + str(int(png[y][x + 3][0])) + str(int(png[y][x + 4][0])) + str(int(png[y][x + 5][0])) + str(int(png[y][x + 6][0])) + str(int(png[y][x + 7][0]))
res_str.append(_str)
res.append(bin2hex(_str))
print res_str
with open('res.bin', 'wb') as f:
for each in res:
f.write(chr(each))
def bin2hex(_bin="0b101"):
return int(_bin, 2) ^ 0xFF
if __name__ == '__main__':
readpng()
得到二进制文件,只用cat命令即可获取flag
总结
CTF脑洞是真的重要,有些东西根本想不到或者不知道怎么想到的。另外,这次misc题目让我更加了解了stegsolve的用法,以前一般都是一起整体提取三个颜色的最低位,没想到还可以分别提取。还有就是了解了USB数据包的方法以及一般做题步骤。还是要多积累。加油!!!