发布时间锁定的负责任披露
我们此前曾宣布将进行时间锁定的负责任披露,该披露已于2023年2月23日00:00(CEST)起可访问。先前加密的报告现可在timevault.drand.love解密。
让我们详细解释这一发现。该问题是在我们审计Protocol Labs的时间锁加密时发现的。tlock是提供基于时间加密的命令行工具,这是一个Go程序,实现了tle命令行工具,提供与网站timevault.drand.love类似的功能。例如,要加密一个7年11个月又1天后的文件,可以使用以下命令:
|
|
我们注意到在加密文件中,字符串"tlock"后的值是文件可访问时的Drand轮次数。当前轮次数可在此处查询。因此,程序将持续时间7y11m1d转换为轮次数81988175。我们发现,若向tlock提供过于遥远的未来年份作为参数,会导致加密针对Drand的第1轮,从而使明文可立即访问。以下是该问题的示例:
|
|
在此示例中,轮次数被设置为1。问题在于将持续时间转换为轮次数的过程中。函数parseDuration提取年份数字并将其从当前日期中减去:
|
|
AddDate函数属于Go标准库中的time包,提供日期相关功能。AddDate调用的Date函数中存在整数溢出问题:年份被转换为天数,然后乘以每天秒数,未进行任何检查。若年份数字过大,会导致错误的负结果。以下是该问题的示例:https://go.dev/play/p/Nz3aFaoA2iF。在tlock中,函数RoundNumber(计算与日期关联的轮次数)对此类负结果返回1。
若攻击者能控制输入日期,并诱使服务器加密未来的内容,而结果可立即访问,这可能构成问题。
该问题已向Protocol Labs报告,随后通过提交96b5251ca25e105d241e46bcca30837fc4dcf150在tlock代码中修复。Go语言中已开设问题并提出了补丁,但在当前Go版本(1.20)中仍存在此问题,因此若您的程序在敏感操作中依赖Date函数,请务必小心。
我们很高兴有机会时间锁定加密并披露影响时间锁加密本身的漏洞发现!