首届祥云杯misc部分wp

这次比赛队里的大师傅们太强了,只会几道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

http://velato.net/

下载下来,利用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()

最终可以得到一张菲谢尔老婆的羞涩图:

发表评论