2018巅峰极客writeup(Misc)

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/baidu_28226047/article/details/81238763

原文地址:https://mistsatan.github.io/articles/2018-Peakgeek-Writeup-Misc.html

作为一个渣渣,带着去看各路神仙打架的想法报名了这次的“巅峰极客”CTF比赛,7.21第一场线上赛果然从头水到尾。。。
为了方便之后巩固,把近几天学习大佬们的writeup过程中总结整理的内容记录下来,第一次写成博客。

我只是个搬运工,以下是众大佬们的writeup:


Misc

1.warmup - 100pt

首先拿到一张图片warmup.bmp,用Stegsolve打开:

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,写出脚本如下:

from PIL import Image

def getBinaryToChar():
    count = 0
    ans = ""
    binStr = ""
    # 转换成灰度图像(黑点0,白点255)
    img = Image.open('./noname.png').convert('L')
    # 遍历像素点(按行读)
    width, height = img.size
    for h in range(height - 1): # 是否-1均可,最后一行是11个0111111111
        for w in range(width - 1):  # 需要-1,最后一列全是0
            pixel = img.getpixel((w, h))
            if pixel == 0:
                color = 1   # 黑点置1
            else:
                color = 0   # 白点置0
            # 9个点一组,构成0xxxxxxxx
            count += 1
            ans += str(color)
            if count == 9:
                if ans != "011111111":
                    binStr += chr(int(ans,2))
                count = 0
                ans = ""
    return binStr

if __name__ == '__main__':
    strr = getBinaryToChar()
    print strr
    with open('res.txt', 'wb') as f:
        f.write(strr)

打开得到的res.txt,看到flag:
这里写图片描述
flag{e0754197-e3ab-4d0d-b98f-96174c378a34}


3.flows - 200pt

拿到一个pcap包,用wireshark打开,发现是USB协议。
按照协议排序,一个个点击查看包内容,发现有个包(95)里面疑似有tips:
tips
将数据另存到txt中,打开可以看到两个提示:
提示
继续查看包,发现两个长度比较大的包很可疑(55和74):
两个可疑包
分别将数据另存出来,用010打开,看到这两个文件头都是D4C3B2A1,就是pcap文件:
文件头D4C3B2A1
修改后缀为.pcap,用wireshark打开,有效数据存放在leftover capture data这里:
这里写图片描述
用wireshark自带的tshark把leftover capture data的内容提取出来:
【tshark命令行详细参见这里

tshark -r pack55.pcap -T fields -e usb.capdata > pack55.txt
tshark -r pack74.pcap -T fields -e usb.capdata > pack74.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键,在大佬的脚本基础上稍作修改,脚本如下:

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",0x29:"[ESC]", 0x2A:"\b", 0X2B:"\t",
             0x2C:" ", 0x2D:"-", 0x2E:"=", 0x2F:"[", 0x30:"]",
             0x31:"\\",0x32:"`", 0x33:";", 0x34:"'", 0x36:",",
             0x37:".", 0x38:"/" }

mappings_shift = { 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:"!", 0x1F:"@", 0x20:"#", 0x21:"$",
                   0x22:"%", 0x23:"^", 0x24:"&", 0x25:"*", 0x26:"(",
                   0x27:")", 0x28:"\r",0x29:"[ESC]", 0x2A:"\b", 0X2B:"\t",
                   0x2C:" ", 0x2D:"_", 0x2E:"+", 0x2F:"{", 0x30:"}",
                   0x31:"|", 0x32:"~", 0x33:":", 0x34:"\"",0x36:"<",
                   0x37:">", 0x38:"?" }

def keyboard_extract():
    output = ""
    keys = open('pack55.txt')
    for line in keys:
        if len(line)!= 24:
            continue
        list = line.split(":")
        if list[2]=='00':
            continue
        num = int(list[2],16)
        if num in mappings:
            if list[0] == '02':
                output += mappings_shift[num]
            elif list[0] == '00':
                output += mappings[num]
        else:
            output += '[unknown]'
    keys.close()
    print output

if __name__ == '__main__':
    keyboard_extract()

第二个包pack74.txt为鼠标数据包,按照第二个tips,只关注第一个字节,猜测01表示0,02表示1,将其提取出来,脚本如下:

import re

def bin2str(bin):
    str = ''
    mo = len(bin)%8
    if (mo):
        bin= '0'*(8-mo) + bin
    chars = re.findall(r'.{8}',bin)
    for char in chars:
        str += chr(int(char, 2))
    return str

def mouse_extract():
    binstr = ""
    keys = open('pack74.txt')
    for line in keys:
        list = line.split(":")
        if list[0]=='00':
            continue
        elif list[0] == '01':
            binstr += "0"
        elif list[0]=='02':
            binstr += "1"
    str = bin2str(binstr)
    keys.close()
    print str

if __name__ == '__main__':
    mouse_extract()

分别运行以上两个脚本,得到两个字符串,拼起来就是flag了:

  • flag{u5b_key
  • bo4rd_m0use}

flag{u5b_keybo4rd_m0use}


展开阅读全文

没有更多推荐了,返回首页