青衿之志,履践致远

一些CTF比赛中用到的RSA题目脚本

一些CTF比赛中用到的RSA题目脚本

e,p,q,c

import gmpy2 as gp
import binascii
p =  gp.mpz()
q =  gp.mpz()
e =  gp.mpz()
c =  gp.mpz()
n = p*q
phi = (p-1) * (q-1)
d = gp.invert(e, phi)
m = pow(c, d, n)
print(m)

e,n,dp,c

import gmpy2 as gp

e = 
n = gp.mpz()
dp = gp.mpz()
c = gp.mpz()

for x in range(1, e):
    if(e*dp%x==1):
        p=(e*dp-1)//x+1
        if(n%p!=0):
            continue
        q=n//p
        phin=(p-1)*(q-1)
        d=gp.invert(e, phin)
        m=gp.powmod(c, d, n)
        if(len(hex(m)[2:])%2==1):
            continue
        print('--------------')
        print(m)
        print(hex(m)[2:])
        print(bytes.fromhex(hex(m)[2:]))

p,q,dp,dq,c

import gmpy2 as gp

p = gp.mpz()
q = gp.mpz()
dp = gp.mpz()
dq = gp.mpz()
c = gp.mpz()

n = p*q
phin = (p-1)*(q-1)
dd = gp.gcd(p-1, q-1)
d=(dp-dq)//dd * gp.invert((q-1)//dd, (p-1)//dd) * (q-1) +dq
print(d)

m = gp.powmod(c, d, n)
print('-------------------')
print(m)
print(hex(m)[2:])

n,e(e长度较大)

import  RSAwienerHacker
n=
e=
d =  RSAwienerHacker.hack_RSA(e,n)
if d:
    print(d)
import hashlib
flag = "flag{" + hashlib.md5(hex(d)).hexdigest() + "}"
print(flag)

p,q,e求d

import gmpy2
from Crypto.Util import number
p = 473398607161
q = 4511491
e = 17
d = gmpy2.invert(e,(p-1)*(q-1))
print(d)

n,e,d求p,q

from gmpy2 import next_prime, gcd
def Factorize(n, e, d):
    g = 2
    while True:
        k = e * d - 1
        while not k & 1:
            k //= 2
            p = int(gcd(pow(g, k, n) - 1, n)) % n
            if p > 1:
                return (p, n // p)
        g = int(next_prime(g))
if __name__ == "__main__":
    n = 0x75be564267f8bf6c2038dd0cadfeecbc3158acfc27e679dd0bdb0db0e90bd5198a0a7edc0626f357a2d75f3c37ede045b7f7ca6bda79e5bf6fc0aea0aa7beda587388599d2b77b538fc3e666784493ffaf731e2ae232e8e9e9f9f2a4df25c19b7680f5bf6c485bd87923f01c17d8ec35438772c28e361774e6e7681d67ecbe19
    e = 0x14b367bf01efd4dc667b8e62975479c612c96e78f7f1f55242b2973c882ddcb33a65c52174d8ae1273764ce429054ea3f2fdc38ff205443c92ef4198739f05aa11fc10d3fc6ff30c8f5f05a04f43e3d8fc9bfffe916b2e0360560a162729e91b7775bda70177e0f875626e0a81bd4eacea9948b02232a82659f8d9aa9b4c754f
    d = 105446909057629013379692394355251350740773777593653963988108428818399001716079
    print(Factorize(n, e, d))

共模攻击(n,m相同,c,e不同)

from libnum import n2s,s2n
from gmpy2 import invert
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():
  n = 
  c1 = 
  c2 = 
  e1 = 
  e2 = 
  s = egcd(e1, e2)
  s1 = s[1]
  s2 = s[2]
  if s1<0:
    s1 = - s1
    c1 = invert(c1, n)
  elif s2<0:
    s2 = - s2
    c2 = invert(c2, n)

  m = pow(c1,s1,n)*pow(c2,s2,n) % n
  print(hex(m))

if __name__ == '__main__':
  main()

共模攻击(分解e1e2并爆破判别)

n= 
c1= 
c2= 
e1e2= 
 
import libnum
import gmpy2
 
def rsa_gong_N_def(e1,e2,c1,c2,n):  #共模攻击函数
    e1, e2, c1, c2, n=int(e1),int(e2),int(c1),int(c2),int(n)
    print("e1,e2:",e1,e2)
    s = gmpy2.gcdext(e1, e2)
    print("mpz:",s)
    s1 = s[1]
    s2 = s[2]
    if s1 < 0:
        s1 = - s1
        c1 = gmpy2.invert(c1, n)
    elif s2 < 0:
        s2 = - s2
        c2 = gmpy2.invert(c2, n)
    m = (pow(c1,s1,n) * pow(c2 ,s2 ,n)) % n
    return int(m)
 
def de(c, e, n): #因为此时的m不是真正的m,而是m^k,所以对m^k进行爆破
    k = 0
    while k<1000: #指定k小于1000
        mk = c + n*k
        flag, true1 = gmpy2.iroot(mk, e)  #返回的第一个数值为开方数,第二个数值为布尔型,可整除为true,可自行测试
        if True == true1:
            # print(libnum.n2s(int(flag)))
            return flag
        k += 1
for e1 in range(2,e1e2):
    if e1e2%e1==0:         #爆破可整除的e
        e2=e1e2//e1
        c=rsa_gong_N_def(e1, e2, c1, c2, n)
        e=gmpy2.gcd(e1,e2)
        m1=de(c, e, n)
        if m1:  #指定输出m1
            print(libnum.n2s(int(m1)))

e,m相同,存在两个n有公约数

import gmpy2
from gmpy2 import invert, iroot
import gmpy2 as gp
from libnum import xgcd, invmod

n=[,,,,,,,,,,,,,,,,,,,]
for i in n:
    for j in n:
        if (i<>j):
            pub_p=gmpy2.gcdext(i,j)
            if (pub_p[0]<>1)&(i>j):
                print i
                print j
                print pub_p[0]
                a=i,p=pub_p[0]
q=a/p
p =  gp.mpz()
q =  gp.mpz()
e =  gp.mpz()
c =  gp.mpz()
n = p*q
phi = (p-1) * (q-1)
d = gp.invert(e, phi)
m = pow(c, d, n)
print(hex(m))

根据enc文件,p,q,e求d和key

import gmpy2
import rsa

p = 285960468890451637935629440372639283459
q = 304008741604601924494328155975272418463
e = 65537
n = p * q

d = gmpy2.invert(e,(q-1)*(p-1))
print(d)

d = 81176168860169991027846870170527607562179635470395365333547868786951080991441

key = rsa.PrivateKey(n,e,d,p,q)
print(key)

with open("flag.enc","rb") as f:
	print(rsa.decrypt(f.read(),key).decode())

根据pem文件解密

RSA public key encryption and decryption

or 用kali跑openssl

RSA解密-提供enc和pem文件类

e=1

import binascii
import gmpy2
N_hex=0x180be86dc898a3c3a710e52b31de460f8f350610bf63e6b2203c08fddad44601d96eb454a34dab7684589bc32b19eb27cffff8c07179e349ddb62898ae896f8c681796052ae1598bd41f35491175c9b60ae2260d0d4ebac05b4b6f2677a7609c2fe6194fe7b63841cec632e3a2f55d0cb09df08eacea34394ad473577dea5131552b0b30efac31c59087bfe603d2b13bed7d14967bfd489157aa01b14b4e1bd08d9b92ec0c319aeb8fedd535c56770aac95247d116d59cae2f99c3b51f43093fd39c10f93830c1ece75ee37e5fcdc5b174052eccadcadeda2f1b3a4a87184041d5c1a6a0b2eeaa3c3a1227bc27e130e67ac397b375ffe7c873e9b1c649812edcd
e_hex=0x1
c_hex=0x4963654354467b66616c6c735f61706172745f736f5f656173696c795f616e645f7265617373656d626c65645f736f5f63727564656c797d

c_hex = gmpy2.mpz(c_hex)
N_hex = gmpy2.mpz(N_hex)

i = 0
while i<10:
    m_hex = hex(c_hex + gmpy2.mpz(hex(i))*N_hex)
    print(m_hex[2:])
    try:
        print(binascii.a2b_hex(m_hex[2:]).decode("utf8"))
    except binascii.Error as e:
        print("位数非偶数,跳过...")
    i += 1

e=2

import gmpy
import string
from Crypto.PublicKey import RSA

# 读取公钥参数
with open('./tmp/pubkey.pem', 'r') as f:
    key = RSA.importKey(f)
    N = key.n
    e = key.e
    
p = 275127860351348928173285174381581152299
q = 319576316814478949870590164193048041239
with open('./tmp/flag.enc', 'r') as f:
    cipher = f.read().encode('hex')
    cipher = string.atoi(cipher, base=16)
    # print(cipher)

# 计算yp和yq
yp = gmpy.invert(p,q)
yq = gmpy.invert(q,p)

# 计算mp和mq
mp = pow(cipher, (p + 1) / 4, p)
mq = pow(cipher, (q + 1) / 4, q)

# 计算a,b,c,d
a = (yp * p * mq + yq * q * mp) % N
b = N - int(a)
c = (yp * p * mq - yq * 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'))

e=3

import gmpy2
from Crypto.PublicKey import RSA

public_key = "./tmp/pubkey.pem"
cipher_file = "./tmp/flag.enc"

#读入公钥
with open(public_key, "r") as f:
    key = RSA.importKey(f)
    n = key.n
    e = key.e

#读入密文
with open(cipher_file, "r") as f:
    cipher = f.read().encode("hex")
    cipher = int(cipher, 16)
    #print(cipher)

#破解密文
def get_flag():
    i = 0
    while True:
        if(gmpy2.iroot(cipher+i*n, 3)[1] == True):
            flag_bin = int(gmpy2.iroot(cipher+x*n, 3)[0])
            flag = hex(flag_bin)[2:-1].decode("hex")
            print(flag) 
            break
        i += 1

def get_flag_for():
    for x in xrange(118600000, 118720000):
        if(gmpy2.iroot(cipher+x*n, 3)[1] == 1):
            flag_bin = int(gmpy2.iroot(cipher+x*n, 3)[0])
            flag = hex(flag_bin)[2:-1].decode("hex")
            print(flag)
            break 

if __name__ == "__main__":
    get_flag_for()
    #get_flag()

 

工具

参考文章

个人收集的RSA常用脚本

常见的RSA套路脚本

共模攻击原理详解

gmpy2常见函数使用

 

添加新评论