ACSC Quals 2023 - pcap 1, 2

题目下载地址:

https://pan.baidu.com/s/1sD2OhS5asS3v2fy8WgAjNg?pwd=aaaa 

pcap-1

题目描述:

50 pts
​
这是我在 Google 幻灯片上准备演示文稿时捕获的计算机数据包。 你能重现幻灯片的内容吗?
注意:如果您发现“fake flag”,请在此处提交。 flag旁边的一些文字说它不被接受,但现在它被接受了。 挑战中有 2 个flag,都被接受。 第 1 部分接受更容易获得的flag。
​
authored by daniellimws
​
Here is a packet capture of my computer when I was preparing my presentation on Google Slides. Can you reproduce the contents of the slides?
​
Note: If you find a "fake flag", submit it here. Some text next to the flag says that it is not accepted, but now it is. There are 2 flags in the challenge, and both are accepted. Part 1 accepts the flag that is easier to get.

pcap-2

题目描述:

200 pts
​
authored by daniellimws
​
Here is a packet capture of my computer when I was preparing my presentation on Google Slides. Can you reproduce the contents of the slides?
​
Note: If you find a "fake flag", submit it in pcap-1. Some text next to the flag says that it is not accepted, but now it is. There are 2 flags in the challenge, and both are accepted. Part 1 accepts the flag that is easier to get.

pcap-1

分析

通过观察协议层次结构统计,我发现大多数互联网数据包都是加密流量。

 

所以我决定分析 USB 流量。

查找HID设备的INTERFACE Descriptor响应,识别键盘和鼠标的地址。 过滤器:

usb.transfer_type == 2 && usb.endpoint_address.direction == 1 && usb.bDescriptorType == 4 && usb.bInterfaceClass == 3

 

通过bInterfaceProtocol字段,很容易发现usb.device_address == 12是键盘,usb.device_address == 13是鼠标。

使用 tshark 从 usbhid.data 字段中提取数据,同时保留 usb.device_address 以供进一步处理。 由于设备引起的URB_INTERRUPT帧长等于72,所以我也将其应用于过滤。

"C:\Program Files\Wireshark\tshark.exe" -r capture.pcapng -T fields -E separator=, -e usb.device_address -e usbhid.data "(usb.device_address == 12 || usb.device_address == 13) 
&& usb.bus_id == 1 && usb.transfer_type == 1 && usb.endpoint_address.direction == 1 && frame.len == 72" > time.txt

输出结果形式如下。其中逗号前的数字为设备地址,其余为HID数据。:

...
13,0100ff000000ffff
13,0100ff000000ffff
13,0101000001000000
13,0101000001000000
13,0000000000000000
13,0000000000000000
13,0000010000000100
13,0000010000000100
12,0000160000000000
12,0000160000000000
12,0000000000000000
...

处理数据

我们可以参考 HID 规范或简单的 wireshark 来了解如何解码数据。

键盘:

 

鼠标:

 

在keyboard部分,我修改自naykisec的USB Keyboard抓包分析,但是去掉了multiline部分。 我还使用缓冲区对输入文本进行重复数据删除,否则输出将如下所示:

sslliiddddeeeessss..ggggoooogglleeee..ccoooommCCTTFF    IInnttttttrroo  PPrrrreesssseeeennttaaaattiiiioonnHHooww  ttoo  bbee  ggoooodd  aaaatt  CCTTFFss//AA  bbeeggiinnnneeeerr''ss    gguuuuiiddddeeDDoonnoottcchheeaaaattGGgguuuueessssiiiinnnnggiissggooooddTTtthhiiiiss  iiiiss  aaaannnn    eexxxxaaaammpppppplleeee  ooooffff  aaaa  ffllllaaaagg::AACCSSCC{{ff00rr33nnss11ccss__iiss__ss00__ffuunn}}IIff    yyoooouuuu  ccccaaaann    rrrreeeeeeaaaadd  tttttthhiissss  mmmmeessssaaggggee  ccoonnnnggrraaaattss!!11BBuuuutt    tttthheeee  ffllaaaagggg  yyoooouu  sssseeeeee  nnnnooww  iiiissss  nnnnooootttt    tthhhheeee  aacccceeeepptteeeeeedd  ffllllaaaagg..IInnssppeeeecctt    tttthhhheeee  ppppaaaacccckkeeeettttssss  mmmmmmmmrrrreeee  ddddeeeeppllyy  aaaanndddd  yyoooouuuu  wwwwiillll  rrrreevvvveeaaaall  mmmmmmrrrreeee  iiiinnffoorrrrmmaaaattiiiioonn    aaaabboooouuuutttt  wwwwhhhhaaaatttt  iissss  hhhhaaaappppeeeenniiiinngg..II''mm    wwwwrrrriittttiiiinnnngggg  tttthhhhhhiissss    hheerrrree  ootthhhheeeerrrrwwiissssee  1111000000  ppeeeeoooopppplllleeee    wwiillll    ddmm  mmmmeeee  ttttoo  ssssaayy    tttthhaaaatt    tttthhee  ffllaaaagggg  iiss  nnnnooootttt  wwoorrrrkkiiiinnnngg  oooooorr    tthhhheeee  cccchhaalllleennggggee  iiiissss  bbrrookkeenn..BBttww    II  ddoonn''tttt  lliikkeeee  ffoorreennssssiiccccssss  ttoooo..  ::))

解析键盘流量exp:

USB_CODES = {
    0x04:"aA", 0x05:"bB", 0x06:"cC", 0x07:"dD", 0x08:"eE", 0x09:"fF",
    0x0A:"gG", 0x0B:"hH", 0x0C:"iI", 0x0D:"jJ", 0x0E:"kK", 0x0F:"lL",
    0x10:"mM", 0x11:"nN", 0x12:"oO", 0x13:"pP", 0x14:"qQ", 0x15:"rR",
    0x16:"sS", 0x17:"tT", 0x18:"uU", 0x19:"vV", 0x1A:"wW", 0x1B:"xX",
    0x1C:"yY", 0x1D:"zZ", 0x1E:"1!", 0x1F:"2@", 0x20:"3#", 0x21:"4$",
    0x22:"5%", 0x23:"6^", 0x24:"7&", 0x25:"8*", 0x26:"9(", 0x27:"0)",
    0x2C:"  ", 0x2D:"-_", 0x2E:"=+", 0x2F:"[{", 0x30:"]}",  0x32:"#~",
    0x33:";:", 0x34:"'\"",  0x36:",<",  0x37:".>",
    0x38: "//"
}
​
pos = {
    "x": 6000,
    "y": 350
}
​
mouse = False
​
MOUSE_UP = 1
MOUSE_DOWN = -1
​
def twocmp(s):
    t, i = str.maketrans("01", "10"), s.rfind("1")
    return s[:i].translate(t) + s[i:] if i != -1 else s
​
def handle_mouse(move):
    move = int(move, 16)
​
    global pos, mouse
​
    # little endian
    delta_x = ((move & 0xff0000) >> 8) + ((move & 0xff000000) >> 24)
    delta_y = ((move & 0xff) << 8) + ((move & 0xff00) >> 8)
​
    control = (move & (0xff << 56)) >> 56
​
    event = 0
​
    # left click
    if control ^ int(mouse):
        if control:
            event = MOUSE_DOWN
            mouse = True
        else:
            event = MOUSE_UP
            mouse = False
​
    if delta_x & 0b1 << 15:
        delta_x = -1 * int(twocmp(f"{delta_x:b}"), 2)
​
    if delta_y & 0b1 << 15:
        delta_y = -1 * int(twocmp(f"{delta_y:b}"), 2)
​
    if delta_x == 0 and delta_y == 0 and not event:
        return None
​
    pos["x"] = max(min(pos["x"] + delta_x, 6000), 0)
    pos["y"] = max(min(pos["y"] + delta_y, 4000), 0)
​
    return event, pos["x"], pos["y"]
​
key_buffer = []
key_cache = []
​
def array(arr):
    ret = []
    for i in range(0, len(arr), 2):
        val = int(arr[i:i+2], 16)
        if val == 0:
            break
        ret.append(val)
​
    return ret
​
def handle_keyboard(hid):
    global key_cache
​
    codes = array(hid[2*2:])
    control_keys = int(hid[2*0:2*0+2], 16)
    shift = control_keys & 0b10 or control_keys & 0b00100000
​
    tmp = []
    down = []
​
    for code in codes:
        char = None
​
        if not USB_CODES.get(code):
            # newline or down arrow - move down
            if code == 0x51 or code == 0x28:
                char = "↑"
            # up arrow - move up
            if code == 0x52:
                char = "↓"
            # backspace
            if code == 0x2a:
                char = "←"
        else:
            # select the character based on the Shift key
            if shift:
                char = USB_CODES[code][1]
            else:
                char = USB_CODES[code][0]
​
        if not char:
            continue
​
        if char not in key_buffer:
            key_buffer.append(char)
            down.append(char)
​
        tmp.append(char)
​
    for c in key_cache:
        if c not in tmp:
            key_buffer.remove(c)
​
    key_cache = tmp
​
    return down
    
DEVICE_MOUSE = "13"
DEVICE_KBOAD = "12"
​
last_move = (0, 0)
​
def distance(a, b):
    return abs(a[0] - b[0]) + abs(a[1] - b[1])
​
with open("preview.txt", "w", encoding="utf-8") as wf:
    with open("time.txt") as f:
        for l in f.readlines():
            device, raw_data = l.split(",")
​
            if device == DEVICE_MOUSE:
                res = handle_mouse(raw_data)
                if res is not None:
                    if res[0] != 0 or distance(res[1:3], last_move) > 100:
                        print(device, *res, sep=",", file=wf)
                        last_move = res[1:3]
            elif device == DEVICE_KBOAD:
                res = handle_keyboard(raw_data)
                if res:
                    if type(res) == list:
                        # key down list
                        print(device, *res, sep=",", file=wf)
                    else:
                        print(device, res, sep=",", file=wf)

usb_codes = {
    0x04:"aA", 0x05:"bB", 0x06:"cC", 0x07:"dD", 0x08:"eE", 0x09:"fF",
    0x0A:"gG", 0x0B:"hH", 0x0C:"iI", 0x0D:"jJ", 0x0E:"kK", 0x0F:"lL",
    0x10:"mM", 0x11:"nN", 0x12:"oO", 0x13:"pP", 0x14:"qQ", 0x15:"rR",
    0x16:"sS", 0x17:"tT", 0x18:"uU", 0x19:"vV", 0x1A:"wW", 0x1B:"xX",
    0x1C:"yY", 0x1D:"zZ", 0x1E:"1!", 0x1F:"2@", 0x20:"3#", 0x21:"4$",
    0x22:"5%", 0x23:"6^", 0x24:"7&", 0x25:"8*", 0x26:"9(", 0x27:"0)",
    0x2C:"  ", 0x2D:"-_", 0x2E:"=+", 0x2F:"[{", 0x30:"]}",  0x32:"#~",
    0x33:";:", 0x34:"'\"",  0x36:",<",  0x37:".>"
    }
​
lines = ["","","","",""]
​
pos = 0
​
for x in open("data.txt","r").readlines():
    code = int(x[6:8],16)
​
    if code == 0:
        continue
    # newline or down arrow - move down
    if code == 0x51 or code == 0x28:
        pos += 1
        continue
    # up arrow - move up
    if code == 0x52:
        pos -= 1
        continue
​
    # select the character based on the Shift key
    if int(x[0:2],16) == 2:
        lines[pos] += usb_codes[code][1]
    else:
        lines[pos] += usb_codes[code][0]
​
​
for x in lines:
    print x

删除重复数据,得到:

slides.google.comCTF Intro PresentationHow to be good at CTFs/A beginner's guideDonotcheatGguessingisgoodTthis is an example of a flag:ACSC{f0r3ns1cs_is_s0_fun}If you can read this message congrats!1But the flag you see now is not the accepted flag.Inspect the packets more deeply and you will reveal more information about what is happening.I'm writing this here otherwise 1000 people will dm me to say that the flag is not working or the challenge is broken.Btw I don't like forensics too. :)
​

pcap-1 的flag就是:

ACSC{f0r3ns1cs_is_s0_fun}

pcap-2

通过提示知道,这是Google的PPT文档。主要的鼠标、键盘操作如下图所示。

 

整个操作预览如下链接:

https://acsc-2023-quals-pcap-preview.pages.dev/preview

在鼠标流量分析时,数据包中的X和Y坐标(各2个字节,little endian)实际上是移动的偏移(相对位置),而不是具体的位置坐标(绝对位置),所以我将其转换为绝对位置坐标以便于可视化。 此外,我还标记了 mouseup 和 mousedown 事件,因此我可以识别拖动行为。

为了防止鼠标溢出屏幕,我把画布限制在6000 * 4000。 为了使动画更快,只会显示距离足够远的点( |x\prime - x| + |y\prime - y| > 100 )。

运行 python parse.py 将 time.txt 转换为 preview.txt 以进行可视化。

我利用web页面进行可视化。

粉红色的点代表 mousedown 点击,蓝色的点是作者开始输入的光标位置。 如果作者此时按下鼠标,光标将变为红色。

由于我的屏幕不够大,我将轴缩放了 0.2 以适应所有点击。

通过观察粉红色和蓝色圆点的出现顺序、位置以及输入时间,我们可以猜测在文本框中输入了一些文本。 (例如,Do,not,cheat,Guessing,is,good,ACSC{ 等) slides.google.com 周围经常出现的粉红色圆点可能是创建新文本框的菜单。

了解了文本框后,可以发现这些文本框是通过拖动来重新排列的。 所以只要跟踪哪个文本框被拖到了哪里,我们就可以解决第 2 部分的标志。

flag: ACSC{Guessing_is_not_good}

为了让这个过程更清晰,我制作了一个版本(在游戏之后)来标记文本框的位置,以及它们是如何被拖来拖去的。 请使用 preview-textbox.js 而不是我在比赛中使用的那个 (preview.js)。

演示:

在线演示

https://acsc-2023-quals-pcap-preview.pages.dev/preview

附: 因为无法 fetch() 本地文件,你必须使用 web 服务器打开它,例如 python -m http.server。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jia9iniu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值