CTF-DAY8
[LitCTF 2023]babyLCG
题目:
from Crypto.Util.number import *
from secret import flagm = bytes_to_long(flag)
bit_len = m.bit_length()
a = getPrime(bit_len)
b = getPrime(bit_len)
p = getPrime(bit_len+1)seed = m
result = []
for i in range(10):seed = (a*seed+b)%presult.append(seed)
print(result)
"""
result = [699175025435513913222265085178805479192132631113784770123757454808149151697608216361550466652878, 193316257467202036043918706856603526262215679149886976392930192639917920593706895122296071643390, 1624937780477561769577140419364339298985292198464188802403816662221142156714021229977403603922943, 659236391930254891621938248429619132720452597526316230221895367798170380093631947248925278766506, 111407194162820942281872438978366964960570302720229611594374532025973998885554449685055172110829, 1415787594624585063605356859393351333923892058922987749824214311091742328340293435914830175796909, 655057648553921580727111809001898496375489870757705297406250204329094679858718932270475755075698, 1683427135823894785654993254138434580152093609545092045940376086714124324274044014654085676620851, 492953986125248558013838257810313149490245209968714980288031443714890115686764222999717055064509, 70048773361068060773257074705619791938224397526269544533030294499007242937089146507674570192265]
"""
分析:
M i = ( a ∗ M i − 1 + b ) % p M_i= (a*M_{i-1}+b) \%p Mi=(a∗Mi−1+b)%p
循环了10次,需要还原M0
直接套用板子,板子链接https://www.cnblogs.com/mumuhhh/articles/17402635.html
解出:LitCTF{31fcd7832029a87f6c9f760fcf297b2f}
[安洵杯 2020]easyaes
题目:
#!/usr/bin/python
from Crypto.Cipher import AES
import binascii
from Crypto.Util.number import bytes_to_long
from flag import flag
from key import keyiv = flag.strip(b'd0g3{').strip(b'}')LENGTH = len(key)
assert LENGTH == 16hint = os.urandom(4) * 8
print(bytes_to_long(hint)^bytes_to_long(key))msg = b'Welcome to this competition, I hope you can have fun today!!!!!!'def encrypto(message):aes = AES.new(key,AES.MODE_CBC,iv)return aes.encrypt(message)print(binascii.hexlify(encrypto(msg))[-32:])'''
56631233292325412205528754798133970783633216936302049893130220461139160682777
b'3c976c92aff4095a23e885b195077b66'
'''
分析:
- 还原key
因为hint由重复八次的4个字节组成,key有15字节,所以异或后会有一部分hint保留,将hint转换为字符串,可以看到有部分重复的字节
hint_key = 56631233292325412205528754798133970783633216936302049893130220461139160682777
print(long_to_bytes(hint_key))
#b'}4$d}4$d}4$d}4$d\x19\x04CW\x06CA\x08\x1e[I\x01\x04[Q\x19'hint = '}4$d'
有hint后可直接异或还原出key。
- CBC解密
题目使用CBC加密:
def encrypto(message):aes = AES.new(key,AES.MODE_CBC,iv)return aes.encrypt(message)
CBC加密:将明文按照16个字节的长度进行分组,每组明文块与前一个密文组xor后再进行ECB的加密模式。
len(binascii.unhexlify(enc))发现长度为16 刚好128bit 所以给出的是最后一个密文块
import binascii
from Crypto.Cipher import AES
from pwn import xor
import libnum
from Crypto.Util.number import *enc = b'3c976c92aff4095a23e885b195077b66'
enc = binascii.unhexlify(enc)key = b'd0g3{welcomeyou}'
msg = b'Welcome to this competition, I hope you can have fun today!!!!!!'
msg = [msg[i:i+16] for i in range(0,len(msg),16)]#分块def decrypt(msg):ebc = AES.new(key,AES.MODE_ECB)return ebc.decrypt(msg)c3 = xor(decrypt(enc),msg[3])
c2 = xor(decrypt(c3),msg[2])
c1 = xor(decrypt(c2),msg[1])
c0 = xor(decrypt(c1),msg[0])
iv = c0
print(b'd0g3{'+iv+b'}')
解出b’d0g3{aEs_1s_SO0o_e4sY}’
参考https://www.cnblogs.com/NozoMizo/articles/17825928.html
朋友给的题,不知道哪翻的
题目:
from Crypto.Util.number import bytes_to_long
import randomflag = b"flag{uuid}"
btl = str(bytes_to_long(flag))
lowercase = '0123456789'
uppercase = '2***7****0'
table = ''.maketrans(lowercase, uppercase)
new_flag = btl.translate(table)
n = 2 ** 512
m = random.randint(2, n - 1) | 1
c = pow(m, int(new_flag), n)
print('m = ' + str(m))
print('c = ' + str(c))
# m = 3097502164103987164323080671192386511065857410221288153061140622970224914473224807053016180200525552838404973541878618391348653867355109392070344210878871
# c = 7575520525465161327133831389027121519268752255113564686585808502942641702897542584106400374391419523883832010238676747853882832409855139906428435538853383
分析
table = ‘’.maketrans(lowercase, uppercase) #生成将lowercase替换为uppercase的替换表
new_flag = btl.translate(table) #对bt1进行字符替换
m = random.randint(2, n - 1) | 1#通过| 1确保它是奇数(因为任何数字与1进行按位或操作都会确保其最后一位为1
解密
已知m,c,n求e,离散对数问题,在Sage中求解
得到替换后的字符串为95225608106780286174533253225403741535234459109003153780283169100088225690381088627758919156459056579
然后再爆破替换表还原flag
from Crypto.Util.number import long_to_bytes
import itertoolsnew_flag = "95225608106780286174533253225403741535234459109003153780283169100088225690381088627758919156459056579"
lowercase = '0123456789'# 已知uppercase的格式为'2***7****0',其中*代表未知数字
# 生成所有可能的uppercase组合
unknown_positions = [1, 2, 3, 5, 6, 7, 8] # 这些位置的字符未知(索引从0开始)
known_chars = ['2', '', '', '', '7', '', '', '', '', '0'] # 已知字符的位置# 填充未知位置
unknown_positions = [1, 2, 3, 5, 6, 7, 8] # 7 个未知位置
for digits in itertools.product('0123456789', repeat=7):uppercase = [''] * 10uppercase[0] = '2'uppercase[4] = '7'uppercase[9] = '0'for i, pos in enumerate(unknown_positions):uppercase[pos] = digits[i]uppercase_str = ''.join(uppercase)# 其余代码不变# 创建替换表(反向,因为我们要从new_flag还原到btl)reverse_table = str.maketrans(uppercase_str, lowercase)try:# 尝试反向替换btl_str = new_flag.translate(reverse_table)btl = int(btl_str)# 转换为bytesflag_bytes = long_to_bytes(btl)# 检查是否符合flag格式if b'flag{' in flag_bytes:print(uppercase_str)print(flag_bytes)except (ValueError, UnicodeDecodeError):# 转换失败,跳过continue
爆破成功
当替换表为2486795130,得到flag{de16c7ab-9bac-449e-b105-0be75e7a136e}