2020五月赛DASCTF

bbcrypto

# -*- coding:utf-8 -*-
import A,SALT
from itertools import *

def encrypt(m, a, si):
    c=""
    for i in range(len(m)):
        c+=hex(((ord(m[i])) * a + ord(next(si))) % 128)[2:].zfill(2)
    return c
if __name__ == "__main__":
    m = 'flag{********************************}'
    a = A
    salt = SALT
    assert(len(salt)==3)
    assert(salt.isalpha())
    si = cycle(salt.lower())
    print("鏄庢枃鍐呭涓猴細")
    print(m)
    print("鍔犲瘑鍚庣殑瀵嗘枃涓猴細")
    c=encrypt(m, a, si)
    print(c)
    #鍔犲瘑鍚庣殑瀵嗘枃涓猴細
    #177401504b0125272c122743171e2c250a602e3a7c206e014a012703273a3c0160173a73753d

一开始真的没看懂这是什么加密,复现题目时发现与仿射加密很像,还是自己太菜了
这里就是 c = ax + salt (mod 128) ,而salt是有周期的,flag的格式我们是知道的,于是可以先根据 ‘f’,'g’来求出a和salt的前一位,就是简单的解方程,随便写出几行代码解出 a = 57

flag = 0
for i in range(128):
	for j in range(128):
		m = (102 * i + j)%128
		n = (103 * i + j)%128
		if m == 23 and n == 80:
			flag = 1
			print(i,j)
			break
	if flag == 1:
		break

再根据解出的a,用 ‘l’,'a’去解出salt的剩下两位,求出salt = ‘ahh’,接下来进行解码
flag = a-1(c - salt) mod 128

from Crypto.Util.number import *
import gmpy2

c = "177401504b0125272c122743171e2c250a602e3a7c206e014a012703273a3c0160173a73753d".decode('hex')
a = 57
salt = 'ahh'
flag = ''
n = 0
for i in c:
	b = ord(salt[n%3])
	n += 1
	flag += chr(gmpy2.invert(a,128)*(ord(i) - b) % 128)
print flag

在这里插入图片描述

easyLCG

from Crypto.Util.number import*
from secret import flag

class LCG:
    def __init__(self):
        self.a = getRandomNBitInteger(32)
        self.b = getRandomNBitInteger(32)
        self.m = getPrime(32)
        self.seed = getRandomNBitInteger(32)

    def next(self):
        self.seed = (self.a*self.seed+self.b) % self.m
        return self.seed >> 16

    def output(self):
        print("a = {}nb = {}nm = {}".format(self.a, self.b, self.m))
        print("state1 = {}".format(self.next()))
        print("state2 = {}".format(self.next()))

class DH:
    def __init__(self):
        self.lcg = LCG()
        self.lcg.output()
        self.g = getRandomNBitInteger(128)
        self.m = getPrime(256)
        self.A, self.a = self.gen_AB()
        self.B, self.b = self.gen_AB()
        self.key = pow(self.A, self.b, self.m)

    def gen_AB(self):
        x = ''
        for _ in range(64):
            x += '1' if self.lcg.next() % 2 else '0'
        return pow(self.g, int(x, 2), self.m), int(x, 2)

DH = DH()
flag = bytes_to_long(flag)
print("g = {}nA = {}nB = {}nM = {}".format(DH.g, DH.A, DH.B, DH.m))
print("Cipher = {}".format(flag ^ DH.key))

'''
a = 3844066521
b = 3316005024
m = 2249804527
state1 = 16269
state2 = 4249
g = 183096451267674849541594370111199688704
A = 102248652770540219619953045171664636108622486775480799200725530949685509093530
B = 74913924633988481450801262607456437193056607965094613549273335198280176291445
M = 102752586316294557951738800745394456033378966059875498971396396583576430992701
Cipher = 13040004482819935755130996285494678592830702618071750116744173145400949521388647864913527703
'''

首先观察到有很多的随机数,并且其中a,b,m,g,m均已知,而随机数种子数seed还未知,根据LCG()函数,写出脚本爆出seed

a = 3844066521
b = 3316005024
m = 2249804527
seed = 1

def next(a,b,m,seed):
    seed = (a*seed+b)%m
    return seed >> 16
def next1(a,b,m,seed):
    seed = (a*seed+b)%m
    seedd = (a*seed+b)%m
    return seedd >> 16
while(1):
    seed1 = next(a,b,m,seed)
    if seed1 == 16269:
        seed2 = next1(a,b,m,seed)
        if seed2 == 4249:
            print seed
            break
    seed += 1
#714405490

接着把所有已知量带入,可以在最后解出明文

from Crypto.Util.number import*

class LCG:
    def __init__(self):
        self.a = 3844066521
        self.b = 3316005024
        self.m = 2249804527
        self.seed = 714405490

    def next(self):
        self.seed = (self.a*self.seed+self.b) % self.m
        return self.seed >> 16

    def output(self):
        print("a = {}nb = {}nm = {}".format(self.a, self.b, self.m))
        print("state1 = {}".format(self.next()))
        print("state2 = {}".format(self.next()))

class DH:
    def __init__(self):
        self.lcg = LCG()
        self.lcg.output()
        self.g = 183096451267674849541594370111199688704
        self.m = 102752586316294557951738800745394456033378966059875498971396396583576430992701
        self.A, self.a = self.gen_AB()
        self.B, self.b = self.gen_AB()
        self.key = pow(self.A, self.b, self.m)

    def gen_AB(self):
        x = ''
        for _ in range(64):
            x += '1' if self.lcg.next() % 2 else '0'
        return pow(self.g, int(x, 2), self.m), int(x, 2)

DH = DH()
Cipher = 13040004482819935755130996285494678592830702618071750116744173145400949521388647864913527703
#flag = bytes_to_long(flag)
#print("g = {}nA = {}nB = {}nM = {}".format(DH.g, DH.A, DH.B, DH.m))
print("flag = {}".format(long_to_bytes(Cipher ^ DH.key)))

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值