[CISCN 2023 初赛]badkey

本文描述了一道网络安全挑战赛中的解题过程,涉及SHA256哈希函数的爆破和RSA公钥密码系统的漏洞利用。参赛者需通过破解给定的PoW并找到满足特定条件的RSA密钥对来获取旗子。
摘要由CSDN通过智能技术生成

目录

1.题目

2.分析

3.解题

4.参考

1.题目

题目据来源:NSSCTF

from Crypto.Util.number import *
from Crypto.PublicKey import RSA
from hashlib import sha256
import random, os, signal, string

def proof_of_work():
    random.seed(os.urandom(8))
    proof = ''.join([random.choice(string.ascii_letters+string.digits) for _ in range(20)])
    _hexdigest = sha256(proof.encode()).hexdigest()
    print(f"sha256(XXXX+{proof[4:]}) == {_hexdigest}")
    print('Give me XXXX: ')
    x = input()
    if len(x) != 4 or sha256(x.encode()+proof[4:].encode()).hexdigest() != _hexdigest:
        print('Wrong PoW')
        return False
    return True

if not proof_of_work():
    exit(1)
    
signal.alarm(10)
print("Give me a bad RSA keypair.")

try:
    p = int(input('p = '))
    q = int(input('q = '))
    assert p > 0
    assert q > 0
    assert p != q
    assert p.bit_length() == 512
    assert q.bit_length() == 512
    assert isPrime(p)
    assert isPrime(q)
    n = p * q
    e = 65537
    assert p % e != 1
    assert q % e != 1
    d = inverse(e, (p-1)*(q-1))
except:
    print("Invalid params")
    exit(2)

try:
    key = RSA.construct([n,e,d,p,q])
    print("This is not a bad RSA keypair.")
    exit(3)
except KeyboardInterrupt:
    print("Hacker detected.")
    exit(4)
except ValueError:
    print("How could this happen?")
    from secret import flag
    print(flag)

2.分析

分为两个流程,第一步sha256爆破四个字节,第二步是审计源码后进行相应攻击

3.解题

连接远程机:

nc node4.anna.nssctf.cn 28552

连接后有如下信息(每一次都不一样):

sha256(XXXX+EFgCDcZULevC7j4e) == fe78a1e8958f40ebe5e79117b578a7b7bee990ddab502be2b4d4a55065dd18e5
Give me XXXX:

第一步:

sha256爆破


from itertools import product
import hashlib


table = [chr(i) for i in range(48, 127)]
m = b'EFgCDcZULevC7j4e'
proof = 'fe78a1e8958f40ebe5e79117b578a7b7bee990ddab502be2b4d4a55065dd18e5'
print('-------start---------')

for i in product(table, table, table, table):
    t = ''.join(i)
    t = t.encode()
    t = t + m
    sh = hashlib.sha256(t)
    if(sh.hexdigest() == proof):
        print(''.join(i))
        break

得到:

AhzE

提交后得到:

sha256(XXXX+EFgCDcZULevC7j4e) == fe78a1e8958f40ebe5e79117b578a7b7bee990ddab502be2b4d4a55065dd18e5
Give me XXXX:
AhzE
Give me a bad RSA keypair.
p =

第二步:

源码审计:

源码链接

根据一些大佬的分析,有以下几种使得rsa raise ValueError("Invalid RSA condition")的方法:

最终我们看到这一行:

if Integer(n).gcd(d) != 1:
    raise ValueError("RSA private exponent is not coprime to modulus")

所以我们尝试在得到p、q的时候产生这样的结果

推理过程:

首先我们设:

d =m\cdot p

因为:

e \cdot d = e\cdot m\cdot p \equiv 1 mod \ phi

所以:

e \cdot d = e\cdot m + e\cdot m\cdot (p-1) \ \equiv 1 mod \ (p-1)

所以:

e\cdot m \equiv 1\ mod\ (p-1)

m = inv(e, p-1)

在下式中我们整理一下:

e\cdot d = e\cdot m \cdot p = k \cdot (p-1)\cdot (q-1) + 1

化简得到:

q = \dfrac{e\cdot m \cdot p - 1}{(p - 1) \cdot k} + 1

注意经验来说,k的范围是在(1, e+1)之间的,我们可以通过爆破得到一组p、q

具体爆破代码:

e = 65537
while True:
    p = getPrime(512)
    k1 = inverse(e, p - 1)
    t = (e * k1 * p - 1) // (p - 1)
    for k2 in range(1, e + 1):
        if t % k2 == 0:
            q = t // k2 + 1
            if isPrime(q) and q.bit_length() == 512:
                print(p, q)
                exit()

4.参考

文章1

文章2

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值