dasctf 7月赛

problem_2

from Crypto.Util.number import *
from Crypto.Cipher import AES
from hashlib import sha256
from random import randbytes, getrandbits
from flag import flag
def diffie_hellman(g, p, flag):
    alice = getrandbits(1024)
    bob = getrandbits(1024)
    alice_c = pow(g, alice, p)
    bob_c = pow(g, bob, p)
    print(alice_c , bob_c)
    key = sha256(long_to_bytes(pow(bob_c, alice, p))).digest()
    iv = b"dasctfdasctfdasc"
    aes = AES.new(key, AES.MODE_CBC, iv)
    enc = aes.encrypt(flag)
    print(enc)

def getp():
    p = int(input("P = "))
    assert isPrime(p)
    assert p.bit_length() >= 1024 and p.bit_length() <= 2048
    g = 2
    diffie_hellman(g, p, flag)

getp()

diffie-hellman,p选手给,那就构造一个p-1光滑直接梭哈掉了。

exp:

import gmpy2
from Crypto.Util.number import getPrime
import random
from Crypto.Util.number import *
from Crypto.Cipher import AES
from hashlib import sha256 

def gen_prime(digit):
    primes = []
    pri = 1
    while(len(primes)<100):
        pri = gmpy2.next_prime(pri)
        primes.append(int(pri))
    while True:
        count = 2
        while count < 2**digit:
            count *= random.choice(primes)
        count += 1
        if(gmpy2.is_prime(count)):
            return count

'''p = gen_prime(1024) 
G = GF(P) 
g_ = G(g) 
ac_ = G(ac) 
alice = int(discrete_log(ac_,g_)) 
print(alice)

'''

alice = 1046382552755992811457982912694618414872058936337177684338202569822370210620216903105219207397545099396117900950990663819206744964944899595012911402477464329708104871889963814612755420606417426402402131901720127104652472541002317267138113556214527301245557009631475388100000836750737255081835356782751153367 
P = 335347423405170083398559193700458873250569626299973646883438047064926777811449508027635784322795263459385528095096950146720369849218673184537518905837461553332860863341898712720955258188662619459370538150944015362912381662926695555870098124952507918358330303676192552193204581458968503798256226692794489522821
ac,bc=223676019829477985645895853282768682560855850770933122577933519525057883850366435365443483994163940231382663968887215078379264068697081085889130204146863047561895606804119130512046059900944330438737166140524383141720020490696090144841644182519896300804491684305301848398654866801293171153005854449806177065769, 175861293669891528934345252748997792066936662405310572915942032646583833324927754007720831902026700146884820356166597766296538489029268404074802240969314519015975193008206638659010499894115919252744649609865797973520881153393357369190942129525709128275570322882970502645366664567710272801953146630381233539658
ct = b'a\\x01\\xe1\\x0f\\x03\\xdd\\xb2\\x88wn\\xear\\xac&\\xbf\\x8aP\\xb1\\xc3C\\xc6\\xfb\\xe1\\xfa\\x8b\\x98\\xc9\\xee;B\\xef\\x19y\\xc2\\x1c\\xfb!\\x16\\xdd/f\\x82+f\\x81\\xee;\\x16'
g = 2 

key = sha256(long_to_bytes(pow(bc, alice, P))).digest()
iv = b"dasctfdasctfdasc"
aes = AES.new(key, AES.MODE_CBC, iv)
enc = aes.decrypt(ct)
print(enc)
import gmpy2
from Crypto.Util.number import getPrime
import random
from Crypto.Util.number import *
from Crypto.Cipher import AES
from hashlib import sha256 

def gen_prime(digit):
    primes = []
    pri = 1
    while(len(primes)<100):
        pri = gmpy2.next_prime(pri)
        primes.append(int(pri))
    while True:
        count = 2
        while count < 2**digit:
            count *= random.choice(primes)
        count += 1
        if(gmpy2.is_prime(count)):
            return count

'''p = gen_prime(1024) 
G = GF(P) 
g_ = G(g) 
ac_ = G(ac) 
alice = int(discrete_log(ac_,g_)) 
print(alice)

'''

alice = 1046382552755992811457982912694618414872058936337177684338202569822370210620216903105219207397545099396117900950990663819206744964944899595012911402477464329708104871889963814612755420606417426402402131901720127104652472541002317267138113556214527301245557009631475388100000836750737255081835356782751153367 
P = 335347423405170083398559193700458873250569626299973646883438047064926777811449508027635784322795263459385528095096950146720369849218673184537518905837461553332860863341898712720955258188662619459370538150944015362912381662926695555870098124952507918358330303676192552193204581458968503798256226692794489522821
ac,bc=223676019829477985645895853282768682560855850770933122577933519525057883850366435365443483994163940231382663968887215078379264068697081085889130204146863047561895606804119130512046059900944330438737166140524383141720020490696090144841644182519896300804491684305301848398654866801293171153005854449806177065769, 175861293669891528934345252748997792066936662405310572915942032646583833324927754007720831902026700146884820356166597766296538489029268404074802240969314519015975193008206638659010499894115919252744649609865797973520881153393357369190942129525709128275570322882970502645366664567710272801953146630381233539658
ct = b'a\\x01\\xe1\\x0f\\x03\\xdd\\xb2\\x88wn\\xear\\xac&\\xbf\\x8aP\\xb1\\xc3C\\xc6\\xfb\\xe1\\xfa\\x8b\\x98\\xc9\\xee;B\\xef\\x19y\\xc2\\x1c\\xfb!\\x16\\xdd/f\\x82+f\\x81\\xee;\\x16'
g = 2 

key = sha256(long_to_bytes(pow(bc, alice, P))).digest()
iv = b"dasctfdasctfdasc"
aes = AES.new(key, AES.MODE_CBC, iv)
enc = aes.decrypt(ct)
print(enc)

Untitled

problem_1

from Crypto.Util.number import *
from secret import secret, flag
def encrypt(m):
    return pow(m, e, n)
assert flag == b"dasctf{" + secret + b"}"
e = 11
p = getPrime(512)
q = getPrime(512)
n = p * q
P = getPrime(512)
Q = getPrime(512)
N = P * Q
gift = P ^ (Q >> 16)
print(N, gift, pow(n, e, N))
print(encrypt(bytes_to_long(secret)),
    encrypt(bytes_to_long(flag)))

# 75000029602085996700582008490482326525611947919932949726582734167668021800854674616074297109962078048435714672088452939300776268788888016125632084529419230038436738761550906906671010312930801751000022200360857089338231002088730471277277319253053479367509575754258003761447489654232217266317081318035524086377 8006730615575401350470175601463518481685396114003290299131469001242636369747855817476589805833427855228149768949773065563676033514362512835553274555294034 14183763184495367653522884147951054630177015952745593358354098952173965560488104213517563098676028516541915855754066719475487503348914181674929072472238449853082118064823835322313680705889432313419976738694317594843046001448855575986413338142129464525633835911168202553914150009081557835620953018542067857943
# 69307306970629523181683439240748426263979206546157895088924929426911355406769672385984829784804673821643976780928024209092360092670457978154309402591145689825571209515868435608753923870043647892816574684663993415796465074027369407799009929334083395577490711236614662941070610575313972839165233651342137645009 46997465834324781573963709865566777091686340553483507705539161842460528999282057880362259416654012854237739527277448599755805614622531827257136959664035098209206110290879482726083191005164961200125296999449598766201435057091624225218351537278712880859703730566080874333989361396420522357001928540408351500991

rsa异或的题以前遇到过,这里改成了右移然后异或,改下脚本就OK

import gmpy2 as gp 
from tqdm import tqdm 
N,gift,c1 = 75000029602085996700582008490482326525611947919932949726582734167668021800854674616074297109962078048435714672088452939300776268788888016125632084529419230038436738761550906906671010312930801751000022200360857089338231002088730471277277319253053479367509575754258003761447489654232217266317081318035524086377,8006730615575401350470175601463518481685396114003290299131469001242636369747855817476589805833427855228149768949773065563676033514362512835553274555294034,14183763184495367653522884147951054630177015952745593358354098952173965560488104213517563098676028516541915855754066719475487503348914181674929072472238449853082118064823835322313680705889432313419976738694317594843046001448855575986413338142129464525633835911168202553914150009081557835620953018542067857943
P_h = gift >> (512-16)

def findp(p,q,q_):
    if len(p)==(512-16):
        pp=int(p,2) + P_h * 2 ** (512-16)
        if gp.gcd(N,pp) > 1:
            print(pp)
    else:
        l=len(p)
        pp=int(p,2)
        qq=int(q,2)
        if (pp^qq)%(2**l)==gift%(2**l) and pp*(qq*2**16 + q_)%(2**l)==N%(2**l):
            findp('1'+p,'1'+q,q_)
            findp('1'+p,'0'+q,q_)
            findp('0'+p,'1'+q,q_)
            findp('0'+p,'0'+q,q_)
for q_ in tqdm(range(2**16)):
    findp('1','1',q_)

同时注意到一个问题,factordb分一下n,会发现有小因子(甚至是偶数),所以所以n应该比N大,再加一个N查,就啥也查不到了。

后面的就不会了,没做过这种related-message attack,现翻ctf-wiki:

Untitled

同时flag的长度也不知道,需要爆破:

exp:

from Crypto.Util.number import *

n = 83410392685813224685786027640778560521035854332627839979281105731457044069408118952629284089869335506983096270269822559619624906180108256504440296527471536363057103101146262613593336072556587341466840510200003498265457285439149541137127199088938421905041387224795918868443175561632999479925818053898100117419
c1 = 69307306970629523181683439240748426263979206546157895088924929426911355406769672385984829784804673821643976780928024209092360092670457978154309402591145689825571209515868435608753923870043647892816574684663993415796465074027369407799009929334083395577490711236614662941070610575313972839165233651342137645009
c2 = 46997465834324781573963709865566777091686340553483507705539161842460528999282057880362259416654012854237739527277448599755805614622531827257136959664035098209206110290879482726083191005164961200125296999449598766201435057091624225218351537278712880859703730566080874333989361396420522357001928540408351500991

def attack(c1, c2, e, n,le,h):
    PR.<x>=PolynomialRing(Zmod(n))
    g1 = x^e - c1
    g2 = (h*2^(le+8)+x*2^8+125)^e - c2
    def gcd(g1, g2):
        while g2:
            g1, g2 = g2, g1 % g2
        return g1.monic()
    return -gcd(g1, g2)[0]

e=11
h = b"dasctf{"
b = b'}'
h = bytes_to_long(h)
b = bytes_to_long(b)
print(b)
for le in range(1,300):
    try:
        t = attack(c1,c2,e,n,le,h)
        print(long_to_bytes(int(t)).decode())
    except:
        continue