【无标题】

1[LitCTF 2023]梦想是红色的 (初级)

 2[BJDCTF 2020]base??

 dict的意思是字典,再结合题目,base,可能是base的字典,但是于base64字典不同

可以用给的字典替换base64的字典

my_dict={0: 'J', 1: 'K', 2: 'L', 3: 'M', 4: 'N', 5: 'O', 6: 'x', 7: 'y', 8: 'U', 9: 'V', 10: 'z', 11: 'A', 12: 'B', 13: 'C', 14: 'D', 15: 'E', 16: 'F', 17: 'G', 18: 'H', 19: '7', 20: '8', 21: '9', 22: 'P', 23: 'Q', 24: 'I', 25: 'a', 26: 'b', 27: 'c', 28: 'd', 29: 'e', 30: 'f', 31: 'g', 32: 'h', 33: 'i', 34: 'j', 35: 'k', 36: 'l', 37: 'm', 38: 'W', 39: 'X', 40: 'Y', 41: 'Z', 42: '0', 43: '1', 44: '2', 45: '3', 46: '4', 47: '5', 48: '6', 49: 'R', 50: 'S', 51: 'T', 52: 'n', 53: 'o', 54: 'p', 55: 'q', 56: 'r', 57: 's', 58: 't', 59: 'u', 60: 'v', 61: 'w', 62: '+', 63: '/', 64: '='}
 
keys=''
for key in my_dict:
    keys+=my_dict[key]
print("keys=",keys)
string1=keys[:64]
print("string1=",string1)
import base64
import string
str1='FlZNfnF6Qol6e9w17WwQQoGYBQCgIkGTa9w3IQKw'
 
string2='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'##标准的 base64 字符串 string2
print(base64.b64decode(str1.translate(str.maketrans(string1,string2))))
print("映射",(str.maketrans(string1,string2)))
print("映射2",(str1.translate(str.maketrans(string1,string2))))
'''
`str.maketrans(string1, string2)` 方法用于创建一个映射表,其中 `string1` 是原始字符集,`string2` 是目标字符集。这个方法返回一个映射表,该表可以用于 `str.translate()` 方法来进行字符替换。
这里的映射原理是将 `string1` 中的每个字符映射到 `string2` 中的对应位置的字符上,实现一一对应的替换关系。具体来说,如果 `string1` 和 `string2` 的长度不同,那么将会以较短的字符串长度为准,多余的字符将被忽略。
举个简单的例子:
假设有两个字符串 `string1 = "ABC"` 和 `string2 = "XYZ"`,那么映射关系就是:
- 将字符 `'A'` 替换为 `'X'`
- 将字符 `'B'` 替换为 `'Y'`
- 将字符 `'C'` 替换为 `'Z'`
如果我们使用 `str.maketrans(string1, string2)`,它将返回一个映射表,该表可以将字符串中的 `'A'` 替换为 `'X'`,`'B'` 替换为 `'Y'`,`'C'` 替换为 `'Z'`。
这个映射表可以用于 `str.translate()` 方法,用来对字符串进行替换操作,实现自定义的字符映射关系。
'''

my_dict是一个字典,keys初始为空字符,然后通过一个循环遍历‘my_dict’中的键,并将每个键对应的值添加到 keys 中,形成一个字符串。

keys 变量包含了通过 my_dict 字典中的值构建的字符串,取了 keys 字符串的前64个字符并将其赋值给 string1 变量。

导入了 Python 的内置库 base64string

base64 库用于处理 Base64 编码,而 string 库包含了标准的 ASCII 字符串。

定义了两个字符串 str1string2str1 是一个 Base64 编码的字符串,string2 是标准的 Base64 字符串,它包含了字符集 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"。

3.[SWPUCTF 2021 新生赛]traditional

首先,让我们先了解一下八卦与二进制的对应关系

根据二进制数的规定:有,用1表示;无,用0表示。我们可以得出八卦各卦阳爻和阴爻的二进制数。下面我们写出八卦各卦阳爻的二进制数(即有阳爻为1,无阳爻为0):

          坤:黑黑黑,卦符阴阴阴,二进制数为000

          艮:黑黑白,卦符阴阴阳,二进制数为001

          坎:黑白黑,卦符阴阳阴,二进制数为010

          巽:黑黑白,卦符阴阳阳,二进制数为011

          震:白黑黑,卦符阳阴阴,二进制数为100

          离:白黑白,卦符阳阴阳,二进制数为101

          兑:白白黑,卦符阳阳阴,二进制数为110

          乾:白白白,卦符阳阳阳,二进制数为111

即字典为,dict = {'乾':'111','巽':'110','离':'101','艮':'100','兑':'011','坎':'010','震':'001','坤':'000'}

需要把八卦序列转换为ASCII字符串

dict = {'乾':'111','巽':'110','离':'101','艮':'100','兑':'011','坎':'010','震':'001','坤':'000'} #替换字典
c= '震坤艮 震艮震 坤巽坤 坤巽震 震巽兑 震艮震 震离艮 震离艮'  #给定的八卦序列
t=c.split(' ')  #split方法用于拆分字符串并将其存储在列表中。内置方法返回字符串中的单词列表,使用“分隔符” 作为分隔符字符串
f=''
for i in range(len(t)):
    s = ''
    for j in range(len(t[i])):
        k=t[i][j]
        a=dict[k]  #找到第i组每个八卦对应的二进制
        s+=a  #将第i组所有八卦对应的二进制相加  
    ch=chr(int(s,2))  #int(s,2)将二进制转化为十进制,chr()将该值对应到ASCII字符
    f+=ch
print(f)

代码创建了一个字典 dict,将每个八卦对应的二进制编码存储起来。

然后,代码将给定的八卦序列拆分为单个八卦,并对每个八卦进行遍历。在遍历的过程中,找到每个八卦对应的二进制编码,并将它们相加起来。

接着,使用 int(s, 2) 将二进制字符串转换为十进制整数,然后使用 chr() 函数将其转换为相应的 ASCII 字符。

最后,将所有字符组合起来形成最终的 ASCII 字符串。

返回:Da01sall

4. [LitCTF 2023]Hex?Hex!(初级)

通过ASCII16进制解码就可以得到flag

在Python中,可以使用内置函数hex()int()实现十进制与十六进制的转换。

使用hex()函数可以将十进制数转换为十六进制。该函数接受一个十进制整数作为输入,返回对应的十六进制字符串。

decimal = 666 #十进制数
hexadecimal = hex(decimal) #十进制转换为十六进制
print(hexadecimal)   #输出十六进制

输出

使用int()函数可以将十六进制数转换为十进制。该函数接受一个十六进制字符串作为输入,返回对应的十进制整数。

hexadecimal = "0x29a"
decimal = int(hexadecimal, 16)
print(decimal) # 输出:666

5.[SWPUCTF 2021 新生赛]crypto2

from gmpy2 import *
from Crypto.Util.number import *



flag  = '***************'

p = getPrime(512)
q = getPrime(512)
m1 = bytes_to_long(bytes(flag.encode()))


n = p*q
e1 = getPrime(32)
e2 = getPrime(32)
print()

flag1 = pow(m1,e1,n)
flag2 = pow(m1,e2,n)
print('flag1= '+str(flag1))
print('flag2= '+str(flag2))
print('e1= ' +str(e1))
print('e2= '+str(e2))
print('n= '+str(n))


#flag1= 100156221476910922393504870369139942732039899485715044553913743347065883159136513788649486841774544271396690778274591792200052614669235485675534653358596366535073802301361391007325520975043321423979924560272762579823233787671688669418622502663507796640233829689484044539829008058686075845762979657345727814280
#flag2= 86203582128388484129915298832227259690596162850520078142152482846864345432564143608324463705492416009896246993950991615005717737886323630334871790740288140033046061512799892371429864110237909925611745163785768204802056985016447086450491884472899152778839120484475953828199840871689380584162839244393022471075
#e1= 3247473589
#e2= 3698409173
#n= 103606706829811720151309965777670519601112877713318435398103278099344725459597221064867089950867125892545997503531556048610968847926307322033117328614701432100084574953706259773711412853364463950703468142791390129671097834871371125741564434710151190962389213898270025272913761067078391308880995594218009110313

源码分析:

一个rsa的加密流程。

引用了两个库gmpy2和Crypto.Util.number。

p和q是随机生成的两个512位数,计算了n。生成32位的随机素数e1,e2,作为RSA加密算法的公钥。最后,将明文 flag 使用 bytes_to_long() 函数转换为长整数 m1,然后分别使用不同的公钥指数 e1 和 e2 对其进行 RSA 加密,得到了密文 flag1 和 flag2。

pow函数是通常用于快速计算模幂。

flag1 = pow(m1,e1,n)

flag2 = pow(m1,e2,n)

先计算m1的e1次方,在对m1的e1次方对n取模。

而m1= bytes_to_long(bytes(flag.encode()))

bytes_to_long() 函数是 Crypto.Util.number 模块中的函数,用于将字节表示的数据转换为长整数表示。

m1就是将flag转换的字符串。

所以要求flag就先求m1,而我们已经知道了flag1,flag2,e1,e2,n。

我们拥有两个使用相同模数n但不同公钥指数加密的密文flag1,flag2。可以使用RSA 的共模攻击(CRT 攻击)。通过扩展欧几里得算法(Extended Euclidean Algorithm),我们可以计算出一个系数,使得两个公钥指数的线性组合等于 1。然后,我们使用这个系数将两个密文解密并恢复出原始明文。

代码脚本:

from gmpy2 import *
from Crypto.Util.number import *
from gmpy2 import gmpy2

flag1 = 100156221476910922393504870369139942732039899485715044553913743347065883159136513788649486841774544271396690778274591792200052614669235485675534653358596366535073802301361391007325520975043321423979924560272762579823233787671688669418622502663507796640233829689484044539829008058686075845762979657345727814280
flag2 = 86203582128388484129915298832227259690596162850520078142152482846864345432564143608324463705492416009896246993950991615005717737886323630334871790740288140033046061512799892371429864110237909925611745163785768204802056985016447086450491884472899152778839120484475953828199840871689380584162839244393022471075
e1 = 3247473589
e2 = 3698409173
n = 103606706829811720151309965777670519601112877713318435398103278099344725459597221064867089950867125892545997503531556048610968847926307322033117328614701432100084574953706259773711412853364463950703468142791390129671097834871371125741564434710151190962389213898270025272913761067078391308880995594218009110313


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)
    s = gmpy2.gcdext(e1, e2)  # 扩展欧几里得算法  t*e1+z*e2=1,求出t和z
    t = s[1]
    z = s[2]
    if t < 0:  # 要求c的s次幂,就要先计算c的模反元素c2r,然后求c2r的-s2次幂
        t = - t
        c1 = gmpy2.invert(c1, n)  # 求c1的逆元
    elif z < 0:
        z = -z
        c2 = gmpy2.invert(c2, n)
    m = (pow(c1, t, n) * pow(c2, z, n)) % n  # (c1^s1*c2^s2)%n=m%n=m
    return m


result = rsa_gong_N_def(e1, e2, flag1, flag2, n)
print(long_to_bytes(result))

该脚本需要用到Crypto.Util.number。需要安装pycryptodome,而且\site-packages下的crypto也需要更改为Crypto,因为在pycryptodome库里面所引用的crypto是c字母大写的。

 int函数将所有输入参数转换为整数,以确保一致性。

共模攻击:

共模攻击(Common Modulus Attack)是一种针对使用相同模数但不同公钥指数的RSA加密系统的攻击方法。在共模攻击中,攻击者通过对一组密文进行分析,可以获取明文或密钥信息。

RSA加密过程中,密文c由明文m加密得到,公钥为e和模数n,加密过程如下:

𝑐=𝑚的𝑒次方 mod 𝑛

当使用相同模数 𝑛n,但不同的公钥指数 𝑒1e1​ 和 𝑒2e2​ 进行加密时,我们有两个密文:

𝑐1=𝑚的𝑒1次方  mod 𝑛

𝑐2=𝑚的𝑒2 次方mod 𝑛

如果e1​和e2​互质,则可以利用中国剩余定理从c1和c2​中还原出m的值。具体步骤如下:

  1. 使用扩展欧几里得算法求出e1​和e2的模反元素d1​和d2​;
  2. 计算 𝑥=𝑐1的𝑑1 次方mod 𝑛和 𝑦=𝑐2的𝑑2 次方mod 𝑛;
  3. 使用中国剩余定理,根据 𝑥x 和 𝑦y 还原出 𝑚m 的值。

 给我们的题目就是:

flag1=m1的e1次方mod n

flag2=m1的e2次方mod n

最后得到flag:

NSSCTF{xxxxx******xxxxx}

6.[羊城杯 2021]Bigrsa

from Crypto.Util.number import *
from flag import *

n1 = 103835296409081751860770535514746586815395898427260334325680313648369132661057840680823295512236948953370895568419721331170834557812541468309298819497267746892814583806423027167382825479157951365823085639078738847647634406841331307035593810712914545347201619004253602692127370265833092082543067153606828049061
n2 = 115383198584677147487556014336448310721853841168758012445634182814180314480501828927160071015197089456042472185850893847370481817325868824076245290735749717384769661698895000176441497242371873981353689607711146852891551491168528799814311992471449640014501858763495472267168224015665906627382490565507927272073
e = 65537
m = bytes_to_long(flag)
c = pow(m, e, n1)
c = pow(c, e, n2)

print("c = %d" % c)

# output
# c = 60406168302768860804211220055708551816238816061772464557956985699400782163597251861675967909246187833328847989530950308053492202064477410641014045601986036822451416365957817685047102703301347664879870026582087365822433436251615243854347490600004857861059245403674349457345319269266645006969222744554974358264

首先,它导入了所需的库以及一个名为 flag 的模块,然后设置了两个不同的 模数n1n2,以及一个公钥指数 e。接下来,它将明文 flag 转换为整数 m,然后使用第一个模数n1和公钥e对其进行加密,再使用第二个模数n2和e对结果进行再加密,最后打印出最终的密文 c

我们要求的是明文flag。

首先要考虑n1和n2是否互质,可以求最大公约数。

import gmpy2

n1 = 103835296409081751860770535514746586815395898427260334325680313648369132661057840680823295512236948953370895568419721331170834557812541468309298819497267746892814583806423027167382825479157951365823085639078738847647634406841331307035593810712914545347201619004253602692127370265833092082543067153606828049061
n2 = 115383198584677147487556014336448310721853841168758012445634182814180314480501828927160071015197089456042472185850893847370481817325868824076245290735749717384769661698895000176441497242371873981353689607711146852891551491168528799814311992471449640014501858763495472267168224015665906627382490565507927272073

a = gmpy2.gcd(n1, n2)
print("最大公约数:",a)

如果最大公约数大于1,那么n1和n2就不互质。

不互质(注意:"互质"和"互素"这两个术语在数学上是等价的,都表示两个数的最大公约数为 1,也就是除了 1 之外没有其他公共因子。它们的含义是一致的。)

import  gmpy2
from Crypto.Util.number import *
 
# output
c=60406168302768860804211220055708551816238816061772464557956985699400782163597251861675967909246187833328847989530950308053492202064477410641014045601986036822451416365957817685047102703301347664879870026582087365822433436251615243854347490600004857861059245403674349457345319269266645006969222744554974358264
 
e=65537
n1=103835296409081751860770535514746586815395898427260334325680313648369132661057840680823295512236948953370895568419721331170834557812541468309298819497267746892814583806423027167382825479157951365823085639078738847647634406841331307035593810712914545347201619004253602692127370265833092082543067153606828049061
n2=115383198584677147487556014336448310721853841168758012445634182814180314480501828927160071015197089456042472185850893847370481817325868824076245290735749717384769661698895000176441497242371873981353689607711146852891551491168528799814311992471449640014501858763495472267168224015665906627382490565507927272073
q=gmpy2.gcd(n1,n2)
q1=n1//q
q2=n2//q
d1=gmpy2.invert(e,(q1-1)*(q-1))
d2=gmpy2.invert(e,(q2-1)*(q-1))
m1=pow(c,d2,n2)
m2=pow(m1,d1,n1)
flag=''
flag=long_to_bytes(m2)
print(flag)

导入了gmpy2和Crypto.Util.number两个库,c,e,n1,n2。

计算模数 n1n2 的最大公约数 q,然后计算出两个模数的素数因子 pq

 接着,根据CRT的原理,分别计算了在模数 p-1q-1 下的RSA私钥 d1d2

最后,使用CRT的解密流程:先用模数 p 下的RSA私钥 d1 解密密文 c 得到中间结果 m1,再用模数 q 下的RSA私钥 d2 解密 m1 得到最终结果 m2,然后将其转换为字节串,即为明文。

输出:

 

7. [SWPU 2020]happy

('c=', '0x7a7e031f14f6b6c3292d11a41161d2491ce8bcdc67ef1baa9eL')
('e=', '0x872a335')
#q + q*p^3 =1285367317452089980789441829580397855321901891350429414413655782431779727560841427444135440068248152908241981758331600586
#qp + q *p^2 = 1109691832903289208389283296592510864729403914873734836011311325874120780079555500202475594

给了c和e

from gmpy2 import *
from Crypto.Util.number import *
c=0x7a7e031f14f6b6c3292d11a41161d2491ce8bcdc67ef1baa9e
e=0x872a335
k1=1285367317452089980789441829580397855321901891350429414413655782431779727560841427444135440068248152908241981758331600586
k2= 1109691832903289208389283296592510864729403914873734836011311325874120780079555500202475594
k3=gcd(k1,k2)
p=k2//k3
q=k3//(1+p)
n=p*q
phi=(p-1)*(q-1)
d=invert(e,phi)
flag=pow(c,d,n)
m=long_to_bytes(flag)
print(m)

用gmpy2 库来处理大整数和 RSA 运算,并使用了 Crypto.Util.number 中的一些函数来处理字节序列和整数之间的转换。定义密文 c、公钥 e,以及 k1​ 和 k2​ 这两个因子。然后找到k1​和k2​的最大公约数k3​,用它们得到了p和q,进而计算了n和 𝜙(𝑛)。接下来,求出私钥d,并用它对密文c进行解密,得到了明文 m。最后,将明文m转换为字节序列flag,并打印出来。

输出:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值