--Misc
---ai和nia的交响曲
---EZ_misc
---Matryoshka
---程序猿Quby的附件
---GIFuck
---Easy_VMDK
---两只老虎
Misc
ai和nia的交响曲
打开直接导出http流
145kb的upload.php查看一下是一个hex,cyberchef转一下得到一张图片
发现每条黑线中间一共7个黑or白像素,猜测7bit,把黑色当0那么就是正常的8bit
用QQ的截图看了一下中间的黑线也不是(0,0,0),因此这里使用一个范围代表黑色和白色,我这里把小于30的当成黑色
from PIL import Image
img = Image.open("flag1.png")
w,h = img.size
flag = ''
for i in range(w):
for j in range(h):
pixel = img.getpixel((i,j))[0]
if(pixel < 30):
flag += '0'
else:
flag += '1'
f = open('outs.txt','w').write(flag)
cyberchef转一下,在结果的尾部得到hint和part1
http导出的flag2是伪加密,把09改00
结合hint是b站视频,每一行看成该视频的时间
但是不得不说,00:03是C我不是很理解(在晚上的时候上了hint说要加一秒嘻嘻),最后测试下来是CAOCAOGAIFAN
最后得到flag
@i_n1a_l0v3S_CAOCAOGAIFAN
EZ_misc
发现有两个IEND,并且中途就提前IEND掉了,但是查看发现只有一个PNG
联想到之前*CTF做到的snipping的CVE
但是使用之前github上的Acropalypsa Multi Tool没有成功,看了一下powershell发现是图片高度错了导致无法加载。
通过CRC计算得到实际高度是138,再放进工具即可
Matryoshka
解压出来一个flag.img,使用winhex打开查看,能拿到三个文件。
normal_rar.rar not_real_cat.jpg encrypt
其中发现normal_rar尾部有个jpg,分离后发现与not_real_cat是一个图片,猜测双图隐写,直接xor发现有蓝色的线条,直接锁定盲水印,使用bwmforpy3的版本
python3 .bwmforpy3.py decode .not_real_cat.jpg .normal_rar.jpg out.png --oldseed --alpha 10
得到密码(注意第一个w小写)watermark_is_fun
查看encrypt文件,发现都是混乱字节且正好大小是整数20mb,直接根据该信息锁定是veracrypt(或truecrypt),使用veracrypt挂载即可得到flag.txt
flag.txt发现长度只有70多但是却占了100多字节,猜测存在0宽。
解base32后发现不是直接DASCTF,猜测需要维吉尼亚,最后得到flag
DASCTF{congratulati0n_you_f1nd_th3_f14g!!!}
程序猿Quby的附件
解压发现图片后面有个rar文件,分离出来发现该rar文件需要密码
图片查看最低位发现有LSB,直接查RGB0没有信息,说明是有密码,猜测cloacked-pixel
图片本身是夏多密码,根据规则转换得到HAVEANICEDAY
cloacked-pixel> python '.lsb.py' extract .QUBY.png xixixi.txt HAVEANICEDAY
得到rar密码we1c0met0ycbCTF!!!
然后随便查看一个excel,能够发现中间(50多~1000多行)的部分被收起来了,展开再改颜色能看到两种不同的数字
另一个文件是3.33和6.66就不截图了
猜测画图,丢给GPT4(这是3.33和6.66的图)
将两张图拼起来的结果如下:
密码w0wyoudo4goodj0b
既然有密码,猜测wav隐写,发现deepsound有密码
extract出来,解压,得到两个txt文件
:JOJ[=%tJD9gr2Q79*;T:-qZD=]S0c:0'nT7orYd9L_TD=Ys#Z9iY:q;-$Xo:dQs>9ia&M9i3]K5r2G>8Oc'9=%u:f8QIW;;bp(8Ms%=10QJ$:KBnd<AmK;7p.T97oN8J
其中这个丢cyberchef直接base85再32能够得到一串base64
另一个文件也是base64,猜测为换表base
DASCTF{Qu6y_d0_not_lik3_w0rking_4t_all}
GIFuck
最后写出汇总的脚本,GPT参与了part2和part3
首先发现题目是给了一张GIF图片,分出来之后发现是brainfuck的图,写脚本提取能够得到一堆符合brainfuck的字符。但是直接放brainfuck编译器中使用debug查看时,发现在开头存在栈内值为0的时候仍然在减1(即存在下溢),但是在某些工具中并不会出现停止(因为这些工具会%256),但是在有些工具中就会直接停止。因此能猜测栈内可能存在信息,直接查看栈内发现基本都是0。因此猜测gif图片还有其他信息。
接着查看gif发现每一帧的帧时长有所不同。写脚本print之后发现均为60的倍数,猜测每个字符需要*(x//60),因此写出以下脚本
'''part1:get brainfuck'''
from PIL import Image
flag = []
for i in range(1099):
pic = Image.open(f'Frame{i}.png')
JIA = pic.getpixel((34,23))[0]
zkuo = pic.getpixel((30,4))[0]
jian = pic.getpixel((23,24))[0]
da = pic.getpixel((16,35))[0]
xiao = pic.getpixel((31,36))[0]
ykuo = pic.getpixel((18,47))[0]
dian = pic.getpixel((19,38))[0]
if (JIA == 0):
flag.append('+')
elif (zkuo == 0):
flag.append('[')
elif (jian == 0):
flag.append('-')
elif (da == 0):
flag.append('>')
elif (xiao == 0):
flag.append('<')
elif (ykuo == 0):
flag.append(']')
elif (dian == 0):
flag.append('.')
else:
flag.append('?')
print(flag,len(flag))
'''part2:'''
from PIL import Image
def extract_frame_durations(gif_path):
# Open the GIF file
gif = Image.open(gif_path)
# Extract frame durations
frame_durations = []
while True:
frame_durations.append(gif.info.get('duration', 0)//60) # Some GIFs might not have a 'duration' field for each frame
try:
gif.seek(gif.tell() + 1)
except EOFError:
break # No more frames
return frame_durations
gif_path = "flag.gif" # Replace with the path to your GIF file
durations = extract_frame_durations(gif_path)
print("Frame Durations:", durations,len(durations))
for i in range(len(durations)):
flag[i] = flag[i]*durations[i]
print(''.join(flag))
brainfuck_code = ''.join(flag)
'''part3'''
#
pointer = 0
tape = [0] * 30000 # Initialize a tape with 30000 cells, all set to 0
code_pointer = 0
# Loop variables
bracket_map = {}
stack = []
output = []
# Map brackets for quick jumps
for i, command in enumerate(brainfuck_code):
if command == '[':
stack.append(i)
elif command == ']':
start = stack.pop()
bracket_map[start] = i
bracket_map[i] = start
# Start interpreting the Brainfuck code
f = open('brainfuck.txt','a')
while code_pointer < len(brainfuck_code):
command = brainfuck_code[code_pointer]
if command == '>':
pointer += 1
elif command == '<':
pointer -= 1
elif command == '+':
tape[pointer] = (tape[pointer] + 1) % 256
elif command == '-':
tape[pointer] = (tape[pointer] - 1) % 256
elif command == '.':
output.append(tape[pointer])
f.write(f'output:{tape[pointer]}')
elif command == ',':
raise NotImplementedError("Input command ',' is not supported.")
elif command == '[':
if tape[pointer] == 0:
code_pointer = bracket_map[code_pointer]
elif command == ']':
if tape[pointer] != 0:
code_pointer = bracket_map[code_pointer]
# Move to the next command
code_pointer += 1
# Print the state for debugging
# f.write(f"Command: {command}, Pointer: {pointer}, Tape: {tape[:100]}, Code Pointer: {code_pointer}n")
# Return the tape and output
print(''.join(str(output)),tape[:100])
得到的结果如下:
[83, 111, 114, 114, 121, 32, 98, 117, 116, 32, 121, 111, 117, 114, 32, 102, 108, 97, 103, 32, 105, 115, 32, 110, 111, 116, 32, 104, 101, 114, 101, 46] [68, 65, 83, 67, 84, 70, 123, 80, 101, 110, 95, 80, 105, 110, 101, 97, 112, 112, 108, 101, 95, 65, 112, 112, 108, 101, 95, 80, 101, 110, 125, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
第一个数组是直接输出的内容,为Sorry but your flag is not here.
第二个数组是栈内未打印的数据,为DASCTF{Pen_Pineapple_Apple_Pen}
栈内未打印信息即是需要找到的flag
Easy_VMDK
尝试明文爆破,明文只需要满足8字节连续,一共12字节已知即可,查看自己有的vmdk文件,发现一共可知12字节:4B 44 4D 56 01 00 00 00 03 00 00 00
把上面12字节写入key.txt
使用bkcrack爆破:.bkcrack.exe -C .Easy_VMDK.zip -c flag.vmdk -p .key.txt
得到key e6a73d9f 21ccfdbc f3e0c61c
解密得到vmdk文件。使用winhex发现一共有两个文件
提取出来,发现flag.zip后面还有一个zip文件,手动分离得到key.txt加密过程:
import cv2
import base64
import binascii
img = cv2.imread("key.png")
r, c = img.shape[:2]
print(r, c)
# 137 2494
with open("key.txt", "w") as f:
for y in range(r):
for x in range(c):
uu_byte = binascii.a2b_uu(', '.join(map(lambda x: str(x), img[y, x])) + "n")
f.write(base64.b64encode(uu_byte).decode() + "n")
直接丢给GPT得到GPT逆向的内容
#Create by GPT
# Initialize an empty list to store the pixel values
decoded_img_data = []
# Read the key.txt file
with open("/mnt/data/key.txt", "r") as f:
lines = f.readlines()
# Loop through each line to decode the pixel values
for line in lines:
try:
# Decode from Base64 to uu-encoded bytes
uu_byte = base64.b64decode(line.strip())
# Decode from uu-encoded bytes to original string
decoded_byte = binascii.b2a_uu(uu_byte)
# Convert the comma-separated string back to a list of integers (RGB values)
pixel_values = list(map(int, decoded_byte.decode().strip().split(", ")))
# Append to the image data list
decoded_img_data.append(pixel_values)
except Exception as e:
print(f"An error occurred: {e}")
# Convert the list to a NumPy array and reshape to the original image dimensions
decoded_img_data = np.array(decoded_img_data, dtype=np.uint8)
decoded_img_data = decoded_img_data.reshape((137, 2494, 3)) # Based on the original image dimensions
# Save the decoded image
decoded_img_path = "/mnt/data/decoded_key.png"
cv2.imwrite(decoded_img_path, decoded_img_data)
decoded_img_path
得到压缩包的密码HELLO_DASCTF2023_WORLD
解压得到flag:DASCTF{2431a606-00a3-4698-8b0f-eb806a7bb1be}
两只老虎
解压后得到一张图片,但是发现这张图片后面IDAT大小突然变了
这里就猜测第chunk[21]是否即这张正常PNG图片的末尾,而再后面部分为多余部分。
接着在chunk[22]发现新的0x789c字节(即满足zlib)
因此合理猜测第一个84EE后面就应该是IEND,尝试删掉chunk[22]与后面的IDAT块,发现对原图并没有影响,因此前面猜测很可能是正确的。
那么删掉chunk[1]~chunk[22]。发现图片有点抽象,猜测高宽不对,先爆破宽度
爆破一下宽度
f = open("2.png",'rb').read()
for i in range(1800):
fw = open(f'./out/{i}.png','wb')
data = b''
data += f[:16]
w = i.to_bytes(4, 'big')
data += w
data += f[20:]
fw.write(data)
发现第二张png图片比第一张的宽度多了10,并且两图做xor发现有部分位置不同
发现很多行都有不一样的内容,但是由于不是蓝色的线因此排除盲水印,这里看看每行的颜色和个数
from PIL import Image
img = Image.open('solved.bmp')
w,h = img.size
count = []
for i in range(h):
tmp = 0
for j in range(w):
pixel = img.getpixel((j,i))
if(pixel != (0,0,0)):
tmp += 1
if(tmp!=10):
count.append(tmp-10)
print(count)
[68, 65, 83, 67, 84, 70, 123, 116, 87, 111, 95, 116, 49, 103, 101, 114, 115, 95, 114, 85, 110, 95, 102, 64, 115, 116, 125]
原文始发于微信公众号(n03tAck):2023年“羊城杯”网络安全大赛 MISC WriteUp
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论