本文主要是介绍2023年磐石行动第十六周,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
1、冰冰给我flag可以吗
题目内容:
png文件解密,flag用DASCTF包裹
题目下载之后发现pypy.exe和一个无法显示的图片,根据题目的描述,应该是图片被这个程序加密了,需要解密才能得到正确的图片:
通过pyinsxtractor.py将exe程序解包,发现使用python3.7(满足<3.9的条件),直接使用
uncompyle6 pypy.PYC > pypy.py
得到加密程序的源码
# uncompyle6 version 3.9.0
# Python bytecode version base 3.7.0 (3394)
# Decompiled from: Python 3.9.13 (tags/v3.9.13:6de2ca5, May 17 2022, 16:36:42) [MSC v.1929 64 bit (AMD64)]
# Embedded file name: pypy.py
import base58def enc(stream, file):text = base58.b58encode(stream) #base58编码temp = list(bytes.decode(text))return tempif __name__ == '__main__':fp = open('冰冰给我flag可以吗.png', 'rb')context = fp.read()key = context[0] #文件第一个字节 0x89fp.close()fp = open('冰冰给我flag可以吗.png', 'wb')tmp = enc(context, fp) #enc编码for i in range(len(tmp)):tmp[i] = chr(ord(tmp[i]) ^ key) #异或keyfp.write(bytes((''.join(tmp)), encoding='utf-8'))fp.close()
# okay decompiling .\pypy.pyc
加密过程就是base58编码+异或0x89,编写exp如下:
import base58
import timedef main():print('begin')begin_time = time.time()#读入图片with open('0.png','rb') as f:datas = f.read()datas = list(bytes.decode(datas)) #字节转字符listkey = 0x89#存储png_datapng_data = ''for data in datas:png_data += chr(ord(data)^key) #获得异或之后的png数据#base58解码png_data = base58.b58decode(png_data)#写入图片with open('flag.png','wb') as f:f.write(png_data)print('end')print('used time is %.2fs'%(time.time()-begin_time))if __name__ == '__main__':main()#begin
#end
#used time is 9.11s
得到flag图片如下:
图片中flag如下:
DASCTF{S@Y_nO_13u7_tH3_6odY_!s_H0Ne~T}
但是这个题目flag错了,需要提交,将6odY
修改为6ody
DASCTF{S@Y_nO_13u7_tH3_6ody_!s_H0Ne~T}
2、Yusa的密码学课堂——密码分析
题目描述
这节课老师给Yusa讲述了一个黄道十二宫杀手的故事。。。
题目下载之后得到task.py
import random
from secret import flag,tableone = []
zero = []
for each in table:if round(random.random()):one.append(each)else:zero.append(each)
output=""
for each in flag:each = bin(ord(each))[2:].rjust(8,'0')for i in each:if i == '1':output += random.choice(one)if i == '0':output += random.choice(zero)
print(output)'''
♥•∧∨∨◦∧Δ∨♠∧⇑⇐⇑♥∞∨ℵ⇐•∧6◦♣⇑⊗⊕∧⇐∧ℵ⇒Δ•⊕ℵ6♠⊕∧∨ΩΔΔ⊕ℵ⊗♥∨Ω◦♠⊗♥⊗ℵ8♣•∧⊕8∧⊗⊕⇑⊗◦∧⊕◦∞Δ∨ℵ⊗∧∧∧Δ∧⇓⇒⇑⊕♦♣8⊕∞Θ⊕⊕⇐∞∧⊕♦∇∞ℵ6⊕♦♦Δ♠♣∨⊕∞∧∨⊕◦ΩΩΔ♦⇑6⇐ℵ∞∨8⇐♠6⇐◦∞⇐⊕Δ∇8•◦∧∧♥⇓Θ♥♠∞ΔΔ◦⇑8∨⊕⊗◦♥♦∧⇒♦♦♣♠8∞ℵ8♦∨••∨∧♣⇐⇑6Θ⇓∧Θ⇐♦8∨⊗∞⇑∧⊗•♦∨∇⇒∧⊗⇐⊕8⇓♠⇑∨••8♥⊕Ω•⇐⇒◦♠⇐♦♠∞⇓⇑⇐⇐6∨◦Θ6♠∇ℵ♦♥◦•∇⇑⇐♣⊕8ℵΘ⇑⇒•♥∧◦∞∨∨♦⊗⇒8♥Θ♣⇑∞∨♦⇑◦♠⇑♥♥♠Δ8Δ⇒⇒Δ6♣⇒♦∇ΘΔ8♣♦⊕⇑♠Θ♥⇐8Δ•∧ℵ•68∧ΩΘ∨∞♣♦∨⇓6•Δ⊗♠♣⇓ℵ♥∞
'''
这个题目初始看着特别唬人,加密原理
1、将table的字符通过round(计算小数四舍五入情况)添加到one和zero中
2、接着将flag中的字符转为二进制,如果不足8位,在高位补0
3、根据字符二进制0和1情况将one和zero中的字符随机输出
从上述分析发现存在两次随机,感觉特别有难度,但是仔细思考就会发现,其实第二个随机其实没啥用,只要知道one和zero,判断输出的字符是在one中,那么那一位就是1,如果字符在zero中,那一位就是0,具体输出那个字符不需要关心,接着就发现table无法知道,随机数也没有办法预测啊,接着分析就会发现一个隐藏的条件,flag应该是可见字符,那么ascii范围<127,那么flag的最高位一定是0,我们通过这个条件知道一部分zero或者全部zero,接着判断output是不是在zero判断当前位是1还是0,接着编写exp如下:
#encoding=utf-8output = '♥•∧∨∨◦∧Δ∨♠∧⇑⇐⇑♥∞∨ℵ⇐•∧6◦♣⇑⊗⊕∧⇐∧ℵ⇒Δ•⊕ℵ6♠⊕∧∨ΩΔΔ⊕ℵ⊗♥∨Ω◦♠⊗♥⊗ℵ8♣•∧⊕8∧⊗⊕⇑⊗◦∧⊕◦∞Δ∨ℵ⊗∧∧∧Δ∧⇓⇒⇑⊕♦♣8⊕∞Θ⊕⊕⇐∞∧⊕♦∇∞ℵ6⊕♦♦Δ♠♣∨⊕∞∧∨⊕◦ΩΩΔ♦⇑6⇐ℵ∞∨8⇐♠6⇐◦∞⇐⊕Δ∇8•◦∧∧♥⇓Θ♥♠∞ΔΔ◦⇑8∨⊕⊗◦♥♦∧⇒♦♦♣♠8∞ℵ8♦∨••∨∧♣⇐⇑6Θ⇓∧Θ⇐♦8∨⊗∞⇑∧⊗•♦∨∇⇒∧⊗⇐⊕8⇓♠⇑∨••8♥⊕Ω•⇐⇒◦♠⇐♦♠∞⇓⇑⇐⇐6∨◦Θ6♠∇ℵ♦♥◦•∇⇑⇐♣⊕8ℵΘ⇑⇒•♥∧◦∞∨∨♦⊗⇒8♥Θ♣⇑∞∨♦⇑◦♠⇑♥♥♠Δ8Δ⇒⇒Δ6♣⇒♦∇ΘΔ8♣♦⊕⇑♠Θ♥⇐8Δ•∧ℵ•68∧ΩΘ∨∞♣♦∨⇓6•Δ⊗♠♣⇓ℵ♥∞'#构造zero字典
zero = []
for i in range(0,len(output),8):if output[i] not in zero:zero.append(output[i])#通过判断当前位置0和1构造二进制flag字符串
flag = ''
for i in range(len(output)):if output[i] in zero:flag += '0'else:flag += '1'#二进制转字符串
for i in range(0,len(flag),8):print(chr(int(flag[i:i+8],2)),end='')
#DASCTF{a30bb82811cd162434f78796c4b3dace}
得到flag如下:
DASCTF{a30bb82811cd162434f78796c4b3dace}
这篇关于2023年磐石行动第十六周的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!