羊城杯2022 部分题解

羊城杯2022 部分题解

2678.54分39名。
排名不算高,但是比赛过程还是挺有意思的,虽然时好时坏的平台和脑洞题很屑。
Crypto有大佬去carry了,这次只搞了Misc,Web辅助坐牢。

签到

ROT13+base32

迷失幻境

vmdk改7z解压,系统盘回收站里发现$RE4UUGI.jpg、$IE4UUGI.jpg,但是后一个文件只是后缀名带jpg,不是图片。
迷失幻境文件夹下面给了1.png到100.png,但是45.png丢了,其他图片算一下md5发现相同,说明只是文件名不同,关键在找到45.png。
回到回收站发现有一个1.1MB的$RJ3JGVF大小看着挺像图片的,hex查一下发现是png格式只不过丢了89504e47头,补全打开发现和迷失幻境文件夹里的图片一样,推测这个就是45.png。
羊城杯2022 部分题解_第1张图片
这个图片和其他图片大小略有不同,stegsolve异或一下拿到key。
羊城杯2022 部分题解_第2张图片
然后去解那个哒哒哒.jpg了,但是试了几个都爆不出来。
后来发现$RE4UUGI.jpg属性里一个提示“猜不出来”,outguess一下拿到flag。

where_is_secret

屑题,最开始不给源码,猜个头
vig.txt提示维吉尼亚加密,用在线爆破网站爆一下得到密钥gwht和压缩包密码GWHT@R1nd0yyds。
解压拿到out.bmp,结合提示给出的加密脚本写解密代码即可。

from PIL import Image
img = Image.open('out.bmp')

d = dict()
k = []
with open('out.txt','w') as f:
    for i in range(371):
        for j in range(371):
            p = img.getpixel((j,i))
            f.write(chr(int(bin(p[1])[2:].zfill(8)+bin(p[2])[2:].zfill(8),2)))

得到out.txt,内容穿插着flag,写正则表达式提取特殊字符后观察手动拼接即可。

import re
f = open('out.txt','r').read()

a = re.findall('[^a-z\{\}0-9][a-z\{\}0-9][^a-z\{\}0-9]', f, re.M)
for i in a:
    print(i)
    
# flag{h1d3_1n_th3_p1ctur3}

躲猫猫

这题拿了个四血,乐。
binwalk一下流量包发现里面藏了一个压缩包,其中hide&seek.py和secret文件被加密,key.log可以分离但是提示损坏,估计是binwalk导致的。
在流量包中ftp协议报文下找到一个important.zip,推测为得到的压缩包,追踪ftp-data得到压缩包文件,提取出完整的key.log。
羊城杯2022 部分题解_第3张图片
报文中有大量的TLS流量,在preferences中导入log文件中的密钥信息,查询发现部分TLS流被解密。在stream29中发现使用邮箱传输了数据,源数据中查询到FFD8字段,导出得到含有压缩包密码的图片。
羊城杯2022 部分题解_第4张图片
在这里插入图片描述
解压得到python源码和secret,源码用于加密图片,逆向解密即可。(这题加密代码跟DS初赛基本一样)

from PIL import Image
from Crypto.Util.number import *
from numpy import array, zeros, uint8
import gmpy2 as gp
import cv2

image = Image.open("cat.png")
w, h = image.size
imagearray = array(image)

x = 5999540678407978169965856946811257903979429787575580150595711549672916183293763090704344230372835328
y = 6310149030391323406342737832910952782997118359318834776480172449836047279615976753524231989362688
kn = 1


x1 = round(x/y*0.001, 16)
u1 = y*3650/x
x2 = round(x/y*0.00101, 16)
u2 = y*3675/x
x3 = round(x/y*0.00102, 16)
u3 = y*3680/x
kt = [x1, x2, x3]
print(kt)

temp_image = zeros(shape=[h, w, 3], dtype=uint8)
print(len(temp_image))
print(len(temp_image[0]))
print(len(temp_image[0][1]))
for k in range(0, kn):
    for i in range(0, h):
        for j in range(0, w):
            x1 = u1 * x1 * (1 - x1)
            x2 = u2 * x2 * (1 - x2)
            x3 = u3 * x3 * (1 - x3)
            r1 = int(x1*255)
            r2 = int(x2*255)
            r3 = int(x3*255)
            for t in range(0, 3):
                temp_image[i][j][t] = (imagearray[i][j][t]-((r1+r2) ^ r3)) % 256
    x1 = kt[0]
    x2 = kt[1]
    x3 = kt[2]

encflagarray = Image.fromarray(temp_image)
encflagarray.show()
encflagarray.save("flag.png")

得到图片,搜图发现是MaxiCode码。Maxicode Wiki
中间起定位作用的圆圈被猫代替了,找个示例码截下来手动覆盖一下,扫描得到flag。


9.7 更新一下Misc后两道题

寻宝

这个题最初卡了很长时间,后来发现他是把文件按字节倒转了。
开头四个字节是05 B4 30 40,是zip格式头504B0304倒转,一直看到文件尾发现就是整个zip文件被按字节倒换了,换回来就行。

f = open("treasure.dat", "rb")
outfile = open("out.txt", "w")
i = 0
ss = ""
while 1:
    c = f.read(1)
    i = i + 1
    if not c:
        break
    else:
        ss += hex(ord(c))[2:].zfill(2)[::-1]

outfile.write(ss)

导入HexEditor解压一下,得到一个小游戏,下一层压缩包密码隐藏在游戏里。鉴于重点在于看到每一关而非打游戏,直接开挂把生命拉满。
比赛的时候给了提示让注意地形,前四关的地形和猪圈密码类似(如下图是第一关地形),查一下得到是变种的猪圈密码。对应解出一段密码OWOH。
羊城杯2022 部分题解_第5张图片
后来给了第二个提示让注意琴键对应的音符,背景音乐里有一段混音,音高对应数字114514。
题目压缩包里面还提到第五关存在电波,因此接着往后打。第五关之后地形类似方波,一路打通关并记下地形波形。
羊城杯2022 部分题解_第6张图片
这玩意多少有点抽象。
最开始以为只看高电平与低电平就行,后来发现转出来的东西不大对劲,而且每一关地形都分为左右两部分,因此变化应该发生在0.5T位置。这说明应该是Manchester编码。
正常的Manchester编码,中间时刻从低到高跳变代表0,反之代表1;差分Manchester编码,在每个时钟周期开始时有跳变代表0,无跳变代表1。整个图形变化都是从低到高后从高到低,因此Manchester编码一定是01相间,没有意义,因此推测是差分Manchester编码。按这个规律尝试解析图形,得到二进制串01011111011000010011000101011111,bin2ascii得到:_a1_。
三部分拼一下即可,估计_a1_在中间,因此口令是:OWOH_a1_114514。解压得到flag文件,放到sublime下查看看到零宽字节。
在这里插入图片描述
零宽字节隐写在线解一下即可得到flag。

Unlimited Zip Works

这个题比赛时没做出来。后来看其他博客知道这是个zip注释隐藏的压缩包套娃,是不能简单用binwalk分离出来的。
分享一下原文链接,大佬tql。
2022年羊城杯wp

你可能感兴趣的:(CTF,安全)