SWPU NSS 2022 秋季招新赛 Misc 出题人笔记

前言

别骂了,后面还会再补完整的,因为被 gank 了,很多东西都是重新写的,稍晚点就会好,只能麻烦师傅们耐心等待了,呜呜呜呜

咕,出题的时候感觉都是基础考点,就把能放在一起考察的就放在一起了,尽量保持单文件,不出现套娃,当然那种 Continue 本身就是以脚本能力作为考察的就是另外一码事了(Coffee CrackMe 同理)。其实可能有细心的小伙伴发现了本次 Misc 全为 C 开头的题目名,其实原本这次这套题是在一个综合取证里面,需要把各个题目通过取证去寻找,不过呢由于当时计划更改,原本和网络联盟的联动的想法取消了,没有时间去准备更多的题目,加上疫情影响花式延期返校,这个想法被迫搁置了,题目理论上除了有一道题有点坑,其他的应该都还好。

Call the Alien

出题人:WDLJT

考点:

SSTV(Robot36)

silenteye 音频隐写

一开始能听到非常明显的 SSTV 中的 Robot 开始标志音频,然后长度接近 36 秒,那我们可以判断为 Robot36 ,那我们就有多种办法解决,最简单的办法,手机上装个 Robot36 的 App 然后对播,或者用 MMSSTV‘

参考画面:

截图

第二个考点是 silenteye 但是我自己没有特别严谨的给出提示或者说指引,在此道个歉,(原逻辑是因为噪点原因,所以考虑有其他隐写,但是呢,我为了不干扰 SSTV 结果太多,所以导致需要调参,但是没有告知,在此道歉,私密马赛)

截图

必须老实的说这个题出的考点不是特别严谨,在此道歉,呜呜呜。

Capture!

出题人:WDLJT

考点:

LSB(需要自行观察通道)

修改宽高(没告知 CRC 异常)

WDLJT:这个 Capture 真的很简单啊。
Haruki:只是你一不小心顺手改了 CRC 是吧。
WDLJT:手贱不小心改了下而已~
Haruki:?

其实我说了考点就没意思了,甚至 Writeup 都不用写了,乐,终于知道意识流 Writeup 是怎么来的了。

首先改宽高,这次用了稍微特殊一点点的值,不太能一眼看出来(应该?),下次可能弄明显点就比如说明显的半屏幕都没东西,

改好之后就可以看到 Part1

选手:为什么你家 flag 永远只有一半啊
WDLJT:激励做题嘛,合理(

然后另外一个就是 LSB ,为了 gank 无脑 r0g0b0 不观察题目的人,特意改了方向

改了隐写通道,稍微观察下低通道非常明显的隐写痕迹

image-20221024160303965

单独提取 r0 通道查看可以看到 part2,记得提取顺序改一下

image-20221024162601951

两个拼到一起 base64 解码就是 flag 了

Coding In Time

出题人:WDLJT

考点:

GIF 帧分离

GIF 时间间隔提取

因为这道题做题方法实在是太多了,索性偷个懒,偷一手其他人的 Writeup(,下次感觉我得把 Coding In Time 加到第一部分的密码后面,不然的话得懵逼一批人,明明方法直接写题面了,但是还是想不到,可能确实是我的问题,下次一定不改(

拿到gif,拆个帧先,推荐在线网站

截图

是一个二维码,把所有帧下载下来后利用PPT(?)拼接

截图

得到二维码,扫描得到前半段flag,在线网站

截图

Tick tock, tick tock, you found it,结合题目,似乎和时间有关?

扔010,看到最后一行貌似有工具?

截图

下载下来这个工具,打开gif

截图

这个时间排布怎么看上去有点无序,或者暗藏玄机?

以UUID的格式,flag还差9位,其中最后一位肯定是大括号,二维码刚好被拆成九个部分

取“}”的ASCII码,发现刚好等于125,由此得到flag

截图

NSSCTF{114f75b5-ef1c-4ece-b062-8852cfbdde7f}

Coffee Please

出题人:WDLJT

考点:

Office 特性

这道题也是一个目标特别明确的题目,考的就是 Office 全家桶的,直接贴选手 Writeup (

  • word, excel, ppt均可以压缩包的方式打开,可先解压,再重压缩,再通过office打开
  • 你甚至可以在解压后的所有文件里直接找flag
  • 随时全选,放大,调色,有意外收获

word:

截图

excel:

截图

ppt:

截图
截图

拼接可得:NSSCTF{8ff8a53a-9378-4e78-b54a-ef86e8c84432}

Convert Something

出题人:WDLJT

考点:

零宽字符

base64 隐写

原本想说出零宽塞得散一点,后来觉得太容易被发现了,后面还是在末尾摁塞的,算是这次比较简单的题了,贴个选手 Writeup:

零宽字符:真实存在,但是肉眼不可见的字符 零宽度空格符 (zero-width space) U+200B 零宽度非断空格符 (zero width no-break space) U+FEFF 零宽度连字符 (zero-width joiner) U+200D 零宽度断字符 (zero-width non-joiner) U+200C 左至右符 (left-to-right mark) U+200E 右至左符 (right-to-left mark) U+200F

  • base隐写:不同于base编码,显著特征是
  • 一行几个字符,等号时有时无

一眼base隐写,贴(抄)个脚本:

import base64

def Base64Stego_Decrypt(LineList):
   Base64Char = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"     #Base64字符集 已按照规范排列
   BinaryText = ""
   for line in LineList:
       if line.find("==") > 0:     #如果文本中有2个=符号
           temp = bin(Base64Char.find(line[-3]) & 15)[2:]      #通过按位与&15运算取出二进制数后4位 [2:]的作用是将0b过滤掉
           BinaryText = BinaryText+"0"*(4-len(temp))+temp      #高位补0
       elif line.find("=") > 0:        #如果文本中有1个=符号
           temp = bin(Base64Char.find(line[-2]) & 3)[2:]       #通过按位与&3运算取出二进制数后2位
           BinaryText = BinaryText+"0"*(2-len(temp))+temp      #高位补0
   Text = ""
   if(len(BinaryText) % 8 != 0):       #最终得到的隐写数据二进制位数不一定都是8的倍数,为了避免数组越界,加上一个判断
       print("警告:二进制文本位数有误,将进行不完整解析。")
       for i in range(0, len(BinaryText), 8):
           if(i+8 > len(BinaryText)):
               Text = Text+"-"+BinaryText[i:]
               return Text
           else:
               Text = Text+chr(int(BinaryText[i:i+8], 2))
   else:
       for i in range(0, len(BinaryText), 8):
           Text = Text+chr(int(BinaryText[i:i+8], 2))      #将得到的二进制数每8位一组对照ASCII码转化字符
       return Text

def Base64_ForString_Decrypt(Text):     #Base64解密
   try:
       DecryptedText = str(Text).encode("utf-8")
       DecryptedText = base64.b64decode(DecryptedText)
       DecryptedText = DecryptedText.decode("utf-8")
   except:
       return 0
   return DecryptedText

if __name__ == "__main__":
   Course = input("base64文件绝对路径")
   File = open(Course, "r")
   LineList = File.read().splitlines()
   print("显式内容为:")
   for line in LineList:
       print(Base64_ForString_Decrypt(line),end="")
   print("隐写内容为:")
   print(Base64Stego_Decrypt(LineList))

发现执行报错,猜测还有其他隐写

截图

扔010,文本一般都不是什么好东西

截图

在倒数几行发现异常,由于记事本内不可见,故尝试零宽字符隐写,在线解密

好像复制不出来(?)扔vscode试试:

截图

复制,解密,得到后半段flag

截图

删除零宽字符隐写,利用脚本解密base隐写,得到前半段flag

截图

拼凑得到完整flag:NSSCTF{e16bc777-0d4a-4b74-92b4-404bc0320da4}

Cover Removed

出题人:WDLJT

考点:

PDF 隐写

wbStego

奇了怪了明明是常见隐写,给一堆人整不会了(,私聊有五分之一的都在问这个的后续。。。

  • 类比office隐写,全选,调色,放大……
  • 把信息藏在pdf文件本体中

下载下来是一个PDF,打开,类比前文 Coffee Please ,暂时无法编辑,全选看看

截图

发现异常,复制下来得到前半段flag:NSSCTF{c024c35f-7358

利用工具 wbStego4.3open ,发现存在PDF隐写,得到后半段flag

截图
截图

拼凑得到完整flag:NSSCTF{c024c35f-7358-46e2-b330-5ff837a3f9ad}

Crack Me

出题人:WDLJT

考点:

zip 伪加密

爆破

出题的时候大意了,应该把这两个顺序反一下,不然容易误解或者被跳过,下次一定!贴个选手 Writeup

拿到一个压缩包,当然是解压啦

截图

有密码,三种思路:

  • 伪加密:010查看压缩包相关数据
  • 直接爆破:ARCHPR
  • CRC爆破:位数较少,已知CRC

拖进010

截图

此处若为奇数,则加密,反之则未加密,先修改为偶数,尝试解压

截图

解压成功,得到两个一模一样的压缩包,直接爆破

  • tips:优先从数字开爆
截图

找到密码,解压,打开flag.txt

截图

这么多flag拿到手软(x

Cycles again

出题人:WDLJT

考点:

图片宽高 CRC 爆破

压缩包内 CRC 爆破明文

Two different types also similar,确实挺similar的

截图

一张损坏的last,拿到png先查宽高

考点:==图片宽高== ==CRC循环校验==

  • CRC可用于校验图片宽高,也可用于校验压缩包文件,借此来破解某些特殊的压缩包

贴个CRC校验宽高的脚本,本质上也是穷举

import zlib
import struct
import itertools

path = input('png文件绝对路径')

bin_data = open(path, 'rb').read()
crc32key = zlib.crc32(bin_data[12:29]) # 计算crc
original_crc32 = int(bin_data[29:33].hex(), 16) # 原始crc


if crc32key == original_crc32: # 计算crc对比原始crc
   print('宽高没有问题!')
else:
   input_ = input("宽高被改了, 是否CRC爆破宽高? (Y/n):")
   if input_ not in ["Y", "y", ""]:
       exit()
   else:
       for i, j in itertools.product(range(4095), range(4095)): # 理论上0x FF FF FF FF,但考虑到屏幕实际/cpu,0x 0F FF就差不多了,也就是4095宽度和高度
           data = bin_data[12:16] + struct.pack('>i', i) + struct.pack('>i', j) + bin_data[24:29]
           crc32 = zlib.crc32(data)
           if(crc32 == original_crc32): # 计算当图片大小为i:j时的CRC校验值,与图片中的CRC比较,当相同,则图片大小已经确定
               print(f"\nCRC32: {hex(original_crc32)}")
               print(f"宽度: {i}, hex: {hex(i)}")
               print(f"高度: {j}, hex: {hex(j)}")
               exit(0)
截图
截图

修改后可以正常显示,打开放大,找到第一段flag

截图

第二段flag在压缩包中,打开压缩包,发现加密

截图

原始大小4,初步断定4个字符,7段,和前面的凑起来刚好组成UUID格式的flag

对于这种形式的压缩包,结合题目提示,采用 ==CRC32== 来爆破内容,而不是密码

贴(抄)个脚本:

#!/usr/bin/env python 
# -*- coding:utf-8 -*-
# python3
import zipfile
import string
import binascii


def CrackCrc(f, crc):  # 通过枚举的方法暴力验证CRC,前提是已知长度
   for i in dic:
       for j in dic:
           for k in dic:
               for h in dic:
                   s = i + j + k + h   # 长度为4的字符
                   if crc == (binascii.crc32(s.encode())):
                       f.write(s)  # 记录爆破内容
                       return


def CrackZip():
   f = open("./result.txt", "w")
   for i in range(2,9):    # 生成2-8这几个数字,对应part文件名
       file = "./Moment.zip"
       crc = zipfile.ZipFile(file, 'r').getinfo(f'part{i}.txt').CRC
       CrackCrc(f,crc)
       print('\r' + "loading:{:%}".format(float((i - 1) / 7)), end='')
   f.close()
   with open("./result.txt", "r+", encoding='utf-8') as fr:
       res = fr.read()
   return res

if __name__ == "__main__":
   dic = string.ascii_letters + string.digits + '-{' + '}' # 字典,大小写+数字+短横线+大括号(UUID格式的flag)
   print("\nCRC32begin")
   res = CrackZip()
   print("\nCRC32finished\n")
   print(res)

可能需要爆个一分钟左右

截图

拼凑得到完整的flag:NSSCTF{41d769db-9f5d-455e-a458-8012ba3660f3}

Continue

出题人:WDLJT

考点:

脚本能力题

是一个压缩包,尝试解压有密码,The password is the same with the name

懂了,套娃,直接上脚本

(Python较慢,至少要跑二三十分钟,有能力的师傅可以试试其他语言)

import zipfile
zip_src='Continue.zip'
while True:
   r = zipfile.is_zipfile(zip_src)
   if r:    
       fz = zipfile.ZipFile(zip_src,"r")
       fz.extractall(pwd=bytes(fz.filename.replace('.zip',''),encoding='utf-8'))
       zip_src=fz.filelist[0].filename
   else:
       break

让他慢慢跑

截图

跑完

1479559098-307906989-FA8EE4D5D740FC77F1B8CB06A4A173F4.png)

真狠啊,2k个压缩包

截图

得到falg:NSSCTF{09b43595-8b96-4aa4-a5d2-c327c8e41174}

感谢观看我的博客~
SWPU NSS 2022 秋季招新赛 Misc 出题人笔记
https://www.wd-ljt.com/post/1024/896.html
来源于问谛居,转载记得联系作者哟~
THE END
分享
二维码
海报
SWPU NSS 2022 秋季招新赛 Misc 出题人笔记
前言 别骂了,后面还会再补完整的,因为被 gank 了,很多东西都是重新写的,稍晚点就会好,只能麻烦师傅们耐心等待了,呜呜呜呜 咕,出题的时候感觉都……
<<上一篇
下一篇>>