碎碎念

确实是新生赛水平)最后咱们拿了第七,又学到了新的知识点(感觉每次比赛都在学新的),另外lunatic师傅yyds image-20250420201918620

three

知识点省流

盲水印+厨子+流量包找密码

WP

ez套娃

part1直接告诉我们是盲水印了,甚至给了个jar文件提示

image

part就是简单的编码套娃,丢给厨子秒了

image

part3就是在流量包里找到密码解密即可,过滤http发现有蚁剑流量,传了一个pass.txt,所以看他的回显,发现有很多密码,都试试就行

image

小套不是套

知识点省流

伪加密+crc爆破+oursecret

WP

medium套娃

二维码扫码得到tess的压缩包密码

image

解压后还有一个加密压缩包,但是没信息了,看了看其实是伪加密,010处理后解压得到一张jpg图片,用010看看会发现下面藏了一个缺了文件头的png图片

image

提取出来后可以发现png尾巴还有东西,这个特征是oursecret隐写,但是需要密码

image

而我们还有另一个加密压缩包,可以看到里面的文件大小都是4字节,可以想到是crc爆破,用https://github.com/AabyssZG/CRC32-Tools这个工具爆一下

image

爆破后得到两个信息,其一这是base64字符串,其二顺序是乱的(它的文件顺序并不是命名顺序),所以我们需要重新处理一下顺序

image

这边偷懒交给gpt了,处理完后解码得到密码,然后从oursecret中解出flag

image

USB

知识点省流

usb键盘流量分析(要扩展键位表,有小键盘)

WP

usb键盘流量,但是常见能搜到的解密脚本很多都不能直接用,因为这里的数据还包括了小键盘,所以需要简单补充一下键位表,这里可以让gpt帮忙完善

image

用tshark把hid数据提取出来

1tshark -r flag.pcap  -T fields -e usbhid.data | sed '/^\s*$/d' > data.txt

然后搞个脚本处理即可

 1# 自定义 HID 映射表(十六进制小写字符串作为键)
 2hid_keymap = {
 3    "04": "a", "05": "b", "06": "c", "07": "d", "08": "e", "09": "f", "0a": "g", "0b": "h", "0c": "i",
 4    "0d": "j", "0e": "k", "0f": "l", "10": "m", "11": "n", "12": "o", "13": "p", "14": "q", "15": "r",
 5    "16": "s", "17": "t", "18": "u", "19": "v", "1a": "w", "1b": "x", "1c": "y", "1d": "z", "1e": "1",
 6    "1f": "2", "20": "3", "21": "4", "22": "5", "23": "6", "24": "7", "25": "8", "26": "9", "27": "0",
 7    "28": "<RET>", "29": "<ESC>", "2a": "<DEL>", "2b": "\t", "2c": "<SPACE>", "2d": "-", "2e": "=",
 8    "2f": "[", "30": "]", "31": "\\", "32": "<NON>", "33": ";", "34": "'", "35": "<GA>", "36": ",",
 9    "37": ".", "38": "/", "39": "<CAP>", "3a": "<F1>", "3b": "<F2>", "3c": "<F3>", "3d": "<F4>",
10    "3e": "<F5>", "3f": "<F6>", "40": "<F7>", "41": "<F8>", "42": "<F9>", "43": "<F10>", "44": "<F11>",
11    "45": "<F12>", "46": "<PRTSC>", "47": "<SCRLK>", "48": "<PAUSE>", "49": "<INS>", "4a": "<HOME>",
12    "4b": "<PGUP>", "4c": "<DEL_FWD>", "4d": "<END>", "4e": "<PGDN>", "4f": "<RIGHT>", "50": "<LEFT>",
13    "51": "<DOWN>", "52": "<UP>", "53": "<NUMLOCK>", "54": "/", "55": "*", "56": "-", "57": "+",
14    "58": "<ENTER>", "59": "1", "5a": "2", "5b": "3", "5c": "4", "5d": "5", "5e": "6", "5f": "7",
15    "60": "8", "61": "9", "62": "0", "63": ".", "64": "<NONUS_BACK>", "65": "<APP>", "66": "<POWER>",
16    "67": "=", "68": "<F13>", "69": "<F14>", "6a": "<F15>", "6b": "<F16>", "6c": "<F17>", "6d": "<F18>",
17    "6e": "<F19>", "6f": "<F20>", "70": "<F21>", "71": "<F22>", "72": "<F23>", "73": "<F24>"
18}
19
20
21# 加载 USB HID 数据文件
22input_file = "data1.txt"  # 替换为你的实际路径
23with open(input_file, "r") as f:
24    lines = f.read().splitlines()
25
26# 解析数据并还原按键
27keystrokes = []
28for line in lines:
29    if len(line) >= 8:
30        hex_code = line[6:8].lower()
31        key = hid_keymap.get(hex_code, '')
32        keystrokes.append(key)
33
34# 输出完整的按键还原结果(包括控制符号)
35reconstructed_text = ''.join(keystrokes)
36print(reconstructed_text)

No.shArk

知识点省流

流量分析+dns协议隐写+jpg silenteye隐写+Arnold猫脸变换+snow隐写

WP

hard套娃

附件just one 流量包 analyze start

先把常规的走一遍,发现导出里面http和ftp协议均有内容,根据题目信息和ftp传送的文件可以知道一定有snow隐写

把可疑的文件dump下来,分别是next.jpg,202410191641147091.png,w1.html,至于为什么可疑后面说

image image

首先是那张png图片,通过简单的分析和流追踪,可以发现这张图片的名字其实是cat.png,与题目给的hint是对应的,导出后打开是一张很奇怪的图片

image

用010分析会发现尾部提示了一个密码为keykeyishere

image

而jpg图因为ftp只有他这么一个文件(那个doc文档其实是snow隐写工具的说明文档忽略不计),肯定有问题,dump下来后简单分析没有任何信息

而w1.html文件就很有说法了,我们先来看看snow隐写的原理,可以看到是由空格和制表位隐写的

image

而我们找到这个w1.html的流量,会发现他的回显里,有大量的制表位,明显不对劲

image

所以将其导出后,修改后缀为txt(不知道不改行不行),然后尝试用snow解密,但是snow隐写需要密码,前面得到的密钥尝试解密发现是不对的,说明还有内容

再次分析,发现流量中存在dns记录,与此同时,有一些dns记录非常的特别,可以发现有大量的01字符串,实际上考察的是DNSlog外带流量隐写

image

根据其ip地址,用tshark导出其外带流量的值

1tshark -r complete.pcapng -T fields -e dns.qry.name -Y ' ip.dst == 114.114.114.114 && dns.qry.type == 1' | sed '/^\s*$/d' | uniq > data.txt

然后把没用的内容去掉,在notepad中分析,我们将1高亮显示就会发现神奇的内容,这是什么啊好难猜啊(好吧是二维码)

image

所以搞个脚本,把01字符串转化一下即可 ,最后得到一个缺少两个定位符的二维码

 1from PIL import Image
 2import numpy as np
 3
 4# 原始数据
 5data_str = """
 611111111111111001100000000001100110000000000000000
 711000000000011001100001111111100000000000000000000
 811001111110011001111000011000011110000000000000000
 911001111110011001111110011000000110000000000000000
1011001111110011000011110011001100110000000000000000
1111000000000011001111110000000000110000000000000000
1211111111111111001100110011001100110000000000000000
1300000000000000000000111100110011110000000000000000
1411110000111111000000110011110000000000110011111111
1500001111111100001100000000111111110011001111001111
1611110011000011001111110000000011001111111100110000
1700001100001100000011000011001111110000111100111100
1811001100111111000000001100111100001111001111000011
1911000000001100111111110011000011111100001111111100
2000000000000011000011001111111111110000000000001100
2100000000000000001111111100110011111100110000110000
2211111111001111001100000011110000111111111100000000
2300000000000000001100000000111100110000001111001111
2400000000000000000000110000000011110011001111000000
2500000000000000001100000011001100110000001100111111
2600000000000000001111111100111100111111111100110011
2700000000000000000011110011000011001111110000111111
2800000000000000000011001111111111111100110000111100
2900000000000000001111111100110011001111000011111100
3000000000000000001100000011110011000011110011111111
31"""
32
33# 解析数据
34lines = data_str.strip().split('\n')
35height = len(lines)
36width = len(lines[0]) // 2  # 每两个字符表示一个像素
37
38# 创建图像数组
39image_array = np.zeros((height, width), dtype=np.uint8)
40
41for y, line in enumerate(lines):
42    for x in range(0, len(line), 2):
43        pixel = line[x:x+2]
44        if pixel == '11':
45            image_array[y, x // 2] = 0  # 黑色
46        elif pixel == '00':
47            image_array[y, x // 2] = 255  # 白色
48
49# 创建图像
50img = Image.fromarray(image_array, mode='L')
51img = img.resize((width*10, height*10), resample=Image.NEAREST)
52img.save("output_image.png")
53img.show()

拿ps简单修复一下,扫描后得到一个密码

image

将得到的密码拿去解密snow,得到半个flag

image

那么前半段去哪了,我们现在还有两张图片没有分析,对于jpg图像来说,除了常规的一些隐写,其实还有一种,silenteye(bmp也可以)

将jpg图片丢给silenteye,然后导入前面得到的key值,发现真的解出了内容,它给了三个值,shuffle,a,b

image

简单调查一下发现,这其实是Arnold猫脸变换(对应了png图片的名字cat),只要确定shuffle,a,b这三个参数即可还原图片,用lunatic师傅的脚本还原一下即可

 1import matplotlib.pyplot as plt
 2import cv2
 3import numpy as np
 4from PIL import Image
 5
 6img = cv2.imread('cat.png')
 7
 8def arnold_encode(image, shuffle_times, a, b):
 9    arnold_image = np.zeros(shape=image.shape)
10    h, w = image.shape[0], image.shape[1]
11    N = h   # 或N=w
12
13    for time in range(shuffle_times):
14        for ori_x in range(h):
15            for ori_y in range(w):
16                new_x = (1*ori_x + b*ori_y)% N
17                new_y = (a*ori_x + (a*b+1)*ori_y) % N
18                arnold_image[new_x, new_y, :] = image[ori_x, ori_y, :]
19
20        image = np.copy(arnold_image)
21
22    cv2.imwrite('flag_arnold_encode.png', arnold_image, [int(cv2.IMWRITE_PNG_COMPRESSION), 0])
23    return arnold_image
24
25def arnold_decode(image, shuffle_times, a, b):
26    decode_image = np.zeros(shape=image.shape)
27    h, w = image.shape[0], image.shape[1]
28    N = h  # 或N=w
29
30    for time in range(shuffle_times):
31        for ori_x in range(h):
32            for ori_y in range(w):
33                new_x = ((a * b + 1) * ori_x + (-b) * ori_y) % N
34                new_y = ((-a) * ori_x + ori_y) % N
35                decode_image[new_x, new_y, :] = image[ori_x, ori_y, :]
36
37    cv2.imwrite('flag.png', decode_image, [int(cv2.IMWRITE_PNG_COMPRESSION), 0])
38    return decode_image
39
40# arnold_encode(img, 1, 2, 3)
41arnold_decode(img, 5, 7, 3)

最后得到前半段flag

image