sky's blog

Jarvis-OJ-Crypto

字数统计: 3,283阅读时长: 18 min
2017/12/11 Share

Medium RSA

题目到手后给了一个公钥和一个密文
我们对这个公钥提取信息:
可以得到
N = 0xC2636AE5C3D8E43FFB97AB09028F1AAC6C0BF6CD3D70EBCA281BFFE97FBE30DD
E = 65537
C = 0x6D3EB7DF23EEE1D38710BEBA78A0878E0E9C65BD3D08496DDA64924199110C79
公钥极短,我们可以直接分解N,得到p和q
P = 275127860351348928173285174381581152299
Q = 319576316814478949870590164193048041239
然后容易求出d = 10866948760844599168252082612378495977388271279679231539839049698621994994673
生成私钥

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
# coding=utf-8
import math
import sys
from Crypto.PublicKey import RSA

keypair = RSA.generate(1024)

keypair.p = 275127860351348928173285174381581152299
keypair.q = 319576316814478949870590164193048041239
keypair.e = 65537

keypair.n = keypair.p * keypair.q
Qn = long((keypair.p-1) * (keypair.q-1))

i = 1
while (True):
x = (Qn * i ) + 1
if (x % keypair.e == 0):
keypair.d = x / keypair.e
break
i += 1

private = open('private.pem','w')
private.write(keypair.exportKey())
private.close()

然后解密得到flag:

1
2
3
openssl rsautl -decrypt -in flag.enc -inkey private.pem -out flag.dec
cat flag.dec
PCTF{256b_i5_m3dium}

BrokenPic

发现文件缺少bmp文件头,补上文件头:

1
42 4D 38 0C 30 00 00 00 00 00 36 00 00 00 28 00 00 00 56 05 00 00 00 03 00 00 01 00 18 00 00 00 00 00 02 0C 30 00 12 0B 00 00 12 0B 00 00 00 00 00 00 00 00 00 00

发现图片可以看了
然后可以看到有key,后发现bmp 内的数据变化很规律,可能是块密码,试试 AES,用key 解密一下:

1
2
3
4
5
6
7
8
9
10
11
12
#!/usr/bin/python
# coding=utf-8
from Crypto.Cipher import AES
key = 'PHRACK-BROKENPIC'
aes = AES.new(key)

with open('brokenpic.bmp', 'r') as f:
data = f.read()
pic = aes.decrypt(data)

with open('2.bmp', 'w') as f:
f.write(pic)

然后可以得到:
原来的图片,扫描后即可得到flag

hard RSA

提取公钥发现e为2,查阅资料找到rabin算法,
可以先分解n,再用对应的脚本解密即可
分解n得到:
p=275127860351348928173285174381581152299
q=319576316814478949870590164193048041239
破解脚本如下

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
# coding=utf-8
import gmpy2
import string
from Crypto.PublicKey import RSA
with open('pubkey.pem', 'r') as f:
key = RSA.importKey(f)
N = key.n
e = key.e
with open('flag.enc', 'r') as f:
cipher = f.read().encode('hex')
cipher = string.atoi(cipher, base=16)
# print cipher
print "please input p"
p = int(raw_input(), 10)
print 'please input q'
q = int(raw_input(), 10)
inv_p = gmpy2.invert(p, q)
inv_q = gmpy2.invert(q, p)
mp = pow(cipher, (p + 1) / 4, p)
mq = pow(cipher, (q + 1) / 4, q)
a = (inv_p * p * mq + inv_q * q * mp) % N
b = N - int(a)
c = (inv_p * p * mq - inv_q * q * mp) % N
d = N - int(c)
for i in (a, b, c, d):
s = '%x' % i
if len(s) % 2 != 0:
s = '0' + s
print s.decode('hex')

解密后即可得到flag

very hard RSA

根据题目给出的程序容易看出是RSA的共模攻击
破解脚本如下:

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
34
35
36
37
# coding=utf-8
import string
import gmpy
def egcd(a, b):
if a == 0:
return b, 0, 1
else:
g, y, x = egcd(b % a, a)
return g, x - b // a * y, y
def main():
with open('flag.enc1', 'r') as f1:
c1 = f1.read().encode('hex')
c1 = string.atoi(c1, base=16)

with open('flag.enc2', 'r') as f2:
c2 = f2.read().encode('hex')
c2 = string.atoi(c2, base=16)
n = 0x00b0bee5e3e9e5a7e8d00b493355c618fc8c7d7d03b82e409951c182f398dee3104580e7ba70d383ae5311475656e8a964d380cb157f48c951adfa65db0b122ca40e42fa709189b719a4f0d746e2f6069baf11cebd650f14b93c977352fd13b1eea6d6e1da775502abff89d3a8b3615fd0db49b88a976bc20568489284e181f6f11e270891c8ef80017bad238e363039a458470f1749101bc29949d3a4f4038d463938851579c7525a69984f15b5667f34209b70eb261136947fa123e549dfff00601883afd936fe411e006e4e93d1a00b0fea541bbfc8c5186cb6220503a94b2413110d640c77ea54ba3220fc8f4cc6ce77151e29b3e06578c478bd1bebe04589ef9a197f6f806db8b3ecd826cad24f5324ccdec6e8fead2c2150068602c8dcdc59402ccac9424b790048ccdd9327068095efa010b7f196c74ba8c37b128f9e1411751633f78b7b9e56f71f77a1b4daad3fc54b5e7ef935d9a72fb176759765522b4bbc02e314d5c06b64d5054b7b096c601236e6ccf45b5e611c805d335dbab0c35d226cc208d8ce4736ba39a0354426fae006c7fe52d5267dcfb9c3884f51fddfdf4a9794bcfe0e1557113749e6c8ef421dba263aff68739ce00ed80fd0022ef92d3488f76deb62bdef7bea6026f22a1d25aa2a92d124414a8021fe0c174b9803e6bb5fad75e186a946a17280770f1243f4387446ccceb2222a965cc30b3929L
e1 = 17
e2 = 65537
s = egcd(e1, e2)
s1 = s[1]
s2 = s[2]

if s1 < 0:
s1 = -s1
c1 = gmpy.invert(c1, n)
elif s2 < 0:
s2 = -s2
c2 = gmpy.invert(c2, n)

m = pow(c1, s1, n) * pow(c2, s2, n) % n
print '{:x}'.format(int(m)).decode('hex')

if __name__ == '__main__':
main()
`

解密后可以得到flag

Extremely hard RSA

拿到题目后分析
得到e =3
推断是RSA的低指数攻击
写脚本如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#!/usr/bin/python
# coding=utf-8
import gmpy
from Crypto.PublicKey import RSA
def calc(j):
a, b = gmpy.root(cipher + j * N, 3)
if b > 0:
m = a
print '{:x}'.format(int(m)).decode('hex')
# pool.terminate()
with open('pubkey.pem', 'r') as f:
key = RSA.importKey(f)
N = key.n
e = key.e
with open('flag.enc', 'r') as f:
cipher = f.read().encode('hex')
cipher = int(cipher, 16)
inputs = range(118600000, 118720000)
result = []
map(calc, inputs)
print len(result)

爆破N久后可以得到flag

God Like RSA

先留个坑位,后面补写

简单ECC概念

参考链接:http://www.8btc.com/eccmath
大体上的意思是说,给你一个曲线F:y^2=x^3+ax+b
你确定下来a和b,然后找一个在曲线F上的点G(x1,y1)
然后自己随机生成一个k(私钥)
然后生成公钥S=kG
注意,这里的kG可不是k*G这么简单,这是几何意义上的:
S=G+G+G+G+……+G(K个G)
然后把公钥丢出去,私钥留给自己
和RSA差不多啦
重点应该是在于如何求S

1
G(x1,y1),P(x2,y2)

重点来了:核心公式

1
2
x3≡t^2-x1-x2(mod p)
y3≡t(x1-x3)-y1(mod p)

其中

1
2
若P=G 则 t=(3x^2+a)/2y1 
若P≠G 则 t=(y2-y1)/(x2-x1)

故此可以求出公钥S
于是脚本如下:

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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# -*- coding:utf8 -*-
a=16546484
p=15424654874903
def egcd(t, b):
if t == 0:
return (b, 0, 1)
else:
g, y, x = egcd(b % t, t)
return (g, x - (b // t) * y, y)

def modinv(o, m):
g, x, y = egcd(o, m)
if g != 1:
raise Exception('modular inverse does not exist')
else:
return x % m

def ecc_m(x1,y1,x2,y2):
if ((x1 == x2) & (y1 == y2)):
fenzi=3*x1*x1+a
fenmu=2*y1
else:
fenzi = y2 - y1
fenmu = x2 - x1
m=(abs(fenzi) * modinv(abs(fenmu), p)) % p
if ((fenzi >= 0 & fenmu >= 0) | (fenzi < 0 & fenmu < 0)):
return m
else:
return p - m

def ecc_x(x1,x2,m):
result_x = m*m-x1-x2
if result_x>0:
return result_x%p
else:
p1=p
if abs(result_x)>p1:
shang=abs(result_x)/p
p1=shang*p+p
return p1+result_x

def ecc_y(x1,result_x,y1,m):
result_y = m*(x1-result_x)-y1
if result_y>0:
return result_y%p
else:
p1 = p
if abs(result_y) > p1:
shang = abs(result_y) / p
p1 = shang * p + p
return p1 + result_y

def ecc_result_x(x1,y1,x2,y2):
m = ecc_m(x1,y1,x2,y2)
result_x=ecc_x(x1,x2,m)
return result_x

def ecc_result_y(x1,y1,x2,y2):
m = ecc_m(x1,y1,x2,y2)
result_x = ecc_x(x1, x2, m)
result_y=ecc_y(x1, result_x, y1, m)
return result_y

x1=x2=x3=6478678675
y1=y2=5636379357093
n=546767
while(n>0):
x2=ecc_result_x(x1,y1,x2,y2)
y2=ecc_result_y(x1,y1,x3,y2)
x3=x2
n-=1
print x2,y2
result = x2+y2
flag = "XUSTCTF{%s}"%result
print flag

运行后即可得到flag

神秘的压缩包

拿到题目后发现压缩包内容,立刻想到CRC32的爆破
利用github上的爆破工具:
https://github.com/theonlypwner/crc32
但是长度这里是5位的,而工具只针对6位的
可以在这里学习修改方法:
https://github.com/veritas501/hctf_wp/blob/master/misc_level1_big_zip/misc_level1_big_zip.md
爆破即可得到:
password:f~Z-;lapEwF\<0ZkhyAo5
即可解压拿到flag

Jarvis’s encryption system

留坑位,后面研究

影之密码

发现只有0 2 4 8,所以猜测是幂数加密,学习链接:
http://baike.baidu.com/link?url=pk_ook24QZMaSO7eHEqHawLWaswbDfgVzHcGGB3YPtSlat-crmZqmKty9bqaWtr-xiTKcbiW1gNt7ldS03A4NK
提示八位大写字母,又发现有7个0,可以分成8段
脚本如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#coding=utf-8
a=["88421","0122","048","02244","04","0142242","0248","0122"]
# b=["124","01","0118","0118","0212","0114","018","04"]
flag=""
for j in range(0,len(a)):
str = a[j]
list=[]
sum=0
for i in str:
list.append(i)
length = len(list)
for i in range(0,length):
sum+=int(list[i])
flag+=chr(64+sum)
print flag
运行即可得到flag

好多盐

可以看到题目中给出了md5和该md5的盐
剩下的就是强行爆破了
于是脚本如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# -*- coding: utf-8 -*-
import hashlib
result ="{FLAG:%number}%salt"
password =["f09ebdb2bb9f5eb4fbd12aad96e1e929.p5Zg6LtD","6cea25448314ddb70d98708553fc0928.ZwbWnG0j","2629906b029983a7c524114c2dd9cc36.1JE25XOn","2e854eb55586dc58e6758cfed62dd865.ICKTxe5j","7b073411ee21fcaf177972c1a644f403.0wdRCo1W","6795d1be7c63f30935273d9eb32c73e3.EuMN5GaH","d10f5340214309e3cfc00bbc7a2fa718.aOrND9AB","8e0dc02301debcc965ee04c7f5b5188b.uQg6JMcx","4fec71840818d02f0603440466a892c9.XY5QnHmU","ee8f46142f3b5d973a01079f7b47e81c.zMVNlHOr","e4d9e1e85f3880aedb7264054acd1896.TqRhn1Yp","0fd046d8ecddefc66203f6539cac486b.AR5lI2He","f6326f02adaa31a66ed06ceab2948d01.Aax2fIPl","720ba10d446a337d79f1da8926835a49.ZAOYDPR2","06af8bcc454229fe5ca09567a9071e62.hvcECKYs","79f58ca7a81ae2775c2c2b73beff8644.TgFacoR3","46aaa5a7fef5e250a2448a8d1257e9cf.GLYu0NO4","2149ac87790dd0fe1b43f40d527e425a.5Xk2O1sG","d15a36d8be574ac8fe64689c728c268e.aZikhUEy","ff7bced91bd9067834e3ad14cc1464cd.E7UROqXn","8cc0437187caf10e5eda345cb6296252.XPin3mVB","5cfcdca4a9cb2985a0b688406617689e.nsGqoafv","5a7dfa8bc7b5dfbb914c0a78ab2760c6.YC1qZUFR","8061d8f222167fcc66569f6261ddd3cc.wNgQi615","3d8a02528c949df7405f0b48afe4a626.CO2NMusb","70651acbc8bd027529bbcccdbf3b0f14.CAXVjFMd","a9dbe70e83596f2d9210970236bdd535.TL6sjEuK","9ed6ef5780f705ade6845b9ef349eb8f.tJ90ibsz","4b46fac0c41b0c6244523612a6c7ac4a.VTjOSNmw","8141e6ecb4f803426d1db8fbeb5686ef.lh75cdNC","df803949fd13f5f7d7dd8457a673104b.V39sEvYX","19052cc5ef69f90094753c2b3bbcd41d.YwoGExpg","cf8591bdccfaa0cdca652f1d31dbd70f.pJCLui49","66e10e3d4a788c335282f42b92c760a1.NQCZoIhj","94c3ae5bcc04c38053106916f9b99bda.vOktelLQ","e67e88646758e465697c15b1ef164a8d.x0hwJGHj","84d3d828e1a0c14b5b095bedc23269fb.2HVWe9fM","264a9e831c3401c38021ba3844479c3f.Cx4og6IW","ed0343dec184d9d2c30a9b9c1c308356.g2rqmPkT","ad5ba8dc801c37037350578630783d80.pFK2JDT5","3f588bedb704da9448e68fe81e42bca6.4ANDOiau","970c9cf3cad3dfa7926f53ccaae89421.R6ML7Qy8","e0a097b7cceaa7a8949fe039884e4a2d.dul2ynqL","7df505218102c64b1fe4fa5981ddb6fa.jPeoyS57","fd4f6043da1f7d5dca993c946ef6cd7c.6p9CwGaY","5fe6d99b9a2824949279187c246c9c30.OGQ2J57y","135b150ad513a961089bb1c05085a3d9.h0dw1Fro","ad6af4fb623b3c51181a371911667fed.HbQT4dRz","c9fa4b0db317d88e2b10060225e92494.ebVnpMzS","d0deab17d115bd6fdce8592bb3667643.bL5zwgvX","006f0cb3a422716692f143f28eb0d187.NHXg1Fof","ddc125de34da1a6ec0cbe401f147bc8f.GDai9Y0n","be5052053c5a806e8f56ed64e0d67821.40alyH3w","aaf18ac446b8c385c4112c10ae87e7dc.ZJQzuIL0","a2db20a4b7386dc2d8c30bf9a05ceef7.QnpOlPWH","8a4fbc32a3251bb51072d51969ba5d33.rtcbipeq","5e35d2c9675ed811880cea01f268e00f.i1Hbne6h","9da23007699e832f4e9344057c5e0bd3.EtbGpMSW","f09233683d05171420f963fc92764e84.fxHoinEe","4feabf309c5872f3cca7295b3577f2a8.KymkJXqA","9b94da2fa9402a3fdb4ff15b9f3ba4d2.G3Tdr1Pg","b3cd8d6b53702d733ba515dec1d770c5.Y71LJWZz","6a5b3b2526bb7e94209c487585034534.rIwb4oxt","e9728ef776144c25ba0155a0faab2526.e1sOXSb8","d41a5e7a98e28d76dbd183df7e3bcb49.36bedvia","81d5ebfea6aff129cf515d4e0e5f8360.dDG4qTjW"]
n=1000000000
while(n<10000000000):
for j in range(0,66):
salt = password[j][33:]
md5 = password[j][:32]
mingwen = "{FLAG:"+str(n)+"}"+password[j][33:]
miwen = hashlib.md5(mingwen).hexdigest()
if (miwen == md5) :
print mingwen
print password[j]
n=10000000000
break
print n
n+=1

这里建议写多线程,我单线程跑了好久,开着爆破,上课回来也就结束了
得到flag是1234567890

Superexpress

题目本质上是一道仿射加密的题目
可以写出脚本

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
import sys
encrypted ="805eed80cbbccb94c36413275780ec94a857dfec8da8ca94a8c313a8ccf9"
# flag = 'TWCTF{*******CENSORED********}'
list=[]
def str2num(s):
return int(s, 16)

for i in range(0,60,2):
list.append(str2num(encrypted[i:i+2]))

true_a = 0
true_b = 0
for a in range(0,255):
for b in range(0,255):
c1 = (a*ord("T")+b)%251
c2 = (a * ord("W") + b) % 251
c3 = (a * ord("C") + b) % 251
if((c1==list[0])&(c2==list[1])&(c3==list[2])):
true_a = a
true_b = b
break
if ((true_a!=0)&(true_b!=0)):
break
k=0
flag=""
for cishu in range(1,31):
for mingwen in range(33,127):
c = (true_a * mingwen + true_b) % 251
if (c==list[k]):
k+=1
flag+=chr(mingwen)
print flag
break

运行即可

Vigenere

这是一个具有base64块的Vigenere密码,我们选择使用Kasiski测试来检测密钥长度,并且对每个base64块进行详尽的搜索。后在github上搜到一个能用的脚本,修改后即可运行处flag
脚本如下:

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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#!/usr/bin/env python3
import functools
import math
import base64
import string
import sys
import logging
logging.basicConfig(stream=sys.stderr, level=logging.INFO)
log = logging.getLogger()

chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/'
assert len(chars) == 64
def shift(char, key, rev = False):
if not char in chars or key == '?':
return char
if rev:
return chars[(chars.index(char) - chars.index(key)) % len(chars)]
else:
return chars[(chars.index(char) + chars.index(key)) % len(chars)]
def decrypt(encrypted, key):
return base64.b64decode(''.join([shift(c, key[i % len(key)], True) for i, c in enumerate(encrypted)]))

with open('encrypted.txt') as fh:
ciphertext = fh.read().strip()
log.info('encrypted.txt: %s', ciphertext)

def kasiski_test(s, l):
dists = []
for i in range(len(s) - l):
word = s[i : i+l]
j = s[i + l : ].find(word)
if j != -1:
dist = (i+l+j) - i
dists += [ dist ]
dist = functools.reduce(math.gcd, dists)
return dist
dist = kasiski_test(ciphertext, 3)
log.info('estimated length: %d', dist)
assert dist == 12

isascii = lambda s: all([ c < 128 for c in s ]) # for bytes
chunk = lambda s, l: [s[i:i+l] for i in range(0, len(s), l)]
assert dist % 4 == 0
def is_valid_key_block(key, k, restrict=3):
key += 'A' * (4 - len(key))
plaintext = decrypt(ciphertext, key)
for s in chunk(plaintext, 3)[ k :: dist // 4]:
if not isascii(s[ : restrict]):
return False
return True
for k in range(dist // 4):
for x in chars:
for y in chars:
if not is_valid_key_block(x + y, k, restrict=1):
continue
for z in chars:
if not is_valid_key_block(x + y + z, k, restrict=2):
continue
for w in chars:
if is_valid_key_block(x + y + z + w, k):
key = x + y + z + w
plaintext = decrypt(ciphertext, key)
print(k, key, b' '.join(chunk(plaintext, 3)[ k :: dist // 4]))

key = 'shA6I8HUXLFY'
print(key)
print(decrypt(ciphertext, key).decode())

得到flag:TWCTF{C14ss1caL CiPhEr iS v3ry fun}

DSA

根据DSA算法,可以知道当使用相同的k的时候,r也相同,那么如果我们知道两个不同的消息利用相同的r的话,就可以进行攻击了。在这道题中,我们发现时m3和m4的r是相同的。
可以写出攻击脚本

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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
from Crypto.Hash import SHA
import gmpy2
y = int("45bb18f60eb051f9d48218df8cd956330a4ff30af5344f6c9540061d5383292d95c4dfc8ac26ca452e170dc79be15cc6159e037bccf564ef361c18c99e8aeb0bc1acf9c0c35d620d60bb7311f1cf08cfbc34ccaa79ef1dad8a7a6facce86659006d4faf057716857ec7ca604ade2c3d731d6d02f933198d390c3efc3f3ff046f", 16)
p = int("00c0596c3b5e933d3378be3626be315ee70ca6b5b11a519b5523d40e5ba74566e22cc88bfec56aad66918b9b30ad281388f0bbc6b8026b7c8026e91184bee0c8ad10ccf296becfe50505383cb4a954b37cb588672f7c0957b6fdf2fa0538fdad83934a45e4f99d38de57c08a24d00d1cc5d5fbdb73291cd10ce7576890b6ba089b", 16)
q = int("00868f78b8c8500bebf67a58e33c1f539d3570d1bd", 16)
g = int("4cd5e6b66a6eb7e92794e3611f4153cb11af5a08d9d4f8a3f250037291ba5fff3c29a8c37bc4ee5f98ec17f418bc7161016c94c84902e4003a7987f0d8cf6a61c13afd5673caa5fb411508cdb3501bdff73e747925f76586f4079fea12098b3450844a2a9e5d0a99bd865e0570d5197df4a1c9b8018fb99cdce9157b98500179", 16)
f3 = open(r"packet3/message3", 'r')
f4 = open(r"packet4/message4", 'r')
data3 = f3.read()
data4 = f4.read()
sha = SHA.new()
sha.update(data3)
m3 = int(sha.hexdigest(), 16)
sha = SHA.new()
sha.update(data4)
m4 = int(sha.hexdigest(), 16)
print m3, m4
s3 = 0x30EB88E6A4BFB1B16728A974210AE4E41B42677D
s4 = 0x5E10DED084203CCBCEC3356A2CA02FF318FD4123
r = 0x5090DA81FEDE048D706D80E0AC47701E5A9EF1CC
ds = s4 - s3
dm = m4 - m3
k = gmpy2.mul(dm, gmpy2.invert(ds, q))
k = gmpy2.f_mod(k, q)
tmp = gmpy2.mul(k, s3) - m3
x = tmp * gmpy2.invert(r, q)
x = gmpy2.f_mod(x, q)
print int(x)
运行即可拿到flag
[61dctf]bbencode
加密脚本的算法只要将加密的密文按着加密脚本重复下去,所以方式就很容易了:
脚本如下:
# assert len(flag) == 32
def str2num(s):
return int(s.encode('hex'), 16)

def bbencode(n):
a = 0
for i in bin(n)[2:]:
a = a << 1
if (int(i)):
a = a ^ n
if a >> 256:
a = a ^ 0x10000000000000000000000000000000000000000000000000000000000000223L
return a

flag = 61406787709715709430385495960238216763226399960658358000016620560764164045692
for i in range(10000000):
flag = bbencode(flag)
if '666c6167' == str(hex(flag))[2:10]:
print i
print hex(flag)[2:-1].decode('hex')

可以得到flag

Complicated Crypto

这篇文章写的相当详细了
https://www.tuicool.com/articles/YBbmMz2
我就不多啰嗦了

[61dctf]rsappend

题目有点小坑,给的数据相当多
但是后面可以发现,还是一道共模攻击的题,于是只需要2组即可,其他都可以删掉
于是可以写出共模攻击的脚本:

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
34
35
36
37
#coding=utf-8 
import sys

def egcd(a, b):
if a == 0:
return (b, 0, 1)
else:
g, y, x = egcd(b % a, a)
return (g, x - (b // a) * y, y)

def modinv(a, m):
g, x, y = egcd(a, m)
if g != 1:
raise Exception('modular inverse does not exist')
else:
return x % m

def main():
n = 130129008900473203968454456805638875182255844172836031362469765750555629223299054613072677100571707156698316733582683118539756860001556017029333867329591302318262912728008327902112481960175532302595162289611406978353816368008691640641366763939266242207191229240305820321249712345088877729541037319788659353057396178127928848886417880913823432701577855911982710310391664759040416918636673098245499680559140960154217578440590540485803953844560093151975252604098243460784073934982164384904788470380402066708313893480356219937915540825156266934523595689350157227336528136089157698775968997579723271988825396396444999743016035145444220925369592263295741687879468786947998534483539986779457827253891091252408156073413533385415338751818544323853074296042153599429749378847870780593975579477549218822682233583377677693108437331184962345568217859524495625257015837972947971787321584159575618388588687948368216479955807108888453821700067186732627409832722329355336479016104249514839541606562090752437124270651936485389358065775555250883907067083447197860848471728871909151915883316674512739238840179296263390441457949281128267215916340163366686542160467601357340644950755337706786366316621293666173843528346692669268972961669116101104865152273
e1 = 3493354673
e2 = 340864687
c1 = 95302089605615051645253770338205531172677353498946580682786822045513597212422921981567826452072575982096979591435896082106066368909398510427324124083956090397824543655853708684901332136907086372208856759943292176759073194584568350898675282883285945088425893961769183074018286761903249180704401358403273776903672507958464947244563165564687651203497198317095965140433811056890812018746508121991041040929574993486548175817290824525606551459788553765629416110310419007396912225733599205599864440826319234419035248234403040065378375700430311931418759746223148198205862641252459687694589780856855757703678024583642215076094232444641853081607984934672271461513190437757388818064739151861157236855430066735235471068167602037785718403200529481153399754491247323829122718485697100562237822159608309949585990842201041193231738706398444530233533281604482892716292766323711237917277799500317596333142843576977429802405873159965636003943698854699972663575602383960580472190300576561953143218321528070200681456278974433060654128626428761278953024384187213765974659768657721533448706022075747036347982370028705538843276631102928500802573434484354218539824751579164697748967608238067706842975984077663380114254296902060435479795741671231918448537178
c2 = 105918022590727868761989308441554006325741233318901416621101439141134508212362387984949614887131575960019253866892976283979646611794365370050551871112439674346802340152058463892106629344277362169322187627579360245792142005899616101515519718660483000821415412306495286717542069436530262341500852884860324349096274655178057271529986597578695272732947460673640986877589225588415523871081101162696385279491410034057376225511693022693861779342120101749193614060384925056132593068290214170342896671210026723193650534803792328917982049779674425511275821311773130342656939142955431868128759911406827872932920704284125816103225607727270365652734742083302757644298457617564597237089509337896240249999242834787525341715546373108420197569425092674224333823552432226153066667988737348643469923827028254712179077001007265954488404167147591307425224250970874724864947175449960116685682348915647317191880538777148647712260093008241728509225817352093441924045801257015598517963598799676359095235231066752986688784477694024390356904157694178691411759003004184256950519184836209393583431328640341243629167223114681734264945594931213193459079614652400888215324779908031661350565230685273639666615465296133672907093946148188967451042301308884510424218096
s = egcd(e1, e2)
s1 = s[1]
s2 = s[2]
if s1<0:
s1 = - s1
c1 = modinv(c1, n)
elif s2<0:
s2 = - s2
c2 = modinv(c2, n)
m = (pow(c1,s1,n)*pow(c2,s2,n))%n
print hex(m)
if __name__ == '__main__':
sys.setrecursionlimit(1000000)
main()

运行可以得到:

1
0x666c61677b77655f646f5f6374665f746f6765746865725f666f725f66756e7d5c674bef926d37beb619a819f2b21861ebc59a33c396be6d2bc5da331e829827d3e2d518520b9588e60a506f3697e071f7634d4b0952f535e4ccb113131776165273fe16519c322b828220daff8d8303f91f4eb88921b248411679409af9e913071594612e4912c5101610765cc2dafab1a11992121ee7329884c5046c0a73c8acdc9bf61124b8224948cb2c562d7ea545b4e900b0aa0059fadc5547f8c765d43967750f8077e0ef061eb8be88d3815f31b9a5ff3d45694e8016caca4a28e9e10b3bcfccdcc278022770dabd57a499138b2aa0043f8b740ad69a0645019ec99aL

转换后即为flag

[61dctf]rsa

留坑位呀~

[61dctf]cry

留坑位呀~

点击赞赏二维码,您的支持将鼓励我继续创作!
CATALOG
  1. 1. Medium RSA
  2. 2. BrokenPic
  3. 3. hard RSA
  4. 4. very hard RSA
  5. 5. Extremely hard RSA
  6. 6. God Like RSA
  7. 7. 简单ECC概念
  8. 8. 神秘的压缩包
  9. 9. Jarvis’s encryption system
  10. 10. 影之密码
  11. 11. 好多盐
  12. 12. Superexpress
  13. 13. Vigenere
  14. 14. DSA
  15. 15. Complicated Crypto
  16. 16. [61dctf]rsappend
  17. 17. [61dctf]rsa
  18. 18. [61dctf]cry