0x01七七的礼物
下载压缩包进行解密,跑出来密码为12138
进行解压得到三个文件,第三个zip还有加密,
mv ‘.\1 (*)*’ .
先看了第一个文本文件,不懂就问,现在我们知道是AES加密,需要密钥,末尾的一段应该有用
看下一个图片,通过strings
发现有很多压缩包,
直接通过foremost分离出来,
全部解压出来发现都是小碎片,这波只能扣6了
找大佬的博客,得到拼好的内容
scumbagtree
在接下来看第三个压缩包,需要密码,试了一下刚才得到的密码,错误,然后就是跑
跑的电脑都热死了,回想之前小明的数学作业.txt后面的 14#AbbQ%C试了一下出来了,wc
解压得到6张图片,三张英语单词翻译了,好像也没有有用的东西,
参考大佬的博客:https://www.st1ck4r.top/posts/15972/
得到密钥scumbagtreelived
跟着大佬走,准没错
得到知乎地址然后就蒙蔽了,啥信息也没得到,就只能在网上找wp了,然后看到一篇文章
https://asciix.github.io/blog/QiQi.html,他还故意给这个页面打了码,然后去解密兽语,没解出来,看着有点猫腻,可能是摩斯密码
然后就试着改了一下,发现可以
解密一下真的得到一个微博地址
找到提示的二维码了
避个坑一定要下载原图,不要右键另存为,点进去查看大图
用工具SilentEye 解密,记得要用原图,不然解不出来
解密一下得到前半部分flag{happybirthdayg
扫了半天才扫出来
=E2=88=B7=E1=92=B7=E1=92=B7=E3=83=AA=E1=92=A3 =E2=88=B7=E1=92=B7=E1=92=B7
是Quoted-printable 加密 解密一下得到:∷ᒷᒷリᒣ ∷ᒷᒷ
对照一下这个网址提供的http://www.suphp.cn/anquanke/87/272987.html 银河字母加密
对照一下得到密文:reentree
拼接一下得到flag
0x02gakki
得到一张图片,通过binwalk分离出来得到一个rar文件
有密码,通过bandzip 跑出来
打开flag.txt文件,一堆毫无逻辑的编码
应该是字符统计,用脚本跑一下
a = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#$%^&*()_+- =\\{\\}[]"
b = open('D:/project/CTFscript/flag.txt').read()
result = {}
for i in a:
counts = b.count(i)
i = '{0}'.format(i)
result[i] = counts
res = sorted(result.items(),key=lambda item:item[1],reverse=True)
for date in res:
print(date)
for i in res:
flag = str(i[0])
print(flag[0], end='')
得到flag:GXY{gaki_IsMyw1fe}
0x03 Markdown
打开得到FLAG
0x04StegoTXT
得到一个文本文件
0宽加密
https://www.mzy0.com/ctftools/zerowidth1/
0x05欢迎
解压得到一堆图片
通过montage工具进行组合得到flag
montage.exe *.png -geometry +0+0 -background #00000000 big.png
qsnctf{Moxin Want to have a full meal.}
0x06 Bear
下载文件得到熊曰加密,通过在线网站解密得到flag qsnctf{80038e81-5f67-4085-a70e-77a3fd74cf96}
0x07 key
下载得到两个文件
图片内容没什么东西,flag文件里存在 snow隐写
通过SNOW工具进行解密得到flag
0x08 索马里海盗
通过提示查询索马里的IP地址
整合字典最终跑出来是: 197.157.245.96 直接打开得到flag
0x9 SilentEye
用SilentEye工具进行解密 猜测文件名即密码得到
得到brainfuck加密信息进行解密得到flag
0x10hanser
文本翻译了一下但是没什么东西
文本看着有些多,0宽解密发现有乱码
换了几个网站发现 https://yuanfux.github.io/zero-width-web/ 这个网站可以解 没东西呀,
对压缩包进行破解最终跑出来密码 !1!1
查看文件尾发现是jpg格式的而文件头却是PNG尝试修改文件头,最终观察了一下发现是jpeg文件,
弄了好久,去看了wp才知道要用image IN这个工具,才得到有flag字眼的图片,
0x11 disk
参考 https://blog.csdn.net/pone2233/article/details/108593252
0x12 Revenge
解压得到一张图片和压缩包,压缩包要密码
010查看图片在尾部发现解压密码: SICTF{this_1s_f1ag}
直接打开key.pyc文件乱码,用strings也没得到什么有用的信息
尝试了各种手法也没接出来,看了wp才知道要写逆脚本我直接当场GG,代码如下
import cv2
import numpy as np
img = np.float32(cv2.imread('flag.png', 1))
bin_str = ""
for i in range(64):
for j in range(64):
for channel in range(3):
channel_img = img[:, :, channel]
number = cv2.dct(channel_img[8 * i:8 * i + 8, 8 * j:8 * j + 8])
# print(number[(7, 7)])
if number[(7, 7)] > 10:
bin_str += "1"
elif number[(7, 7)] < -10:
bin_str += "0"
print(bin_str)
print(len(bin_str))
运行得到一大堆01,去掉后面一大串补全的0
进行 多次解密 2进制转Ascii > Base58 > Base 32 > Base 64
得到的字符进行维吉尼亚密码的爆破,参考:https://blog.csdn.net/qq_47875210/article/details/128736277
0x13 初音未来
解压得到一张图片,010打开一堆字符,
尝试一些解码发现base64解出来的是png文件的内容,直接保存一手
直接打开文件还是打不开,发现文件头被弄反了,改回原文件头,发现还是不对,观察了一下发现好像所有的都被弄反了,
写脚本直接就是无从下手,去看wp得到反转脚本
f=open("./download.png","rb")
ff=open("./flag123.png","wb")
dat1 = f.read()
for i1 in range(0,len(dat1),2):
for i2 in [1,0]:
try:
W=chr(dat1[i1+i2]).encode("iso8859-1") #
ff.write(W)
except:pass
ff.close()
但是有个问题奥,运行得到的flag123.png,文件头部没有转换完成需要重新改成89 50 4E 47 0D 0A 1A 0A就能打开图片了,
查了一下密码为什么是4536251
结果到这里就卡住了,查半天要用特定工具才能解出来,对我这个菜鸟及其不友好。要用cloacked-pixel进行解密
0x14 信息传递
下载得到一个流量包和字典,我上来就是一手foremost提文件,结果提取出来的就是一些网页文件,还有乱码看不懂导出http文件查看也就找到个登录页面,应该也没什么用导出IMF 文件发现有些东西,由于
依次打开发现picture.eml文件里有个压缩包,
直接base64解码在保存就得到了压缩包结果还有密码,跑了一下常用CTF密码也没跑出来,只能去包里找了,找到一个WRWAALIUWOHZAPQW,但是不对,难道还有?我直接一手strings大法 ,密码为:WRWAALIUWOHZAPQWFTQIPMVJFOKHHZUZ
一堆黑白图片应该是01转换,直接转换一下,脚本写不出来,直接就是一手手敲01,得到ISCC{i2s0c2c3} 但是不对,对照一开始给的字典,
对照一下拿到flag
0x15 FindHideMsg
下载得到一张图片
直接就是 foremost 分离得到一个压缩包解压又是一张图片
strings了一下发现有个感觉像密码的字符
直接就是cloacked-pixel 拿到flag
0x16 EZjoanDaemen
伪加密,binwalk分离出来
得到一个word文档,打开也没啥有用信息,到这就卡住了
cat查看的时候发现有图片,binwalk分离,得到一堆图片,
到这里是麻了,怎么看都没啥东西,用Stegsolve发现头部有东西,看这像是AES或者别的什么加密
参考 https://blog.csdn.net/qq_52307221/article/details/128155977
原来文档下面空白那一部分存在SNOW加密使用SNOW工具进行解密得到AES的key
用大佬脚本提取到了flag
'''
# @Author: https://github.com/librauee/Steganalysis/blob/master/LSB/get_info.py
# @Date: 2022-12-02 16:08:22
# @LastEditors: St1ck4r
# @LastEditTime: 2022-12-02 17:13:07
# @link: https://www.st1ck4r.top
'''
from PIL import Image
from Crypto.Cipher import AES
import base64
# aes密钥
password = b'welcome_to_misc!'
# AES ECB模式解密
def aesecb(c):
en_text = base64.b64decode(c) #需要加密的内容,bytes类型
aes = AES.new(password,AES.MODE_ECB) #创建一个aes对象
# AES.MODE_ECB 表示模式是ECB模式
den_text = aes.decrypt(en_text) # 解密密文
return den_text.decode().strip(b'\x00'.decode()) # den_text.decode():转化为str类型,strip(b'\x00'.decode()):去除末尾生成的\x00
def mod(x,y):
return x%y
def toasc(strr):
return int(strr, 2)
#le为所要提取的信息的长度,str1为加密载体图片的路径,str2为提取文件的保存路径
def func(le,str1,str2):
b=""
im = Image.open(str1)
lenth = le*8
width,height = im.size[0],im.size[1]
count = 0
for h in range(height):
for w in range(width):
#获得(w,h)点像素的值
pixel = im.getpixel((w, h))
#此处余3,依次从R、G、B三个颜色通道获得最低位的隐藏信息
if count%3==0:
count+=1
b=b+str((mod(int(pixel[0]),2)))
if count ==lenth:
break
if count%3==1:
count+=1
b=b+str((mod(int(pixel[1]),2)))
if count ==lenth:
break
if count%3==2:
count+=1
b=b+str((mod(int(pixel[2]),2)))
if count ==lenth:
break
if count == lenth:
break
# 提取隐藏信息
c=''
for i in range(0,len(b),8):
#以每8位为一组二进制,转换为十进制
stra = toasc(b[i:i+8])
#将转换后的十进制数视为ascii码,再转换为字符串写入到文件中
#print((stra))
c+=chr(stra)
# 写入指定文件
with open(str2,"a",encoding='utf-8') as f:
f.write(aesecb(c))
f.close()
def main():
#文件长度
le = 24
#含有隐藏信息的图片
for i in range(1,167):
new = "new_"+str(i)+".png"
#信息提取出后所存放的文件
get_info = "flag.txt"
func(le,new,get_info)
print("完成信息提取!")
if __name__=='__main__':
main()
多次base64解密得到flag,提交
0x17 喵~
使用工具zsteg查看发现,b1,bgr,lsb,xy有数据,发现是一张PNG图片,导出
使用:zsteg -E b1,bgr,lsb,xy mmm.png > 1.png 然后在用foremost提取一下,才能得到一半的图片
改一下高度,扫码得到一个网盘地址下载flag.rar,解压,
结果就在这里了我以为这里没有东西了,我看有个MPEG ASTS,AAC 猜测是个音频文件,到处然后就是各种尝试都没有想要的东西,看了wp才知道rar藏了东西,还必须得用WinRAR解压才能得到flag.pyc文件
通过在线反编译网站:https://tool.lu/pyc/ 得到代码
运行得到flag
#Author: mochu7
def decode(arg1):
ciphertext = arg1[::-1]
flag = ''
for i in range(len(ciphertext)):
if i % 2 == 0:
s = int(ciphertext[i]) - 10
else:
s = int(ciphertext[i]) + 10
s = s ^ i
flag += chr(s)
print(flag)
if __name__ == '__main__':
ciphertext = [
'96',
'65',
'93',
'123',
'91',
'97',
'22',
'93',
'70',
'102',
'94',
'132',
'46',
'112',
'64',
'97',
'88',
'80',
'82',
'137',
'90',
'109',
'99',
'112']
decode(ciphertext)
0x18 EzMisc
不知道是什么数据丢到CyberChef走一遍发现是base64,是个zip文件,
找了个在线网站导出,结果导出的是16进制还得,010新建文件,编辑-粘贴为16进制在保存为zip即可得到压缩包
解压得到
压缩包有密码要找密码,发现rabbit.jpg里面有加密字符串,应该是rabbit加密
011 001 011 101 010
111 111 101 010 101 我属实不知道这是个什么玩意,看了wp才知道科比加密(6的)
111 111 111 101 010 对着得到rabbit解密密钥:AHOKB
5b+r5Y675ZaC6aWx5bCP5YWU5Yeg5oqK77yB base64解码得到 快去喂饱小兔几把!
解密得到C代码,搜key 得到keykeykeykeykeykeykey
结果不对看i’m hint 栅栏跑了一下,提示key的长度为23
跑一下得到解压密码,
到这很迷奥,解压得到的key.bmp啥东西没有,又去瞅了一眼wp
把key.zip下面这一堆取出来,然后进行首尾逆序
逆序代码
input = open('key.rar', 'rb')
input_all = input.read()
ss = input_all[::-1]
output = open('flag.rar', 'wb')
output.write(ss)
input.close()
output.close()
然后改一下文件头就可以解压了
得到flag.bmp,看wp看不懂,直接找脚本爆破
import os
import time
import math
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("-f", type=str, default=None, required=True,
help="输入同级目录下图片的名称")
args = parser.parse_args()
SAVE_DIR = os.getcwd()
def save_img(data, width=None, height=None, sqrt_num=None):
with open(os.path.join(SAVE_DIR, "fix_width.bmp"), "wb") as f:
f.write(data[:0x12] + width.to_bytes(4,
byteorder="little", signed=False) + data[0x16:])
with open(os.path.join(SAVE_DIR, "fix_height.bmp"), "wb") as f:
f.write(data[:0x16] + height.to_bytes(4,
byteorder="little", signed=False) + data[0x1a:])
with open(os.path.join(SAVE_DIR, "fix_sqrt.bmp"), "wb") as f:
f.write(data[:0x12] + sqrt_num.to_bytes(4,
byteorder="little", signed=False) * 2 + data[0x1a:])
def get_pixels_size(data):
bfSize = int.from_bytes(data[0x2:0x2+4], byteorder="little", signed=False)
bfOffBits = int.from_bytes(
data[0xa:0xa+4], byteorder="little", signed=False)
biBitCount = int.from_bytes(
data[0x1c:0x1c+2], byteorder="little", signed=False)
channel = biBitCount // 8
# 由于宽高都会被修改,所以我计算出来的Padding_size也不是正确的,没有意义
# padding_size = (4 - col * channel % 4) * row if col * channel % 4 != 0 else 0
# pixels_size = (bfSize - bfOffBits - padding_size) // channel
return (bfSize - bfOffBits) // channel
if __name__ == '__main__':
file_path = os.path.abspath(args.f)
if os.path.splitext(args.f)[-1] != ".bmp":
print("您的文件后缀名不为BMP!")
time.sleep(1)
exit(-1)
with open(file_path, "rb") as f:
data = f.read()
col = abs(int.from_bytes(data[0x12:0x12+4],
byteorder="little", signed=True))
row = abs(int.from_bytes(data[0x16:0x16+4],
byteorder="little", signed=True))
pixels_size = get_pixels_size(data)
width, height = pixels_size // row, pixels_size // col
sqrt_num = int(math.sqrt((pixels_size)))
save_img(data, width=width, height=height, sqrt_num=sqrt_num)
print("温馨提示:由于填充字节的问题,所以可能会偏差几个像素!")
print(f"1.修复宽度: {width}")
print(f"2.修复高度: {height}")
print(f"3.修复宽度高度为: {sqrt_num}")
time.sleep(1)
然后将得到的图片放到stegsolve里切换一下图层,就可以扫描得到flag了
0x19 geek_challenge
这题不会,一直让我算数,怎么输都说我输了,服了
看了wp都是直接上脚本一直跑,等程序报错flag就出来了
import pwn
io = pwn.remote("challenge.qsnctf.com", 10074)
while True:
rec = io.recvline()
print(rec.decode())
if b"= ?" in rec:
answer = eval(rec.decode()[:-5])
data = str(answer).encode()
io.sendline(data)
0x20 Mosaic
我是菜鸡,找了好多大佬的脚本,找到个这个然后修改一下尺寸就能出扫码拿flag了
from PIL import Image
import math
BOX_Y,BOX_X = 95,131
BOX_SIZE = 18
BOX_N = 21
QR_N = 57
QR_SIZE = 10
with Image.open("./mosaic.bmp") as im:
mosaic=[[im.getpixel((BOX_X+x*BOX_SIZE,BOX_Y+y*BOX_SIZE)) for x in range(BOX_N)] for y in range(BOX_N)]
qrcode=[[-1 for _ in range(QR_N)] for _ in range(QR_N)]
# 读取未打码部分
for x in range(500):
for y in range(500):
if not ((BOX_X <= x < BOX_X+BOX_SIZE*BOX_N) and (BOX_Y <= y < BOX_Y+BOX_SIZE*BOX_N)):
qrcode[y//QR_SIZE][x//QR_SIZE]=im.getpixel((x,y))
# 二维码格式要求的部分
for sx,sy in [(28,28),(28,50),(50,28),(50,50)]:
for i in range(-2,3):
for j in range(-2,3):
if (i==2) or (i==-2) or (j==2) or (j==-2):
qrcode[sy+j][sx+i]=0
# 对每一个马赛克像素找出所有可能的原始二维码像素组合
selection=[]
for xi in range(BOX_N):
for yj in range(BOX_N):
# 找出对这个马赛克像素有贡献的原始二维码像素
content={}
for i in range(BOX_SIZE):
for j in range(BOX_SIZE):
x=BOX_X+BOX_SIZE*xi+i
y=BOX_Y+BOX_SIZE*yj+j
qrx=x//QR_SIZE
qry=y//QR_SIZE
if not ((qrx,qry) in content):
content[(qrx,qry)]=0
content[(qrx,qry)]+=1
source = [*content.keys()]
known = [qrcode[y][x] for x,y in source]
guess = [[value] if value>=0 else [0,255] for value in known]
guessId = [0 for _ in guess]
possibles = []
# 枚举所有可能性,找出所有可能正确的可能性
while True:
sum = 0
for i in range(len(guessId)):
sum += content[source[i]]*guess[i][guessId[i]]
mean = math.floor(sum/(BOX_SIZE**2))
if(mosaic[yj][xi]==mean):
possible =[(source[i],guess[i][guessId[i]]) for i in range(len(guessId))]
print(possible)
possibles.append(possible)
has_next = False
for i in range(len(guessId)):
if guessId[i]+1<len(guess[i]):
has_next = True
guessId[i]+=1
for j in range(i):
guessId[j]=0
break
if not has_next:
break
selection.append(possibles)
# 找出可以完全确定原始内容的马赛克像素,并以此排除一些其他马赛克像素的某些可能性
# 重复执行,直到无法进一步确认
while True:
confirmed=[*filter(lambda x:len(x)==1,selection)]
unconfirmed=[*filter(lambda x:len(x)!=1,selection)]
if len(confirmed)==0:
break
new_cells={}
for possibles in confirmed:
possible=possibles[0]
for p,v in possible:
x,y=p
if qrcode[y][x]<0:
new_cells[p]=v
qrcode[y][x]=v
print(new_cells)
selection=[*map(lambda ps:[*filter(lambda p:all(map(lambda ptv:(qrcode[ptv[0][1]][ptv[0][0]] < 0) or (qrcode[ptv[0][1]][ptv[0][0]] == ptv[1]),p)),ps)],unconfirmed)]
# 在图片上填上所有能确定内容的的像素
for x in range(500):
for y in range(627):
if ((BOX_X <= x < BOX_X+BOX_SIZE*BOX_N) and (BOX_Y <= y < BOX_Y+BOX_SIZE*BOX_N)):
v=qrcode[y//QR_SIZE][x//QR_SIZE]
if v>=0:
im.putpixel((x,y),v)
im.save('unmosaic.bmp')