概述
本篇文章原文:http://www.7yue.top/vnctf2021-misc-wp/
冰冰好像藏着秘密
这题好像被非预期嘞,出题人本来是想出rar伪加密+傅里叶盲水印的,但变成了foremost+WaterMarkH就能出,呜呜。
直接用winhex打开,能看到png文件头
结尾有png文件尾
这部分数据保存下来即可得到png文件。
解rar伪加密:
第17位置的数据84,改成80即可解开伪加密。rar在伪加密状态下会显示压缩包已损坏或压缩格式未知,所以判断rar伪加密的方法并不难。
解压即可得到图片。
之后根据压缩包的名字FFT,可知是傅里叶。利用傅里叶盲水印即可跑出flag。
脚本如下:
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
img = cv.imread('FFT.png', 0) #直接读为灰度图像,不过此题已经是灰度图片了
f = np.fft.fft2(img) #做频率变换
fshift = np.fft.fftshift(f) #转移像素做幅度谱
s1 = np.log(np.abs(fshift))#取绝对值:将复数变化成实数取对数的目的为了将数据变化到0-255
plt.subplot(121)
plt.imshow(img, 'gray')
plt.title('original')
plt.subplot(122)
plt.imshow(s1,'gray')
plt.title('center')
plt.show()
解得:
利用WaterMarkH也能出
得到flag:
VNCTF{Ff5_1S_bEauTiful}
Do_you_like_Rhythm_Doctor
音游题,节奏医生。可惜steam上好贵,我也找不到破解版,没法钞能力做题惹
只能审关卡代码看看哪里比较特殊。(不过其实有这款游戏也只是可以帮助理解)
主要关卡数据如下:
根据经验和英文单词的意思,顺便看看游戏视频,猜测bar为按顺序的1-16,大概是类似进度的数据,beat为节拍,row为轨道。y和row的数据90%都是一样的,但也有部分是有区别的,具体不知道会是什么。
pluseType是脉冲类型,这是关键,只有两种Wave和Square两种情况,很容易想到0或1,而其他的又看不出有什么含义,于是尝试下按顺序读取pulseType信息,脚本如下:
data = open('main.rdlevel', 'r', encoding='UTF-8')
true = 1 #用于对true赋值,保证程序正常运行。因为字符串中存在ture,使用eval时会把ture当做变量。
flag = ''
while 1:
s = data.readline()
if not s:
break
s = s.strip('n')
if not "pulseType" in s:
continue
dic1 = eval(s[:-1]) #将每行数据转化为字典,由于每行最后均有逗号,故为s[:-1]
if dic1['pulseType'] == 'Square':
flag += '0'
else:
flag += '1'
print(flag)
#011001100101011101101101010011100110110000110010111001001101111101100000011100010011101110100011011001010101100010111001111001000000101101110001001111101111001100001111111111111111111100001111
这并不能得到正确答案,但是能正好得到24个字符,且开头为f,方向可能是对的。
根据关卡代码得此关共有0 1 2 3四个轨道,尝试按照轨道顺序读取数据,
最终脚本如下:
from Crypto.Util.number import *
data = open('main.rdlevel', 'r', encoding='UTF-8')
true = 1 #用于对true赋值,保证程序正常运行。因为字符串中存在ture,使用eval时会把ture当做变量。
flag = ''
row = {0:"", 1:"", 2:"", 3:""}
while 1:
s = data.readline()
if not s:
break
s = s.strip('n')
if not "pulseType" in s:
continue
dic1 = eval(s[:-1]) #将每行数据转化为字典,由于每行最后均有逗号,故为s[:-1]
if dic1['pulseType'] == 'Square':
row[dic1['row']] = row[dic1['row']] + '0'
else:
row[dic1['row']] = row[dic1['row']] + '1'
print(row)
flag = int(row[0] + row[1] + row[2] + row[3], 2)
print(long_to_bytes(flag))
#{0: '011001100110110001100001011001110111101101111101', 1: '010101110011001100110001011000110110111101111101', 2: '011011010110010101011111010101100010011001111101', 3: '010011100101111101000011010101000100011001111101'}
#b'flag{}W31co}me_V&}N_CTF}'
由于每个轨道的最后八位都是’01111101’,asc转码后为字符’}’。
故将前三个轨道的’}'去掉,得到最终flag:
flag{W31come_V&N_CTF}
interesting_fishing
压缩包内有一个邮件文件,注释.txt即为题目描述
邮件文件内有一串很长的base64编码,解码得到一个rar文件:
在myprojectgiveyourflaggiveyourflagx64Debug目录下有一个特殊的db文件
文件内有一串base64编码,解密后得:
根据base64解码后的u-65432,u-65420可知是被混淆过了
根据上述解混淆示例,将数据表示为 [65432, 65420, 65420……]的格式,
脚本如下:
list1 = [65432,65420,65420,65424,65421,65478,65489,65489,65418,65426,65437,65420,65434,65491,65486,65487,65485,65491,65487,65486,65483,65481,65488,65482,65487,65487,65486,65485,65490,65437,65425,65421,65490,65439,65424,65491,65426,65439,65426,65430,65431,65426,65433,65490,65427,65415,65423,65437,65428,65425,65419,65436,65490,65437,65425,65427,65489,65456,65415,65425,65426,65433,65415,65439,65426,65433,65499,65486,65488,65421,65420,65425,65422,65435,65421,65499,65486,65488,65428,65425,65417,65499,65486,65488,65425,65426,65499,65486,65488,65434,65425,65422,65435,65431,65433,65426,65499,65486,65488,65433,65425,65425,65436,65421,65499,65486,65488,65439,65427,65431,65436,65499,65486,65488,65458,65425,65422,65420,65432,65499,65486,65488,65461,65425,65422,65435,65439,65426,65499,65486,65488,65469,65457,65450,65463,65468,65491,65487,65479,65499,65486,65488,65424,65439,65422,65439,65426,65425,65431,65439,65490,65422,65439,65422]
flag = ""
for i in list1:
flag += chr(0xffff - int(i) + 1)
print(flag)
解得:
https://vnctf-213-1257061123.cos.ap-nanjing.myqcloud.com/Pyongyang%20stores%20low%20on%20foreign%20goods%20amid%20North%20Korean%20COVID-19%20paranoia.rar
下载得到一个加密的压缩包,有hint:压缩包是四位数字
利用hashcat爆破
先利用rar2john获取hash值
然后利用hashcat爆破:
.hashcat.exe -m 13000 -a 3 '$rar5$16$1349cb834c70bf27bb4e48bb3fbe6975$15$ca4a3bc58278b04d9fba4d7d52acb196$8$56245cd11e4a1c2e' ?d?d?d?d --show
得到密码:9705
打开压缩包得到一个word文件,后缀改为zip,有一个hideinfo.xml。虽然里面的数据看起来和word文档显示的数据一样,但有一个零宽字节隐写。
http://330k.github.io/misc_tools/unicode_steganography.html
解得第一部分flag:
vnctf{APT_1S_c0M1nG
重新观察最初的邮件文件,看到一个PG1ldGEgaHR0c开头的有用的base64编码,解码得:
能够看到一张图片的地址,打开并保存
根据文件名ThisIsSecret可知是利用OurSecret解密
没有密码,unhide一下即可得到一个2.txt,保存打开即可得到第二部分flag:
_fr0m_l@z@RuS}
将两部分flag连起来得到最终flag:
vnctf{APT_1S_c0M1nG_fr0m_l@z@RuS}
HAPPYNEWYEAR
hint1:https://www.dcode.fr/tools-list#symbols
hint2:stegpy,但是不是那么白给的stegpy
下载附件得到一个加密的压缩包和一副写着密码的图
明显是需要解密了,蓝色的比较简单,很明显是谢赫语言密码
横竖线的密码比较难找,我还假设过这些密码全是数字,尝试掩码爆破,可惜并没有解出答案。根据hint1可以找到解密网站:
https://www.dcode.fr/chinese-code
最终得到密码:
f87840bdddcc01e4
得到一张图片:
尝试过各种png的隐写方式,也尝试过寻找原图去拼合两张图片,但都无济于事。
根据hint2可知是stegpy隐写,但无密码和一些与题目文件名有关的密码都没用,于是尝试爆破。
这个爆破的难点主要在于python和终端的交互,stegpy的输入密码特殊性导致不能像一般的交互那样写脚本。理论上修改stegpy源码让stegpy和终端的交互更倾向于常见的方式也是可行的,但我还没有试过。
下面直接给出爆破脚本,此脚本在misc大师傅们一起写的"automisc"中可以找到,只需要稍加修改即可,我利用的字典也是此项目的字典。
https://github.com/L1near/CTFpics-1/blob/master/webpsteg.py
# -*- coding: utf-8 -*-
import os
from subprocess import Popen,PIPE
import sys
def checkwebp(pic):
print("IF you don't need a password for the pic please input 1") # 无密钥
print("IF you know the password of the pic please input 2") # 有密钥且已知
print("IF not input 3 I will use the password.txt") # 有密钥但未知
choice = input()
if choice == '1':
os.system("stegpy {}".format(pic))
elif choice == '2':
print("INPUT THE password:")
password = input()
cmd = ["stegpy", "-p",pic]
subp = Popen([sys.executable, '-c', 'import pty, sys; pty.spawn(sys.argv[1:])', *cmd],stdin=PIPE,stdout=PIPE,stderr=PIPE)
print(subp.stdout.read(len("Enter password (will not be echoed):")))
subp.stdin.write(bytes((password+'n').encode('utf-8')))
subp.stdin.flush()
print(subp.stdout.readlines())
# print(subp.stdout.readlines()[1])
print('n')
elif choice == '3':
file = open('password.txt', 'r')
line = file.readline()
while line:
print(line)
cmd = ["stegpy", "-p", pic]
subp = Popen([sys.executable, '-c', 'import pty, sys; pty.spawn(sys.argv[1:])', *cmd], stdin=PIPE, stdout=PIPE,stderr=PIPE)
print(subp.stdout.read(len("Enter password (will not be echoed):")))
subp.stdin.write(bytes((line + 'n').encode('utf-8')))
subp.stdin.flush()
print('result:')
result = subp.stdout.readlines()[1]
print(result)
if result != b'Wrong password.rn':
break
# print(subp.stdout.readlines()[1])
print('n')
line = file.readline()
else :
print('Input Wrong!')
if __name__ == "__main__":
checkwebp('happynewyear.png')
解得:
最终密码即为tyinfo
解得最终flag为:
VNCTF{HappyNewY3a5}
最后
以上就是专注指甲油为你收集整理的VNCTF2021 MISC wp的全部内容,希望文章能够帮你解决VNCTF2021 MISC wp所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复