老大终于对队伍里的密码手下手了(不是。。
老大召集队伍里的密码手一起刷crypto hack,一起上大分。为了更好的记录本次的学习成果决定对学习当中遇到的问题和收获做一些整理也算是对最近焦虑和压抑的科研生活做个调剂,而且crypto hack这个平台在网上公开的wp比较少,大家一起刷一波也能整理出不少wp供其他同学学习和参考,也算是公者千古了(不是。。
给自己点小鼓励:你要做冲出的黑马 而不是坠落的星星。
Signing Server (60pt)
题目描述
题目源代码
#!/usr/bin/env python3
from Crypto.Util.number import bytes_to_long, long_to_bytes
from utils import listener
class Challenge():
def __init__(self):
self.before_input = "Welcome to my signing server. You can get_pubkey, get_secret, or sign.\n"
def challenge(self, your_input):
if not 'option' in your_input:
return {"error": "You must send an option to this server"}
elif your_input['option'] == 'get_pubkey':
return {"N": hex(N), "e": hex(E) }
elif your_input['option'] == 'get_secret':
secret = bytes_to_long(SECRET_MESSAGE)
return {"secret": hex(pow(secret, E, N)) }
elif your_input['option'] == 'sign':
msg = int(your_input['msg'], 16)
return {"signature": hex(pow(msg, D, N)) }
else:
return {"error": "Invalid option"}
listener.start_server(port=13374)
题目分析
奶奶滴,60分的题目咋这么水了。。。
首先,程序支持我们进行3种操作:
1.获得公钥(其实没用)
2.获得flag的密文
3.输入一个meg获得它的RSA数字签名
根据RSA的基础和数字签名的基础:
s
e
c
r
e
t
=
f
l
a
g
E
m
o
d
(
N
)
secret=flag^E mod (N)
secret=flagEmod(N)
s
i
g
n
=
m
s
g
D
m
o
d
(
N
)
sign=msg^Dmod(N)
sign=msgDmod(N)
因此,首先我们可以调用加密函数,获得flag对应的secret,然后把secret作为msg输入获得它的数字签名,这个签名的过程也就相当于对密文进行解密,因此将获得十六进制抓化成ascii获得flag
具体操作
注意输入json格式
对上述信息进行解密
Let’s Decrypt (80pt)
题目描述
题目源代码
#!/usr/bin/env python3
import re
from Crypto.Hash import SHA256
from Crypto.Util.number import bytes_to_long, long_to_bytes
from utils import listener
from pkcs1 import emsa_pkcs1_v15
# from params import N, E, D
FLAG = "crypto{?????????????????????????????????}"
MSG = 'We are hyperreality and Jack and we own CryptoHack.org'
DIGEST = emsa_pkcs1_v15.encode(MSG.encode(), 256)
SIGNATURE = pow(bytes_to_long(DIGEST), D, N)
class Challenge():
def __init__(self):
self.before_input = "This server validates domain ownership with RSA signatures. Present your message and public key, and if the signature matches ours, you must own the domain.\n"
def challenge(self, your_input):
if not 'option' in your_input:
return {"error": "You must send an option to this server"}
elif your_input['option'] == 'get_signature':
return {
"N": hex(N),
"e": hex(E),
"signature": hex(SIGNATURE)
}
elif your_input['option'] == 'verify':
msg = your_input['msg']
n = int(your_input['N'], 16)
e = int(your_input['e'], 16)
digest = emsa_pkcs1_v15.encode(msg.encode(), 256)
calculated_digest = pow(SIGNATURE, e, n)
if bytes_to_long(digest) == calculated_digest:
r = re.match(r'^I am Mallory.*own CryptoHack.org$', msg)
if r:
return {"msg": f"Congratulations, here's a secret: {FLAG}"}
else:
return {"msg": f"Ownership verified."}
else:
return {"error": "Invalid signature"}
else:
return {"error": "Invalid option"}
listener.start_server(port=13391)
题目分析
感谢队内KBU师傅的帮助,一开始我们俩都把这个题目想复杂了(其实是我误导了师傅,一直在考虑PKCS的那个cve,其实这个题目简单的很多
题目首先对MSG这句话进行签名得到SIGNATURE
我们的目标是构造一个msg(题目要求msg必须含有I am Mallory.*own CryptoHack.org这句话),传入e,n进行签名,要求是与题目给出的签名是相同的。
具体操作
首先,调用get_signature函数获得题目中的签名
其实这里的n,e都是安全,没法利用。
然后,我们本地跑一下自己构造msg的digest
from pkcs1 import emsa_pkcs1_v15
msg="I am Mallory.*own CryptoHack.org"
digest = emsa_pkcs1_v15.encode(msg.encode(), 256)
print(digest.hex())
'''0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff003021300906052b0e03021a05000414f21168b397a142c7a3a7a635f5eef70f4bc9f30b'''
拿到flag的条件是:
s
i
g
n
a
t
u
r
e
e
m
o
d
n
=
d
i
g
e
s
t
signature^e \ mod\ n =digest
signaturee mod n=digest
现在我们已知
s
i
g
n
a
t
u
r
e
signature
signature和
d
i
g
e
s
t
digest
digest题目需要我们构造
n
,
e
n,e
n,e满足上边的等式。这时,我们令e=1,得到
s
i
g
n
a
t
u
r
e
m
o
d
n
=
d
i
g
e
s
t
signature\ mod \ n=digest
signature mod n=digest,即
s
i
g
n
a
t
u
r
e
=
k
n
+
d
i
g
e
s
t
signature=kn+digest
signature=kn+digest,k=1时,
n
=
s
i
g
n
a
t
u
r
e
−
d
i
g
e
s
t
n=signature-digest
n=signature−digest,我们构造
n
,
e
n,e
n,e即可得到答案。
传入拿flag