这次比赛队里的大师傅们太强了,只会几道misc,被大佬们带进了前十。这篇博客就写一下祥云杯misc解出的几道题的wp。
ps:这次比赛是我第一次进线下赛,还是在吉林长春,作为浙江人的我一直没看过铺满路的大雪,只有小时候才有偶尔几次雪比较大的时候。一般要不就是没雪,要不就是薄薄一层。第一次“公费旅行”+第一次看大雪,真的特别期待这场决赛的到来。之后应该也会新开一篇文章讲下决赛的经历。
[toc]
签到
base64解码
进制反转
下载得到一个rar文件,但是打开显示压缩包文件头已损坏。

当rar被伪加密后,就会显示报这种错误,用010editor打开rar文件,可以发现加密标识位是1,可知是伪加密:

将1修改成0即可正常打开文件,打开文件后获得一个flag.wav文件,但是播放不了。
用010editor打开发现没有头文件,而且中间的数据块也怪怪的,显然需要异或一下。

先查看文件尾,发现flag信息,flag是歌名

整个文件对FF异或,可获得正确的wav文件:

wav文件修复后,可以播放了。但是完全听不懂说的是哪国的语言,利用听歌识曲也没法听出来。
之后发现需要倒放,利用AU将整首歌倒放后声音明显清楚了,然后利用听歌识曲得到这首歌名叫做:

全部改成大写,去掉括号和里面的内容,去掉空格即可得到flag
带音乐家
下载附件得到decode_it和一个加密的压缩包。
这题的难点其实主要在第一步,decode_it该如何处理。
winhex打开发现头文件4D 54 68 64,查阅资料可知是mid文件,mid是一个音频格式的文件。

修改后缀为mid,之后听声音和audacity分析,都看不出什么特别的地方。
最后通过google,找到了一个MIDI文件音频隐写工具 velato
下载下来,利用velato解密,执行以下命令,可以得到一个decode_it.exe:
Vlt.exe decode_it.mid

然后执行decode_it.exe:

所以压缩包密码即为: Hello, World!
解开压缩包后里面有一个word文档,有一段精灵语的密码,隐藏里有一串字符串

精灵语密码解密后得到:flagis
字符串用base64解码是乱码。
之后在压缩包的注释里发现有一些空格,应该也是某种加密方式

这种类型的加密应该是已经出现过很多次了,里面有两种字符,tab和空格。将tab转为 '-' ,空格转为 '.' ,换行符 '\n' 换成空格,得到摩斯密码:
.- . ... -.- . -.-- ----. ..--- .---- ----. ..--- ...-- ..--- ...-- ..--- ..---
解码得:
AESKEY9219232322
密文为:nvPrjrss1PyqAZB/14lkvJGTJ9l4rOfwJeqSqSHSqXU=
密钥为:9219232322
AES解码,加密模式ECB
解码得到flag:
flag{mU51c_And_ch@ract0rs~}
到点了
下载附件得到三个word文档,打开第一个word文档,隐藏里提示密码为八位字母数字

第二个word文档是加密状态的,提取word文档加密的hash值,网上搜到了类似的文章
python3 office2john.py dummy.docx > hash.txt
之后用hashcat跑,题目说的是8位数字和字母,太多了,就先试着用纯数字跑,
hashcat -m 9400 --username hash.txt -a 3 ?d?d?d?d?d?d?d?d -o cracked_pass.txt
然后跑出来了,密码是20201024,后来发现是文档的修改日期

第二个word文档解开密码后能看到图片下面有一块颜色被修改成了白色的数据

改成红色可以看到是AB字符串,猜测是培根密码

利用CyberChef解码,得到:GOODNIGHTSWEETIE
打开第三个word文档,发现无法读取的内容

修改后缀为压缩包,发现4.zip

4.zip里有一个bmp图片,先用zsteg分析一下:

发现有一个wbStego隐写,直接提取提取不出来,需要利用工具wbstego43open。

选择Decode,选择图片,输入密码后,设置保存路径即可获得flag文件


xixixi
下载附件得到一个磁盘文件,装载后得到一张kejin.png,左上角有flag的一小部分

利用DiskGenius装载虚拟磁盘,恢复文件后得到被删除的文件

有用的一共就两个文件,一个是xi.py,一个是xixi.py。得到两段代码:
xixi.py
import struct
class FAT32Parser(object):
def __init__(self, vhdFileName):
with open(vhdFileName, 'rb') as f:
self.diskData = f.read()
self.DBR_off = self.GetDBRoff()
self.newData = ''.join(str(self.diskData))
def GetDBRoff(self):
DPT_off = 0x1BE
target = self.diskData[DPT_off+8:DPT_off+12]
DBR_sector_off, = struct.unpack("<I", target)
return DBR_sector_off * 512
def GetFAT1off(self):
target = self.diskData[self.DBR_off+0xE:self.DBR_off+0x10]
FAT1_sector_off, = struct.unpack("<H", target)
return self.DBR_off + FAT1_sector_off * 512
def GetFATlength(self):
target = self.diskData[self.DBR_off+0x24:self.DBR_off+0x28]
FAT_sectors, = struct.unpack("<I", target)
return FAT_sectors * 512
def GetRootoff(self):
FAT_length = self.GetFATlength()
FAT2_off = self.GetFAT1off() + FAT_length
return FAT2_off + FAT_length
def Cluster2FAToff(self, cluster):
FAT1_off = self.GetFAT1off()
return FAT1_off + cluster * 4
def Cluster2DataOff(self, cluster):
rootDir_off = self.GetRootoff()
return rootDir_off + (cluster - 2) * 512
xi.py:
import struct
from xixi import FAT32Parser
from xixixi import Padding, picDepartList
def EncodePieces():
global clusterList
res = []
Range = len(picDepartList) # 58
# GetRandomClusterList(n) - Generate a random cluster list with length n
clusterList = GetRandomClusterList(Range)
for i in range(Range):
if i != Range - 1:
newCRC = struct.pack("<I", clusterList[i+1])
plainData = picDepartList[i][:-4] + newCRC
else:
plainData = picDepartList[i]
# Show the first piece to him, hhh
if i == 0:
newPiece = plainData
else:
newPiece = ''
key = clusterList[i] & 0xFE
for j in plainData:
newPiece += chr(ord(j) ^ key)
# Padding() -- Fill to an integral multiple of 512 with \xFF
res.append(Padding(newPiece))
return res
可知文件的CRC32被修改了,还被异或了。
写一个逆脚本,跑一下即可得到flag:
import struct
import binascii
from xixi import FAT32Parser
fat=FAT32Parser("new.vhd")
f = open("new.vhd", "rb")
f.seek(0x27bae00) #定位图片
flag = open("flag.png", "wb")
flag.write(f.read(8)) #写入头文件
key = 0
def read(n):
global key
b = b''
for i in f.read(n):
b += (i ^ (key & 0xFE)).to_bytes(length=1,byteorder='big',signed=False)
return b
while 1:
d = read(8)
lenth, ctype_type = struct.unpack(">I4s", d)
#print(lenth,ctype_type) #length 数据长度,ctype_type 数据块类型
data = read(lenth)
crc = struct.unpack(">I", read(4))[0]
#print(crc)
real_crc = binascii.crc32(ctype_type+data) & 0xffffffff
#print(real_crc)
real_data = struct.pack(">I", lenth) + ctype_type + data + struct.pack(">I", real_crc)
flag.write(real_data)
if crc != real_crc: #CRC错误的IDAT数据块
b_endian = struct.pack(">I", crc)
clusterList = struct.unpack("<I", b_endian)[0]
#print(clusterList)
f.seek(fat.Cluster2DataOff(clusterList))
key = clusterList & 0xfe
if ctype_type == b"IEND":
break
flag.close()
f.close()
最终可以得到一张菲谢尔老婆的羞涩图:
