不知为何,密码比逆向做的多,但是不会密码也不会逆向

crypto

解个方程

1
2
3
4
5
6
7
8
from Crypto.Util.number import *
from gmpy2 import invert
p = 88405749077010121197972538332505989817
q = 314336612126421969080144444342415739457
e = 65537

d = invert(e, (p-1)*(q-1))
print(d)

这个是动态flag

ez_log

这个题是求离散对数,g=3,直接用函数求

1
2
3
4
5
6
7
8
9
10
from Crypto.Util.number import long_to_bytes


from sympy.ntheory import discrete_log
p=3006156660704242356836102321001016782090189571028526298055526061772989406357037170723984497344618257575827271367883545096587962708266010793826346841303043716776726799898939374985320242033037
g = 3
c=2637361207438328172880452774725735558448205624296999428196250415451022718950315626464793126507500112508727744681450551541566511482157902377105193512791814667446983536196889757495426692091900

m = discrete_log(p, c, g)
print(long_to_bytes(m))

也是动态flag

四重加密

1
2
3
4
5
6
7
8
base32:
qsnctf
ascii code:
zcye{mxmemtxrzt_lzbha_kwmqzec}|key=hello
维吉尼亚:
synt{yqitbfqnoi_xsxwp_wpifoqv}
凯撒:
flag{ldvgosdabv_kfkjc_jcvsbdi}

把flag改成qsnctf就好

ez_rsa

1
2
3
4
5
6
7
8
9
10
11
12
13
from Crypto.Util.number import *
flag = b'qsnctf{xxx-xxxx-xxxx-xxxx-xxxxxxxxx}'
m = bytes_to_long(flag)
p = getPrime(512)
q = getPrime(512)
r = getPrime(512)
n = p * q * r
leak = p * q
e = 0x10001
c = pow(m, e, n)
print(f'c = {c}')
print(f'n = {n}')
print(f'leak = {leak}')

相当于已知r,e,c求m

我们知道
$$
c = m^e \mod pqr\iff\
c = m^e + kpqr\iff\
c = m^e + (kpq)r\iff\
c = m^e \mod r
$$
那么就可以解出来了

1
2
3
4
5
6
7
8
9
10
11
12
13
from Crypto.Util.number import *
import gmpy2 as gy

c = 173595148273920891298949441727054328036798235134009407863895058729356993814829340513336567479145746034781201823694596731886346933549577879568197521436900228804336056005940048086898794965549472641334237175801757569154295743915744875800647234151498117718087319013271748204766997008772782882813572814296213516343420236873651060868227487925491016675461540894535563805130406391144077296854410932791530755245514034242725719196949258860635915202993968073392778882692892
n = 1396260492498511956349135417172451037537784979103780135274615061278987700332528182553755818089525730969834188061440258058608031560916760566772742776224528590152873339613356858551518007022519033843622680128062108378429621960808412913676262141139805667510615660359775475558729686515755127570976326233255349428771437052206564497930971797497510539724340471032433502724390526210100979700467607197448780324427953582222885828678441579349835574787605145514115368144031247
leak = 152254254502019783796170793516692965417859793325424454902983763285830332059600151137162944897787532369961875766745853731769162511788354655291037150251085942093411304833287510644995339391240164033052417935316876168953838783742499485868268986832640692657031861629721225482114382472324320636566226653243762620647
r = n // leak
phi = r-1
e = 0x10001
d = gy.invert(e,phi)
m = pow(c,d,r)
print(long_to_bytes(m))
#qsnctf{12ff81e0-7646-4a96-a7eb-6a509ec01c9e}

根据这道题可以知道:已知c,e,和n的任意一个因子(如果这个因子可以求phi)那就可以直接解

factor1

这个题是第一次见

1
2
3
4
5
6
7
8
9
10
11
12
13
import gmpy2
import hashlib
from Crypto.Util.number import *

p = getPrime(512)
q = getPrime(512)
d = getPrime(256)
e = gmpy2.invert(d, (p**2 - 1) * (q**2 - 1))
flag = "qsnctf{" + hashlib.md5(str(p+q).encode()).hexdigest() + "}"
print(flag)
# 4602579741478096718172697218991734057017874575484294836043557658035277770732473025335441717904100009903832353915404911860888652406859201203199117870443451616457858224082143505393843596092945634675849883286107358454466242110831071552006337406116884147391687266536283395576632885877802269157970812862013700574069981471342712011889330292259696760297157958521276388120468220050600419562910879539594831789625596079773163447643235584124521162320450208920533174722239029506505492660271016917768383199286913178821124229554263149007237679675898370759082438533535303763664408320263258144488534391712835778283152436277295861859
# 78665180675705390001452176028555030916759695827388719494705803822699938653475348982551790040292552032924503104351703419136483078949363470430486531014134503794074329285351511023863461560882297331218446027873891885693166833003633460113924956936552466354566559741886902240131031116897293107970411780310764816053

可以看到这个题很神奇的地方在于(p*2 - 1) * (q*2 - 1),所以我去搜了一下,就搜到攻击脚本了

Cryptanalysis of RSA Variants with Primes Sharing Most Significant Bits - tr0uble - 博客园 (cnblogs.com)

好像叫LUC,用连分数方法攻击,但是看不懂,有机会之后看看

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
from sage.all import *
from math import isqrt
def attack(N, e):
"""
Recovers the prime factors of a modulus and the private exponent if two prime factors share most significant bits
:param N: the modulus
:param e: the public exponent
:return: a tuple containing the prime factors and the private exponent, or None if the private exponent was not found
"""
PR = PolynomialRing(ZZ, 'x')
x = PR.gen()
convergents = continued_fraction(ZZ(e) / ZZ((N-1)**2)).convergents()
for c in convergents:
k = c.numerator()
d = c.denominator()
try:
f = x**2 - x*(N**2 + 1 - int((e*d-1)/k)) + N**2
if f.discriminant() > 0:
root = f.roots()
p2 = root[0][0]; q2 = root[1][0]
if is_square(p2) and is_square(q2):
p = isqrt(p2); q = isqrt(q2)
if p*q == N:
return p, q, d
except:
continue
return None

e = 4602579741478096718172697218991734057017874575484294836043557658035277770732473025335441717904100009903832353915404911860888652406859201203199117870443451616457858224082143505393843596092945634675849883286107358454466242110831071552006337406116884147391687266536283395576632885877802269157970812862013700574069981471342712011889330292259696760297157958521276388120468220050600419562910879539594831789625596079773163447643235584124521162320450208920533174722239029506505492660271016917768383199286913178821124229554263149007237679675898370759082438533535303763664408320263258144488534391712835778283152436277295861859
n = 78665180675705390001452176028555030916759695827388719494705803822699938653475348982551790040292552032924503104351703419136483078949363470430486531014134503794074329285351511023863461560882297331218446027873891885693166833003633460113924956936552466354566559741886902240131031116897293107970411780310764816053
p=q=d=0
p,q,d = attack(n,e)
print(str(p + q))

这个是sage

1
2
17842948407837550252915901438494310860377505026658598797918460167146832545038336985103505761787935094014130901091944301325113646047622033244783641463109866\
qsnctf{8072e8b2982bc729cc74ef58f1abc862}

misc

那个txt一打开,好像看不出来是什么,到最后发现504d0304那就是压缩包了,写个脚本生成文件

1
2
3
4
5
6
7
8
9
10
11
12
13
def hex_to_bin(input_file, output_file):
with open(input_file, 'r') as f_in, open(output_file, 'wb') as f_out:
for i, line in enumerate(f_in):
if i % 2 == 0: # 每隔一行处理一次
hex_str = line[10:57].replace(' ', '') # 从第11个字符开始,读取到第57个字符
bin_data = bytes.fromhex(hex_str)
f_out.write(bin_data)

# 使用函数


hex_to_bin('a.txt', 'output.zip')
#这边事先处理成正的了

output.zip直接爆破,因为说了是小写和数字

z12345,得到flag图片拼接即可

1
qsnctf{b414e3e3a6449ddba0997db259203eb7}

RE

来打cs咯

文件描述不要在实体机打开

于是在win10虚拟机中sandboxie中尝试用ida调试

但是打开后函数很杂,看不出来在干什么

网上查查这种题该怎么做,看到要放到在线沙箱中分析一下

直接拿到

10.0.80.253:8118

1
qsnctf{10.0.80.253:8118}