西电CTF平台——训练场强壮密码人和安全杂项及MoeCTF 2024 MISC篇

moectf是对ctf小白入门非常友好的一个网站,若对ctf感兴趣,可以一起加油进步
练习网址:https://ctf.xidian.edu.cn/training

强壮密码人

古典密码与编码

1. Augustine's Way

凯撒密码解密。
image

2. Augustine's Way#2

直接放入随波逐流CTF编码工具一键解码。
image

3. Ex Viginere?

根据重合指数爆破出密钥长度,计算k1和k2,就可以还原明文。在足够长的英文文本中,每个字母出现的频率有一个确定的值,重合指数就是根据这一统计规律来计算的。

import gmpy2
f = open(r'C:\Users\lvqiyun\Desktop\cipher','r')
c = f.read()
f.close()
# 我们已经知道,维吉尼亚密码可以被分解为若干组平移密码来破译,
# 而一个明文足够长的平移密码的重合指数接近 0.0687。
# 换言之,如果我们选取某个 l 值,使得分组后的密文的重合指数接近 0.065,
# 则说明选取的 t 值与密钥的长度是一致的。
best_index = 0.065
sum = 0
dic_index = {'a': 0.08167,'b': 0.01492,'c': 0.02782,'d':0.04253,'e': 0.12702,'f':0.02228,'g': 0.02015,'h':0.06094,'i':0.06966,'j':0.00153,'k':0.00772,'l':0.04025,'m':0.02406,'n':0.06749,'o':0.07507,'p':0.01929,'q':0.00095,'r':0.05987,'s':0.06327,'t':0.09056,'u':0.02758,'v':0.00978,'w':0.02360,'x':0.00150,'y':0.01974,'z':0.00074}
def IndCo(s):
    # 计算字符串的重合指数(所有字母出现频率的平方和)
    # 输入 s 
    # 输出 重合指数
    alpha = 'abcdefghijklmnopqrstuvwxyz'
    freq = {}
    for i in alpha:
        freq[i] = 0
    for i in s:
        freq[i] =  freq[i] + 1
    index = 0
    for i in alpha:
        index = index + (freq[i]*(freq[i] - 1 )) / (len(s) * (len(s) - 1 ))
    return index
def IndCo_m(s):
    # 计算明文 s 中的各字母频率和英文字母中的频率吻合程度
    # 输入:明文 s
    # 输出:吻合程度
    alpha = 'abcdefghijklmnopqrstuvwxyz'
    freq = {}
    for i in alpha:
        freq[i] = 0
    for i in s:
        freq[i] += 1
    index = 0
    for i in alpha:
        index += freq[i] / len(s) * dic_index[i]
    return index
def get_keylen(c):
    # 求出最符合统计学的 m,n 的最小公倍数,方法通过爆破足够大的周期样本,观察成倍出现的周期
    # 计算方法是解出每一个子密文段的重合指数然后求平均值 在和最佳重合指数相减 误差小于 0.01
    # 输入:密文
    # 输出:公共周期列表
    keylen = []
    for i in range(1,100):
        average_index = 0
        for j in range(i):
            s = ''.join(c[j+i*x] for x in range(0,len(c)//i))
            index = IndCo(s)
            average_index+=index
        average_index = average_index/i - best_index
        if abs(average_index)<0.01:
            keylen.append(i)
    return keylen
keylen = get_keylen(c)
print(keylen)
#____________________________得到 keylen_____________________________#
#____________________________爆破 flag———————————————————————————————#
def decrypt(c,i,j):
    alpha = 'abcdefghijklmnopqrstuvwxyz'
    m = ''
    for x in c:
        m += alpha[((alpha.index(x)-j)*gmpy2.invert(i,26))%26]
    return m 
def get_key(c):
    # 得到一个密文段的单个字符 key .i .j
    # 暴力枚举,找到最符合的
    # 输入:密文段
    # 输出:i,j
    for i in range(26):
        if gmpy2.gcd(i,26)!= 1 :
            continue
        for j in range(26):
            m = decrypt(c,i,j)
            index = IndCo_m(m)
            if abs(index-0.065)<0.01:
                return (i,j)
def get_all_key(s,keylen):
    # 得到一个周期内所有密文段的 key
    # 输入:原密文,周期
    # 输出:无
    for i in range(keylen):
        temps = ''.join([s[i+x*keylen] for x in range(0,len(s)//keylen)])
        print(get_key(temps))
get_all_key(c,keylen[0])
# 于是就可以分析得到 ka = []  kb= []
# 例如:(23, 9)(25, 21)(21, 9)(3, 10)(19, 16)(23, 3)(25, 22)(21, 13)(3, 14)(19, 21)(23, 15)(25, 9)(21, 21)(3, 9)(19, 10)(23, 16)(25, 3)(21, 22)(3, 13)(19, 14)(23, 21)(25, 15)(21, 9)(3, 21)(19, 9)(23, 10)(25, 16)(21, 3)(3, 22)(19, 13)(23, 14)(25, 21)(21, 15)(3, 9)(19, 21)(23, 9)(25, 10)(21, 16)(3, 3)(19, 22)(23, 13)(25, 14)(21, 21)(3, 15)(19, 9)(23, 21)(25, 9)(21, 10)(3, 16)(19, 3)(23, 22)(25, 13)(21, 14)(3, 21)(19, 15)
# 那么得到就是 k1=[23,25,21,3,19],k2=[9,21,9,10,16,3,22,13,14,21,15]

通过md5值进行爆破。

import gmpy2
from hashlib import*
k1=[9,7,25,11,11,19,5,3,25,9,7]
k2=[25,19,18,19,25,20,8]

f = open(r'C:\Users\lvqiyun\Desktop\cipher','r')
c = f.read()
f.close()
plaintext = ''
l1 = len(k1)
l2 = len(k2)
alpha='abcdefghijklmnopqrstuvwxyz'
for i in range(len(c)):
    plaintext+=alpha[((alpha.index(c[i])-k2[i%l2])*gmpy2.invert(k1[i%l1],26))%26]

for i in range(len(plaintext)):
    a=plaintext[i:i+16]
    b=a+'How_Interesting_the_Cryptography_Is'
    if(md5(b.encode()).hexdigest()=='196cf7098c7ea6e3e4d03691fb9d4f58'):
        print(a)
#moectf{pieceofchocolate}

4. Ez Vigenere

维吉尼亚密码不知道key,但是知道flag是以moectf开头的可以去试key,把前面六个字母都对上之后,flag就得到了。
image

5. OldButPopular

凯撒+栅栏,先凯撒,找首字母是m的,就是要找的字符串。 然后用在线网站解不太对,看一下长度发现是38,数一下moectf这几个字符的索引,发现分栏的方式应该是8 8 8 7 7,跟标准的栅栏密码稍微差那么一点。
image

a="mf3n_u31o{rtg7_dec__0_w}c4wt_t0t540ohr"
a1=a[:8]
a2=a[8:16]
a3=a[16:24]
a4=a[24:31]
a5=a[31:]
flag=[]
for i in range(8):
    flag.append(a1[i])
    flag.append(a2[i])
    flag.append(a3[i])
    if i <7:
        flag.append(a4[i])
        flag.append(a5[i])
for i in flag:
    print(i,end="")
# moectf{c453r_w4nt_t0_g0_ou7_th3_w0r1d}

6. vigenere

把内容复制到https://www.guballa.de/vigenere-solver 爆破一下。
image
把空格转换成下划线即可。
moectf{attacking_the_vigenere_cipher_is_interesting}

7. モンスターを縫う!

flag1凯撒解码
image
flag2维吉尼亚
image
flag3栅栏
image
flag4培根密码
image
flag5是rot13
image
flag6摩斯密码
image
拼接起来即可。moectf{cl@ssical_cipheripr3tTY_G00D!}

安全杂项

计算机基础

CCCC

在线代码平台运行。
image
代码的意思就是将flag数组中的每一个数先与0xff异或,然后在转换为字符。

Python

在线代码平台运行。
image
rol函数的作用是将数字大于等于8的按照二进制的形式右移三位再与上0xff,小于8的左移五位再与上0xff。
第一个for循环遍历enc数组里的每一个数,对里面的每一个数先进行rol函数的处理,再减去当前数在enc数组中对应的索引,然后再异或key字符串中i % len(key)索引的字母对应的ascii码值,最后得到结果。
第二个for循环是将处理完后的enc数组中的每一个数转换成其对应的字符,也是根据ascii码。

run_me

cmd命令行运行即可得到flag。
image

run_me2

kali中命令行运行即可得到flag。如果提示权限不够,给该文件赋予777的权限,让所有的用户都拥有读写执行权限。
image

杂项

Cor1e的支票

打开文件,看到里面只有。?!三种字符,立马联想到Ook!编码方式。
去Ook!编码网站随便输入点信息,转换成Ook!看一下,也是三种字符。
image
加密后的全是英文字符,但给我们的文件里是中文的字符,需要全部转换成英文的字符,然后每隔5位添加一个空格。

strings = "....................!?!!.?....................?.?!.?..................!.....!.?.......!?!!.?!!!!!!?.?!.?!!!.!!!!!.?.........!?!!.?........?.?!.?..!.?.......!?!!.?!!!!!!?.?!.?!!!!!!!!!!!.?.........!?!!.?........?.?!.?..........!.?.........!?!!.?!!!!!!!!?.?!.?!!!!!!!!!!!!!!!!!.?.......!?!!.?......?.?!.?......!.......!.?.................!?!!.?!!!!!!!!!!!!!!!!?.?!.?!!!.?...............!?!!.?..............?.?!.?......!.!!!!!!!!!!!!!.?...........!?!!.?!!!!!!!!!!?.?!.?!!!!!!!!!!!.?.............!?!!.?............?.?!.?..................!.?.............!?!!.?!!!!!!!!!!!!?.?!.?!!!!!!!!!!!!!.?...........!?!!.?..........?.?!.?....!.............!.?...............!?!!.?!!!!!!!!!!!!!!?.?!.?!!!.?...............!?!!.?..............?.?!.?..........................!.!!!!!!!!!!!!!!!!!.!!!!!!!!!.!!!!!!!!!!!!!.?.............!?!!.?!!!!!!!!!!!!?.?!.?!!!!!!!!!!!!!!!!!!!!!.?.................!?!!.?................?.?!.?....!.?.........!?!!.?!!!!!!!!?.?!.?!!!!!!!!!.?...........!?!!.?!!!!!!!!!!?.?!.?!!!!!!!.?.......!?!!.?......?.?!.?........!.?.............!?!!.?............?.?!.?..................!.?."
res = ""
for i in range(0, len(strings), 5):
    res += strings[i:i+5]+" "
print(res)
# ..... ..... ..... ..... !?!!. ?.... ..... ..... ..... .?.?! .?... ..... ..... ..... !.... .!.?. ..... .!?!! .?!!! !!!?. ?!.?! !!.!! !!!.? ..... ....! ?!!.? ..... ...?. ?!.?. .!.?. ..... .!?!! .?!!! !!!?. ?!.?! !!!!! !!!!! .?... ..... .!?!! .?... ..... ?.?!. ?.... ..... .!.?. ..... ...!? !!.?! !!!!! !!?.? !.?!! !!!!! !!!!! !!!!! .?... ....! ?!!.? ..... .?.?! .?... ...!. ..... .!.?. ..... ..... ..... .!?!! .?!!! !!!!! !!!!! !!!?. ?!.?! !!.?. ..... ..... ....! ?!!.? ..... ..... ....? .?!.? ..... .!.!! !!!!! !!!!! !.?.. ..... ....! ?!!.? !!!!! !!!!! ?.?!. ?!!!! !!!!! !!.?. ..... ..... ..!?! !.?.. ..... ..... ?.?!. ?.... ..... ..... ....! .?... ..... ..... !?!!. ?!!!! !!!!! !!!?. ?!.?! !!!!! !!!!! !!.?. ..... ..... !?!!. ?.... ..... .?.?! .?... .!... ..... ..... !.?.. ..... ..... ...!? !!.?! !!!!! !!!!! !!!?. ?!.?! !!.?. ..... ..... ....! ?!!.? ..... ..... ....? .?!.? ..... ..... ..... ..... ..... .!.!! !!!!! !!!!! !!!!! .!!!! !!!!! .!!!! !!!!! !!!!. ?.... ..... ....! ?!!.? !!!!! !!!!! !!?.? !.?!! !!!!! !!!!! !!!!! !!!!. ?.... ..... ..... ...!? !!.?. ..... ..... ..... ?.?!. ?.... !.?.. ..... ..!?! !.?!! !!!!! !?.?! .?!!! !!!!! !.?.. ..... ....! ?!!.? !!!!! !!!!! ?.?!. ?!!!! !!!.? ..... ..!?! !.?.. ....? .?!.? ..... ...!. ?.... ..... ....! ?!!.? ..... ..... ..?.? !.?.. ..... ..... ..... .!.?.

将处理好的字符串放进去进行解码即可得到flag。
image

Locked_bass

压缩包解压有一个需要密码的压缩包。
用16进制软件打开,发现是个伪加密。
image
将0900改为0000,再进行解压。
image
得到一串字符串。
这就是你要的贝斯:bW9lY3Rme04wd190aDFzX2k0X2FfYkBzc19VX2Nhbl91M2VfdG9fcGxhOX0=
进行base64解码后得到flag。
image

Macross

百度上搜有效信息一点没有,上 Google 搜出来是个记录鼠标移动的软件,下载安装,然后打开 Windows 图画,运行文件,得到名画。
image
moectf{Rec0rder_15_Funny}

OsuMaster

自己下载个osu软件玩吧,根据音乐画图即可。

White Album

解压得到图片放到kali中打开,提示crc校验错误,说明宽高不对
image
利用脚本得到正确的宽高值。

import struct
import binascii
import os

m = open("C:/Users/lvqiyun/Desktop/white_album.png", "rb").read()
k = 0
for i in range(5000):
    if k == 1:
        break
    for j in range(5000):
        c = m[12:16] + struct.pack('>i', i) + struct.pack('>i', j) + m[24:29]
        crc = binascii.crc32(c) & 0xffffffff
        if crc == 0x7E9DC7DB:
            k = 1
            print(hex(i), hex(j))
            break
# 0x400 0x2fc

图片用HxD打开,把它的宽高改成如上的值。
image

1、开头的0~7八个字节为png的文件头:89 50 4E 47 0D 0A 1A 0A (固定格式)
2、8~11四个字节:00 00 00 0D 表示头部数据块的长度为13(固定格式)
3、12~15四个字节:49 48 44 52 表示文件头数据块的标示(固定格式)
4、16~19四个字节:00 00 04 00表示图片的宽(不固定)
5、20~23四个字节:00 00 02 80表示图片的高(不固定)
6、24~28五个字节:08 06 00 00 00表示Bit depth(图像深度)、ColorType(颜色类型)、 Compression method(压缩方法)、 Filter method(滤波器方法)、Interlace method(隔行扫描方法)这五个字节不固定,均为可变数据
7、29~32四个字节:7E 9D C7 DB为图片的crc校验值由从第12个字节到第28个字节的十七位字节进行crc计算得到

打开图片,看到下面有像二维码的东西,但不完整。
image
以为是要拼成一个二维码,但有5块不对,再注意两边有点像条纹码,一直找在线网站,找到了该网站。在线条形码选择pdf417,即可读到flag。
image

bell202

题目提示解调器,根据文件名modem的解释也知道跟解调器相关,kali中minimodem命令可以读取。
bell202对应参数1200
image
minimodem --rx -f moe_modem.wav 1200
image

cccrrc

解压需要密码,一开始以为是伪加密,改了标志位后无果。再一看里面的文件大小,都只有几KB,可以采用crc爆破的方式。
image
脚本地址:https://gitcode.com/gh_mirrors/cr/crc32?utm_source=csdn_github_accelerator&isLogin=1
使用命令:python crc32.py reverse 0x67b2d3df
image
四个文件全部爆破出来后,16进制转字符即可。
image

find_me

直接利用kali自带的zsteg命令即可拿到flag。
image

hide-and-seek

pdf本质上也是一个zip,这题肯定是pdf隐写了,不管三七二十一,拖进kali,利用strings命令读取。
image
看到东西了,flag被拆分到/ActualText标签后面,过滤出来进行拼接。
image
moectf{Hey_U_ve_f0und_m3!}

nyanyanya

kali的zsteg一把梭。
image

rabbit

16进制打开,在末尾看到字符串。
image
结合题目,是个rabbit加密,直接无密钥解密拿到flag。
解密网址:https://www.sojson.com/encrypt_rabbit.html
image

what_do_you_recognize_me_by

16进制打开文件,发现文件头有点奇怪,看前面三个字节应该是png,但是第4个字节有问题,再看文件尾,确认是png文件,需要修改第4个字节为47。
image
image
image
打开是个二维码,利用在线网站或工具识别得到flag。
image

zip套娃

两个加密压缩包,没发现线索,直接爆破得到密码。
image
打开密码.txt
image
掩码爆破。不知道为啥没有拿到,且用网上爆破出来的密码也不对,可能是压缩包有问题,就这样吧。

不会吧,就这?

内容里只有两类,以为是培根密码或者摩斯密码,结果都不是。
image
将不会吧?视为1,就这¿视为0,8位二进制再转换成字符即可。(每一行需要逆序),脚本如下:

with open("puzzle.txt", mode="r", encoding="utf-8") as f:
    lines = f.readlines()
    for line in lines:
        res = line.replace("不会吧?", "1").replace("就这¿", "0").replace("\n","").replace(" ","")
        print(chr(int(res[::-1], 2)), end="")       # Y0u_wh4t?-0n1y_th1S?

用moectf{}包括即可。

寻找黑客的家

根据朋友圈的照片关键词红荔村,可以知道是在广东省。
image
根据另一张图汉明宫搜索,有很多店,只能去试了,结果是下图这家店。
image
flag为moectf{shenzhen_longhua_qingquan}

小纸条

变相的猪圈密码,只是在空白的那一侧加上了一条弯线。
image
对照着上图可以得到ILOVEMYBIGBED,拼接moectf{}即可。

想听点啥

解压得到一个加密压缩包,一个音频,一个mscz文件。听音频没发现,然后搜索mscz是什么,它需要用到MuseScore软件,下载完启动即可。
image
打开看到字符串MOECTFI1iKEiSTHEPASSWORD,说明密码是MOECTFI1iKE.
image
解压得到一个python文件,里面就是一个异或操作。

file = open("flag.txt", "rb").read()
flag = "m"
for i in range(len(file)):
    flag += chr(ord(flag[i]) ^ file[i])
print(flag)		# moectf{Want_s0me_mor3_mus1c?}

星空

kali里一顿命令梭,有隐写的内容。
image
是个rar格式的压缩包,16进制打开,找到rar格式的文件头52617221,将其下面的16进制代码全部复制出来,保存为rar文件。
image
解压,得到420张图片,随便看看,就能看到有红色的线,看来只要拼凑完好就能拿到flag。
image
image
先用https://uutool.cn/photo-collage/ 网站将420张图片拼接或者用kali的montage命令拼接,然后再利用kali里的gaps命令自动解拼图拿到flag。(不知道为啥,命令执行了几个小时都没拼出来)
montage *.jpg -tile 20x21 -geometry +0+0 flag.jpg
gaps --image=1111.jpg --generations=30 --population=420
moectf{thE_5t@rrY_sKy_1s_ReAlly_beauTifuL}

MoeCTF 2024

安全杂项

so many 'm'

拿到手是一段乱序的文本,需要词频统计。附上代码。

# -*- coding:utf-8 -*-

alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#$%^&*()_+- =\\{\\}[]"
strings = open('C:/Users/lvqiyun/Desktop/flag.txt').read()
result = {}
for i in alphabet:
    counts = strings.count(i)
    i = '{0}'.format(i)
    result[i] = counts




res = sorted(result.items(), key=lambda item: item[1], reverse=True)
for data in res:
    print(data)

for i in res:
    flag = str(i[0])
    print(flag[0], end="")

运行结果如下。
image
提交结果不正确,再一看提示,“如果有某几个字符无法判断顺序请按字典序排序”,看到结果p和M的数量一致,需要把M放前面,换下顺序,提交成功。
moectf{C0MpuTaskingD4rE}

杂项入门指北

看图片的右半部分能够看到莫斯密码。
image
翻译一下,得到结果。
.... ....- ...- . ..--.- .- ..--.- --. ----- ----- -.. ..--.- - .---- -- .
image

罗小黑战记

看完gif图,能看到有一个二维码一闪而过,利用stegsolve工具分解帧,将第110帧保存。
image
然后扫码完成。
image

ez_F5

根据文字描述,是个F5隐写,需要利用F5-steganography隐写工具进行提取。
密码通过查看图片属性然后base32解码得到。
image
image
命令如下:java Extract suantouwangba.jpg -p no_password -e output.txt

image
打开output.txt即可拿到flag。
image

Find It

先看图片的属性,没有位置信息经纬度等有用信息,看图片里的线索,首先能看到雄峰集团和美居酒店。
image
百度搜索雄峰集团,看图片,根据对比应该是陕西的。
image
继续细化定位,位于西安经济技术开发区。
image
上高德地图,搜索西安雄峰集团,然后搜他周边的幼儿园。
image
image
这两个幼儿园位于同一个小区内,锁定了,提取共同的字,吉的堡幼儿园,转换为拼音即可。
moectf{ji_di_bao_you_er_yuan}

Abnormal lag

Audacity打开音频,切换到频谱图,可以在头尾看到隐写的东西。
image
image
image
image
有些地方看不太清,但是结果中只有数字和a-f之间的字符,所以多尝试几次就可以了。
moectf{09e3f7f8-c970-4c71-92b0-6f03a677421a}

The upside and down

下载得到16进制文件,翻到最下面可以看到熟悉的png格式的文件头,只是写反了,再观察头部,也是倒序了,所以只需将整段16进制倒叙保存为png文件即可。
image
image
将16进制的数据复制出来,用python倒序一下再保存为png文件。
image
得到一个二维码,扫描得到flag。
image

ctfer2077①

得到一张二维码,扫描得到一串字符串。
image
尝试去解码,无果,以为这张照片里隐藏了一段视频,kali分析一下,单纯的只是一张照片。
image
zsteg命令隐写一把梭出答案。
image

ctfer2077②

根据题目提示,是一个加密卷,利用veracrypt工具进行加载,密码通过社会主义核心价值观加解密网站解密得到。
image
加载完后有一个flag?.txt文件,打开无用。
image
查看挂载盘的属性是NTFS,利用ntfsstreamseditor软件得到一个小鹤.txt文件。
image
根据小鹤双拼的对应图进行翻译。
image
第一行:shuangpinzhengdehenyouyisibushima(双拼真的很有意思不是吗)
第二行:key jiushixiamianzheduanhuadequanpinxiaoxie(key就是下面这段话的全拼小写)
第三行:shuangpinshizheyangdazide
将第三行提交即可。

ctfer2077③

wireshark打开流量包,选择文件->导出对象->HTTP,将两个upload文件保存下来。
image
image
1个只有1kb,一个有3617kb
image
打开1kb的内容如下,提示压缩包文件上传成功。
image
看来压缩包在另外一个文件中,利用kali的foremost命令分解,得到压缩包,解压得到MP3、gif和zip文件。MP3文件用audacity软件打开,没有发现。stegsolve打开gif文件,查看每一帧,在第30帧看到一个密码。
image
尝试用这个密码去解压缩包,密码不多,看来这密码是用于MP3文件的,利用MP3Stego软件解密。
Decode.exe -X -P C5EZFsC6 brainfuck.mp3
image
打开brainfuck.mp3.txt,发现是brainfuck编码方式,brainfuck解码一下。
image
image
拿到密码解压,拿到三个txt文件,全是1和0组成的字符串。根据提示,是福尔摩斯小人编码。
image
根据福尔摩斯小人密码表对照得到flag。
image
image
image
image
moectf{PEOPLE_DANCING_HAPPILY}

每人至少300份

到手九张图片,一个py文件,一个txt文件,第一想法就是拼图,根据边角的连接能还原如下。
image
扫码一下,得到key,在进行base58解码。
image
image
然后再去看py文件和txt文件,是一段加密函数,英文字符若是a-g之间就转换成t-z,若是t-z之间就转换成a-g,若是h-s之间就转换成s-h;数字字符就是前一个和后一个异或,最后一个不变,写python脚本还原。

def self_decoding(encode_text):
    code_setting_first = "doanythingfryuienbcjklmqpsw"
    code_setting_last = ""
    data_set = {}
    decoded_text = []
    for x in code_setting_first:
        if ord(x) < 104:  # h
            num = ord(x) + 19
        elif ord(x) > 115:  # s
            num = ord(x) - 19
        elif 104 <= ord(x) <= 115:
            num = 219 - ord(x)
        code_setting_last += chr(num)
        data_set[chr(num)] = x

    for x in encode_text:
        if x in code_setting_last:
            decoded_text.append(data_set[x])

    number_setting = "012345678913"
    temp = []
    for i in range(len(encode_text) - 1, 0, -1):
        if encode_text[i] in number_setting:
            if i != len(encode_text) - 1:
                x = str(int(encode_text[i]) ^ int(encode_text[i + 1]))
                encode_text[i] = x
            elif i == len(encode_text) - 1:
                x = encode_text[-1]
            temp.append(x)
    decoded_text += temp[::-1]
    return decoded_text


def reverse_decoding(input_text):
    output_text = input_text[::-1]
    return output_text


if __name__ == "__main__":
    with open('encoded.txt', 'r') as fin:
        data = []
        for line in fin:
            line = reverse_decoding(line)
            line = line.replace('\n', '')
            data = line.split(' ')
            print(''.join(self_decoding(data)))

运行结果如下
image
也是告诉我们图片的排列顺序,直接拼就完事了,将base58解码后的结果提交即可。

捂住一只耳

音频最后报了一串数字63 31 43 31 41 52 31 51 71 101,根据提示,是键盘码,第一位数代表数字几,第二位代表数字几下的第几个字符,101是数字0下的第一个字符,翻译完后就是NEVERGETUP。

小小套娃

解压得到图片和加密压缩包,对于图片,直接丢kali里一顿命令。
file、zsteg、binwalk -e、pngcheck等命令都试试,这里发现IDAT块有问题。
image
利用binwalk -e分离,得到四个文件,发现有个文件里面是png格式的16进制。
image
图片是个二维码,扫描得到压缩包密码。
image
解压得到txt和加密压缩包。txt里是零宽字符(需要用sublime text、kali的vim命令、winhex等工具打开即可看到)。
image
通过零宽字符隐写网站里的解密网站全部试一遍,可拿到解密内容。
image
解压得到txt,新佛曰加密,不过原来能解密的网站现在不开源了,找了半天没找到替代品。(目前只能先看别人解出来的答案了)
image
image

时光穿梭机

根据题目故事描述,有几个关键词:1946年4月20日、国内知名古墓、遗址公园、正对的中医院、伦敦当时最有名的图报当然是the illustrated London News。
上网搜索到了对应的图报,但是查看需要付费,只能放弃了。
image
这个时候就可以借助AI了,直接搜索1946年4月20日《伦敦新闻画报》中提到的中国古墓是哪一座墓得到答案为王建永陵。
image
高德地图搜索王建永陵,查看其附近的中医院,有两个,经过尝试是汉方堂中医门诊部
image
所以flag为moectf{han_fang_tang}

ez_usbpcap

题目提示是键盘流量,先看下数据在hid data里。
image
利用tshark命令将这个字段的值都提出来。tshark -r flag.pcapng -T fields -e usbhid.data | sed '/^\s*$/d' > usbdata.txt,结果如下。
image
网上搜索一下每个键盘按键对应的键码值,然后写python脚本还原。

normalKeys = {"04": "a", "05": "b", "06": "c", "07": "d", "08": "e", "09": "f", "0a": "g", "0b": "h", "0c": "i",
              "0d": "j", "0e": "k", "0f": "l", "10": "m", "11": "n", "12": "o", "13": "p", "14": "q", "15": "r",
              "16": "s", "17": "t", "18": "u", "19": "v", "1a": "w", "1b": "x", "1c": "y", "1d": "z", "1e": "1",
              "1f": "2", "20": "3", "21": "4", "22": "5", "23": "6", "24": "7", "25": "8", "26": "9", "27": "0",
              "28": "<RET>", "29": "<ESC>", "2a": "<DEL>", "2b": "\t", "2c": "<SPACE>", "2d": "-", "2e": "=", "2f": "[",
              "30": "]", "31": "\\", "32": "<NON>", "33": ";", "34": "'", "35": "<GA>", "36": ",", "37": ".", "38": "/",
              "39": "<CAP>", "3a": "<F1>", "3b": "<F2>", "3c": "<F3>", "3d": "<F4>", "3e": "<F5>", "3f": "<F6>",
              "40": "<F7>", "41": "<F8>", "42": "<F9>", "43": "<F10>", "44": "<F11>", "45": "<F12>",
              "59": "1", "5a": "2", "5b": "3", "5c": "4", "5d": "5", "5e": "6", "5f": "7", "60": "8", "61": "9",
              "62": "0", }

shiftKeys = {"04": "A", "05": "B", "06": "C", "07": "D", "08": "E", "09": "F", "0a": "G", "0b": "H", "0c": "I",
             "0d": "J", "0e": "K", "0f": "L", "10": "M", "11": "N", "12": "O", "13": "P", "14": "Q", "15": "R",
             "16": "S", "17": "T", "18": "U", "19": "V", "1a": "W", "1b": "X", "1c": "Y", "1d": "Z", "1e": "!",
             "1f": "@", "20": "#", "21": "$", "22": "%", "23": "^", "24": "&", "25": "*", "26": "(", "27": ")",
             "28": "<RET>", "29": "<ESC>", "2a": "<DEL>", "2b": "\t", "2c": "<SPACE>", "2d": "_", "2e": "+", "2f": "{",
             "30": "}", "31": "|", "32": "<NON>", "33": "\"", "34": ":", "35": "<GA>", "36": "<", "37": ">", "38": "?",
             "39": "<CAP>", "3a": "<F1>", "3b": "<F2>", "3c": "<F3>", "3d": "<F4>", "3e": "<F5>", "3f": "<F6>",
             "40": "<F7>", "41": "<F8>", "42": "<F9>", "43": "<F10>", "44": "<F11>", "45": "<F12>"}


file = open("usbdata.txt")
res_usb_data = []
for line in file.readlines():
    if line[4:6] in normalKeys:
        res_usb_data.append(normalKeys[line[4:6]])
    elif line[4:6] in shiftKeys:
        res_usb_data.append(shiftKeys[line[4:6]])
    else:
        continue
res = ""
for i in res_usb_data:
    res += i
print(res)	# 6d6f656374667b6e3168613077307930756469616e6c33323435317ddgmqtwx

最后进行16进制转换即可拿到flag。
image

the_secret_of_snowball

一张损坏的图片,16进制打开,以为有隐藏信息,用kali的file命令解析了一下,没有。拉到最下面,看到base64编码字符。
image
解码得到如下字符串。
image
再一看jpg文件的文件头应该是FFD8FF,文件尾是FFD9,而下载的图片的文件头是FFD6FF,需要修改,然后搜索FFD9,将后面的删除。还原得到正常的图片。
image
image
image
将图片里的和解码得到的一拼接就是flag。moectf{Welc0me_t0_the_secret_life_0f_Misc!}

我的图层在你之上

得到pdf文件和加密压缩包,先用wbs43open-win32这个强大的工具试了一下,没东西,然后kali里一顿命令,啥也没发现,可能秘密就在图片里了。利用pdf2docx库转换提出图片。
pip install pdf2docx

from pdf2docx import Converter

pdf_file = "black.pdf"
docx_file = "black.docx"

cv = Converter(pdf_file)
cv.convert(docx_file)
cv.close()

提出来之后又是kali里一顿梭,还是没发现,老老实实用stegsolve打开,看了半天,在blue plane0中看到了内容。key=p_w_d
image
解压得到txt文件。
image
凯撒解一下拿到flag。
image

解不完的压缩包

python脚本解压,直到一个加密的压缩包cccccccrc.zip。

import zipfile

name = "999"
while True:
    fz = zipfile.ZipFile(name + '.zip', 'r')
    fz.extractall()
    str1 = str(fz.filelist[0].filename)
    index = str1.find(".")
    name = str1[:index]
    fz.close()

打开压缩包,发现pwd的四个txt文件都比较小,尝试用crc校验码爆破内容。
image
四个文件爆破出来的内容16进制转换后都是些乱码,所以就写了个脚本爆破。

import string
import zipfile
import binascii

dic = string.ascii_letters + string.digits + ':+-=_!()/*&%$#@^'


def caclCRC(crc):
    #每个密码文件都是两个字节,嵌套两个循环即可
    for k1 in dic:
        for k2 in dic:
            s = k1 + k2
            s = str(s).encode()
            if (binascii.crc32(s)) == crc:
                return s.decode('utf-8')

def getCRC():
    f = zipfile.ZipFile("cccccccrc.zip", "r")
    password = ''
    for i in range(1,5):
        GetCrc = f.getinfo(f"pwd{i}.txt")
        crc = GetCrc.CRC
        password += caclCRC(crc)

    return password

print(getCRC())

运行得到密码*m:#P7j0,解压得到flag.txt,拿到flag。
image

拼图羔手

16张图片可以拼成一张二维码,这里可以借用montage和gaps命令或者手搓,得到二维码。
image
扫码得到加密后的flag。
image
接下来就是对encode.py反写解密就好了。

from base64 import b64decode

encode_data = "71517ysd%ryxsc!usv@ucy*wqosy*qxl&sxl*sbys^wb$syqwp$ysyw!qpw@hs"
encode_key = b'eGl4c2R4bmxVbVhpeHVuYkdzYXJkZnRhVWl4YXZ0aXRzSnh6bXRpYVU='


def reverse_encoding(input_text):
    output_text = input_text[::-1]
    return output_text


def self_decoding(input_text):
    code_setting_first = "doanythigfruebcjklmqpswvxz"
    code_setting_sec = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    number_setting = "0123456789"
    decoded_text = " "
    for x in input_text:
        if x in code_setting_first:
            if 116 <= ord(x) <= 122:
                num = ord(x) - 19
            elif 103 >= ord(x) >= 97:
                num = ord(x) + 19
            elif 115 >= ord(x) >= 104:
                num = 219 - ord(x)
            decoded_text += chr(num)

        elif x in code_setting_sec:
            if 72 <= ord(x) <= 78:
                num = ord(x) - 7
            elif 65 <= ord(x) <= 71:
                num = ord(x) + 7
            elif 88 <= ord(x) <= 90:
                num = ord(x) - 9
            elif 79 <= ord(x) <= 81:
                num = ord(x) + 9
            elif 86 >= ord(x) >= 81:
                num = 168 - ord(x)
            decoded_text += chr(num)

        elif x not in number_setting:
            decoded_text += x

    temp = []
    lst = ["7", "1", "5", "1", "7"]
    for i in range(len(lst)-1,-1,-1):
        if lst[i] in number_setting:
            if i != len(lst) - 1:
                x = str(int(lst[i]) ^ int(lst[i + 1]))
                lst[i] = x
            elif i == len(lst) - 1:
                x = lst[-1]
            temp.append(x)
    decoded_text += "".join(temp[::-1])
    return decoded_text

def decode_strange_character_hint(encode_key):
    key = str(b64decode(encode_key.decode("utf-8")))
    res = reverse_encoding(self_decoding(key))
    print("".join(res.split(" ")))


print("".join((self_decoding(reverse_encoding(encode_data))).split(" ")))	# hs@dkj!dfhf$kdjfh$ud^hfuh*oeh&oej*fhljd*fvb@chb!vhefi%whf52367
decode_strange_character_hint(encode_key)   # 'StrangeCharacterStaywithNumberOnSomewhere'

提交解密后的内容发现不对,再看到提示中特殊字符不能出现在flag中,需要用对应的数字替代。
image
结合键盘,!对应1,@对应2,以此类推,替换完之后得到正确flag,moectf{hs2dkj1dfhf4kdjfh4ud6hfuh8oeh7oej8fhljd8fvb2chb1vhefi5whf52367}。

posted @ 2025-06-24 18:49  死不悔改奇男子  阅读(1915)  评论(0)    收藏  举报