安恒DASCTF五月月赛

我是菜鸡,我是菜鸡,我是菜鸡,重要的事情说三遍。

Crypto

1. bbcrypto

这个...直接就解同余方程组。

#! /usr/bin/env python3
from Crypto.Util.number import inverse
from itertools import cycle
hexstr = "177401504b0125272c122743171e2c250a602e3a7c206e014a012703273a3c0160173a73753d"
[x1, x2, x3, x4, x5] = [ord("flag{"[i]) for i in range(5)]
[c1, c2, c3, c4, c5] = [int(hexstr[2*i:2*(i+1)],16) for i in range(5)]
a1 = (c4-c1)*inverse((x4-x1), 128) % 128
a2 = (c5-c2)*inverse((x5-x2), 128) % 128
assert a1 == a2
a = a1
b1 = (c1 - a * x1) % 128
b2 = (c2 - a * x2) % 128
b3 = (c3 - a * x3) % 128
a_ = inverse(a, 128)
salt = [b1, b2, b3]
si = cycle(salt)
cycletimes = len(hexstr) // 2
clist = [int(hexstr[2*i:2*(i+1)],16) for i in range(cycletimes)]
flag = b""
for i in range(cycletimes):
    flag += bytes([(clist[i]-next(si))*a_ % 128])
print(flag)

2. Encrypt_Img

这个其实也能想到。首先看到了Plaintext1和Plaintext2的长度差1,又发现是RC4流加密。设Key产生的密钥流是Keystream,那么
ciphertext1 = Plaintext1 \bigoplus Keystream
ciphertext2 = Plaintext2 \bigoplus Keystream
因为Ciphertext1, Ciphertext2, Plaintext1, Plaintext2已知,因此可以求得前P1和P2长度的Keystream,其中len(P1\_Keystream) - len(P2\_Keysteam) = 1
设现在是加密到了图像(Image)的第i字节,那么有
Enc1[i] = Image[i] \bigoplus Keystream[i+1]
Enc2[i] = Image[i] \bigoplus Keystream[i]
现在已知Enc1, Enc2, Keystream[0],想求Image
Enc2[0] = Image[0] \bigoplus Keystream[0],即Image[0] = Enc2[0] \bigoplus Keystream[0]
那么Keystream[1] = Enc1[0] \bigoplus Image[0]
以此类推,能求得全部的Keystream和Image。

from numpy import array
from PIL import Image
from Crypto.Util.number import long_to_bytes, bytes_to_long

Plaintext1 = "RC4IsInteresting"
Plaintext2 = "ThisIsAEasyGame"
ciphertext1 = 12078640933356268898100798377710191641
ciphertext2 = 79124196547094980420644350061749775
keystream1 = long_to_bytes(bytes_to_long(Plaintext1.encode()) ^ ciphertext1)
keystream2 = long_to_bytes(bytes_to_long(Plaintext2.encode()) ^ ciphertext2)
keystream = [keystream1[0]]
enc1 = Image.open(r"enc1.png")
enc2 = Image.open(r"enc2.png")
img1 = array(enc1)
img2 = array(enc2)
a, b, _ = img1.shape
m = 0
for i in range(a):
    for j in range(b):
        pixel1 = img1[i][j]
        pixel2 = img2[i][j]
        for k in range(3):
            pixel2[k] ^= keystream[m]
            keystream.append(pixel1[k]^pixel2[k])
            m += 1
        img2[i][j] = pixel2
dec = Image.fromarray(img2)
# dec.show()
dec.save("flag.png")

3. easyLCG

LCG写C语言开满优化爆破就完事啦

#include <stdio.h>
#include <limits.h>
const __int64 a = 3844066521;
const __int64 b = 3316005024;
const __int64 m = 2249804527;
const __int64 state1 = 16269;
const __int64 state2 = 4249;
int main() {
    __int64 i = 0;
    __int64 seed;
    for (;;) {
        seed = (a*i + b) % m;
        if ((seed >> 16) == state1) {
            seed = (a*seed + b) % m;
            if ((seed >> 16) == state2) {
                printf("%lld", i);
                return 0;
            }
        }
        if (i == UINT_MAX) break;
        i++;
    }
}
#/usr/bin/env python3
from Crypto.Util.number import *
class LCG:
    def __init__(self):
        self.a = 3844066521
        self.b = 3316005024
        self.m = 2249804527
        self.seed = 714405490 # 写C开满优化爆破
    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
Plaintext = Cipher ^ dh.key
print(long_to_bytes(Plaintext))
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容