CryptoCTF easy

文章目录

  • 2023
    • suction
    • Blue Office
  • 2022
    • Baphomet

2023

suction

题目描述:

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

def keygen(nbit, r):
	while True:
		p, q = [getPrime(nbit) for _ in '__']
		e, n = getPrime(16), p * q
		phi = (p - 1) * (q - 1)
		if GCD(e, phi) == 1:
			N = bin(n)[2:-r]
			E = bin(e)[2:-r]
			PKEY = N + E
			pkey = (n, e)
			return PKEY, pkey

def encrypt(msg, pkey, r):
	m = bytes_to_long(msg)
	n, e = pkey
	c = pow(m, e, n)
	C = bin(c)[2:-r]
	return C

r, nbit = 8, 128
PKEY, pkey = keygen(nbit, r)
print(f'PKEY = {int(PKEY, 2)}')
FLAG = flag.lstrip(b'CCTF{').rstrip(b'}')
enc = encrypt(FLAG, pkey, r)
print(f'enc = {int(enc, 2)}')

题目分析:
给出了n,e,c且每个都是少最后8bit
n - 256bit,e - 16bit,由于都比较小,可直接爆破出来
n这里用factor()分解,若最后分解得到的是两个数,并且都是128bit,那么p,q,n都可以确定了
n出来了那之后再爆e和c,256 * 256,也不大,最后通过得到的flag是否都为可打印字符来判断flag是否正确

from Crypto.Util.number import *
from gmpy2 import *
PKEY = 55208723145458976481271800608918815438075571763947979755496510859604544396672
ENC = 127194641882350916936065994389482700479720132804140137082316257506737630761 << 8
n_ = int(bin(PKEY)[2:-8],2) << 8
e_ = int(bin(PKEY)[-8:],2) << 8

# for i in range(45,256):
#     print(i)
#     n = n_ + i
#     if n % 2 == 0:
#         continue
#     a = factor(n)
#     if len(a) == 2:
#         print(n,a,i) # 69

n = 55208723145458976481271800608918815438075571763947979755496510859604544396613 
p = 188473222069998143349386719941755726311
q = 292926085409388790329114797826820624883
phi = (p - 1) * (q - 1)
for i in range(256):
    e = e_ + i
    if not isPrime(e):
        continue
    for j in range(256):
        c = ENC + j
        d = inverse(e,phi)
        m = pow(c,d,n)
        flag = long_to_bytes(int(m))
        if flag.isascii():
            print(flag)
# CCTF{6oRYGy&Dc$G2ZS}  

Blue Office

题目描述:

import binascii
from secret import seed, flag

def gen_seed(s):
    i, j, k = 0, len(s), 0
    while i < j:
        k = k + ord(s[i])
        i += 1
    i = 0
    while i < j:
        if (i % 2) != 0:
            k = k - (ord(s[i]) * (j - i + 1))
        else:
            k = k + (ord(s[i]) * (j - i + 1))

        k = k % 2147483647
        i += 1

    k = (k * j) % 2147483647
    return k

def reseed(s):
    return s * 214013 + 2531011

def encrypt(s, msg):
    assert s <= 2 ** 32
    c, d = 0, s
    enc, l = b'', len(msg)
    while c < l:
        d = reseed(d)
        enc += (msg[c] ^ ((d >> 16) & 0xff)).to_bytes(1, 'big')
        c += 1
    return enc

enc = encrypt(seed, flag)
print(f'enc = {binascii.hexlify(enc)}')

题目分析:
gen_seed()压根没用到呀,感觉是用来耗时间的,有些人喜欢顺着看下来,看完之后才发现这串没用,但时间也过去了。所以还是从加密那里看起吧。
步入正题
主要在下面两串
d = reseed(d)
enc += (msg[c] ^ ((d >> 16) & 0xff)).to_bytes(1, 'big')
第一串LCG,第二串flag的其中一个字节和d的第16-24位(1个字节)异或。assert s <= 2 ** 32表明s应该在32位左右,但我们只需用到24位,所以可以把这个运算看成GF(2 ** 24)下的运算,flag的格式固定CCTF{},故通过异或运算可以得到seed的第16-24位,还16位未知,不大直接爆破,之后flag也就出来了

import binascii
enc = 'b0cb631639f8a5ab20ff7385926383f89a71bbc4ed2d57142e05f39d434fce'
enc = binascii.unhexlify(enc)
flag = b'CCTF{'

def reseed(s):
    return s * 214013 + 2531011

def encrypt(s, msg):
    assert s <= 2 ** 32
    c, d = 0, s
    enc, l = b'', len(msg)
    while c < l:
        d = reseed(d)
        enc += (msg[c] ^ ((d >> 16) & 0xff)).to_bytes(1, 'big')
        c += 1
    return enc

s1 = (enc[0] ^ flag[0]) << 16

for i in range(2 ** 16):
    seed = s1 + i
    flag = encrypt(seed,enc[1:])
    if b'CTF' in flag:
        print(flag)
# CCTF{__B4ck_0r!F1c3__C1pHeR_!!}

2022

Baphomet

题目描述:

from base64 import b64encode
from flag import flag

def encrypt(msg):
	ba = b64encode(msg.encode('utf-8'))
	baph, key = '', ''

	for b in ba.decode('utf-8'):
		if b.islower():
			baph += b.upper()
			key += '0'
		else:
			baph += b.lower()
			key += '1'

	baph = baph.encode('utf-8')
	key = int(key, 2).to_bytes(len(key) // 8, 'big')

	enc = b''
	for i in range(len(baph)):
		enc += (baph[i] ^ key[i % len(key)]).to_bytes(1, 'big')

	return enc

enc = encrypt(flag)
f = open('flag.enc', 'wb')
f.write(enc)
f.close()

题目分析:
密文长度为48,说明key长度为6(字节)
CCTF{40bit,大于6 * 6base64以6字节分组加密)
故可知baph前6位q0nurN,与密文前6位异或得到key
key和密文都知道,异或便可得到完整flag

未完待续…

你可能感兴趣的:(赛事复现,密码学,安全,ctf)