R3CTF2024 WP
Crypto
R0System
考点:代码审计 ECDH
打开代码后有两个小系统,看一下功能
然后再看一下登录之后有哪些功能
其实到这里就可以发现一个非常明显的漏洞点了, 重置密码,但是对用户名没有任何限制,这就导致任何用户,可以重置任何用户的密码
这是泄露的内容,看到Alice和Bob,两个人在传输信息,并且涉及到公钥的交换,其实大体可以确定使用了非对称加密,进行密钥交换,既然是Alice发给Bob的消息,Alice用Bob的公钥进行加密,Bob想要解密必然需要使用自己的私钥进行解密,所以我们的目标是获得Bob的私钥
这里是进行交换密钥的地方,逻辑比较简单
ecdhs是ECDH类的一个对象,调用A用户的该方法,与B的公钥进行交换,就可以得到AB之间的共享密钥
这样发给B之后,B只需要用自己的该方法,传入A的公钥进行交换,就能得到AB之间的共享密钥进行解密
共享密钥生成流程图大概如下:
那么获取B的私钥是我们当前需要完成的,途径也很明确,登录上B的账号 直接让系统返回
步骤:
注册一个普通用户01
登录01
修改Bob的密码
退出01
登录Bob
获取私钥
拿到B的私钥后,我们需要恢复共享密钥是什么,这个在本地直接调用给出的代码就好,不过要仔细观察系统的传值形式
注册普通用户
重置Bob的密码
登录Bob拿私钥
拿泄露数据
因为可以看到flag的加密方式就是用共享密钥做了一个AES的简单加密
下面本地恢复共享密钥
首先可以发现exchange_key传参的内容是一个二元组,但是我们获得的泄露的公钥信息只是一个长字符串,所以需要转换成二元组,同时题目已经给出我们转换的方法了
exp:
from hashlib import md5
from utils import * #注意一定要在同文件夹下导包直接用给出的代码
B_private_key = 0xef7c7923ef85988c24c6f66c6799ccb285691ca9cbc0c4dfd259d84e6b4a2f90 #这是十六进制格式的
A_pub = 'e7e620bb5a43a7ac3a78f908f6e1f702fe4d9176adfe3e1efa22df1d636aa7ab08a32839893d6ed323aa01eefb2fc7393250299252ba96339f43cb40c658f28c' #这个因为需要转化成二元组 所以是字符串
print(b2p(bytes.fromhex(A_pub)))
print(p2b(b2p(bytes.fromhex(A_pub))).hex())
#字符串转化为二元组
A_pub_ = b2p(bytes.fromhex(A_pub))
# pub_key =(85971966356924244980831307020457178590563197663408196712967537635077016642444, 79000431020590387084280106635416454953038752073893771961864570482154499521525)
class ECDH:
def __init__(self):
self.curve = Curve()
self.private_key = B_private_key #这是十六进制格式的
self.public_key = self.curve.mul(self.private_key, self.curve.G) #根据私钥会自动生成公钥
#进行密钥交换合成
def exchange_key(self,others_publickey):
print(self.public_key)
return md5(str(self.curve.mul(self.private_key,others_publickey)).encode()).digest()
f = ECDH() #用户B和A进行交换
print("flag",f.exchange_key(A_pub_).hex()) #注意最后的格式 给出hex 作为AES的key
拿下:
R1System
考点:代码审计 ECDH
首先要说一下 这个题非了,R2是他的修复版
可以发现 开始的时候题目先自己注册了Alice的账号 那Bob呢
这也就是说 如果没有用户登录,Bob是不会注册的
所以我们能不能先直接注册一个Bob的账号
答案是可以的,因为这个限制只限制了Alice的账号不能注册 这也是非的点
这样先别登录 直接注册一个Bob的账号
拿到和R0的信息 相同的解法 就不赘述了
以上就是赛时做出来的题目,其他的期待复现见!