M = bytes()
temp = bytes()
for j in b:
s = long_to_bytes(j)
if s == b'\n':
M += base64.b64decode(temp)
M += b' '
temp = bytes()
continue
temp += s
print (M)
得到如下结果
1
THIS FLAG IS HIDDEN. CAN YOU FIND IT OUT? DO YOU KNOW BASE64? YoungC THINK YOU ARE NOT THAT FAMILIAR WITH BASE64. Base64 is a group of similar binary-to-text encoding schemes that represent binary data in an ASCII string format by translating it into a radix-64 representation. The term Base64 originates from a specific MIME content transfer encoding. The particular set of 64 characters chosen to represent the 64 place-values for the base varies between implementations. The general strategy is to choose 64 characters that are both members of a subset common to most encodings, and also printable. This combination leaves the data unlikely to be modified in transit through information systems, such as E-mail, that were traditionally not 8-bit clean.[1] For example, MIME's Base64 implementation uses A\xa8CZ, a\xa8Cz, and 0\xa8C9 for the first 62 values. Other variations share this property but differ in the symbols chosen for the last two values; an example is
from Crypto.Util.number import*
import base64
with open('flag.txt', 'rb') as f:
c = f.read()
def get_base64_diff_value(s1, s2):
base64chars = b'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
res = 0
for i in range(len(s2)):
if s1[i] != s2[i]:
return abs(base64chars.index(s1[i]) - base64chars.index(s2[i]))
return res
def solve_stego():
line = b''
bin_str = ''
for i in c:
k = long_to_bytes(i)
if k == b'\n':
steg_line = line
norm_line = base64.b64encode(base64.b64decode(line))
diff = get_base64_diff_value(steg_line, norm_line)
pads_num = steg_line.count(b'=')
if diff:
bin_str += bin(diff)[2:].zfill(pads_num * 2)
else:
bin_str += '0' * pads_num * 2
print(goflag(bin_str))
line = b''
continue
line += k
def goflag(bin_str):
res_str = ''
for i in range(0, len(bin_str), 8):
res_str += chr(int(bin_str[i:i + 8], 2))
return res_str
if __name__ == '__main__':
solve_stego()
for x in range(2,100):
for y in range(2,100):
try:
if x%y != 0:
res = (((y%x)**5)%(x%y))**2019+y**316+(y+1)//x
if res == A:
print ("x:%d y:%d"%(x,y))
except:
pass
importsympyimportrandomdefmyGetPrime():A=getPrime(513)print(A)B=A-random.randint(1e3,1e5)print(B)returnsympy.nextPrime((B!)%A)p=myGetPrime()#A1=21856963452461630437348278434191434000066076750419027493852463513469865262064340836613831066602300959772632397773487317560339056658299954464169264467234407#B1=21856963452461630437348278434191434000066076750419027493852463513469865262064340836613831066602300959772632397773487317560339056658299954464169264467140596q=myGetPrime()#A2=16466113115839228119767887899308820025749260933863446888224167169857612178664139545726340867406790754560227516013796269941438076818194617030304851858418927#B2=16466113115839228119767887899308820025749260933863446888224167169857612178664139545726340867406790754560227516013796269941438076818194617030304851858351026r=myGetPrime()n=p*q*r#n=85492663786275292159831603391083876175149354309327673008716627650718160585639723100793347534649628330416631255660901307533909900431413447524262332232659153047067908693481947121069070451562822417357656432171870951184673132554213690123308042697361969986360375060954702920656364144154145812838558365334172935931441424096270206140691814662318562696925767991937369782627908408239087358033165410020690152067715711112732252038588432896758405898709010342467882264362733c=pow(flag,e,n)#e=0x1001#c=75700883021669577739329316795450706204502635802310731477156998834710820770245219468703245302009998932067080383977560299708060476222089630209972629755965140317526034680452483360917378812244365884527186056341888615564335560765053550155758362271622330017433403027261127561225585912484777829588501213961110690451987625502701331485141639684356427316905122995759825241133872734362716041819819948645662803292418802204430874521342108413623635150475963121220095236776428#so,what is the flag?
def mydecrypt(A,B):
ans=1
temp=gmpy2.powmod(-1,1,A)
#print(temp)
for i in range(B+1,A):
ans=(ans*gmpy2.invert(i,A))%A
return (ans*temp)%A
解flag部分的代码如下:
p = sympy.nextprime(mydecrypt(A1,B1))
q = sympy.nextprime(mydecrypt(A2,B2))
r = n//p//q
phi = (p-1)*(q-1)*(r-1)
d = gmpy2.invert(e,phi)
flag = gmpy2.powmod(c,d,n)
print(binascii.unhexlify(hex(flag)[2:]))
0x03 [GWCTF 2019]BabyRSA
secret文件里面存放了N、m1、m2。encrypto.py的内容如下:
import hashlib
import sympy
from Crypto.Util.number import *
flag = 'GWHT{******}'
secret = '******'
assert(len(flag) == 38)
half = len(flag) / 2
flag1 = flag[:half]
flag2 = flag[half:]
secret_num = getPrime(1024) * bytes_to_long(secret)
p = sympy.nextprime(secret_num)
q = sympy.nextprime(p)
N = p * q
e = 0x10001
F1 = bytes_to_long(flag1)
F2 = bytes_to_long(flag2)
c1 = F1 + F2
c2 = pow(F1, 3) + pow(F2, 3)
assert(c2 < N)
m1 = pow(c1, e, N)
m2 = pow(c2, e, N)
output = open('secret', 'w')
output.write('N=' + str(N) + '\n')
output.write('m1=' + str(m1) + '\n')
output.write('m2=' + str(m2) + '\n')
output.close()
由于p和q是相邻的素数,可以将N开平方根求解。
np = (gmpy2.iroot(N,2))[0]
p = sympy.nextprime(np)
q = N//p
fromCrypto.Util.numberimport*fromflagimportflagdefnextPrime(n):n+=2ifn&1else1whilenotisPrime(n):n+=2returnnp=getPrime(1024)q=nextPrime(p)n=p*qe=0x10001d=inverse(e,(p-1)*(q-1))c=pow(bytes_to_long(flag.encode()),e,n)# d = 19275778946037899718035455438175509175723911466127462154506916564101519923603308900331427601983476886255849200332374081996442976307058597390881168155862238533018621944733299208108185814179466844504468163200369996564265921022888670062554504758512453217434777820468049494313818291727050400752551716550403647148197148884408264686846693842118387217753516963449753809860354047619256787869400297858568139700396567519469825398575103885487624463424429913017729585620877168171603444111464692841379661112075123399343270610272287865200880398193573260848268633461983435015031227070217852728240847398084414687146397303110709214913# c = 5382723168073828110696168558294206681757991149022777821127563301413483223874527233300721180839298617076705685041174247415826157096583055069337393987892262764211225227035880754417457056723909135525244957935906902665679777101130111392780237502928656225705262431431953003520093932924375902111280077255205118217436744112064069429678632923259898627997145803892753989255615273140300021040654505901442787810653626524305706316663169341797205752938755590056568986738227803487467274114398257187962140796551136220532809687606867385639367743705527511680719955380746377631156468689844150878381460560990755652899449340045313521804
for i in range(1000,3000):
if e*d-1 > 2**i and e*d-1<2**(i+1):
print(i)
break
#2063
q是p的下一个素数。
for k in range(pow(2,15),pow(2,16)):
if phi %k == 0:
p = sympy.prevprime(gmpy2.iroot(phi//k,2)[0])
q = sympy.nextprime(p)
if phi//k == (p-1)*(q-1):
break
0x08 [AFCTF2018]可怜的RSA
常规解密。
import gmpy2
import base64
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP
f = open('flag.enc', 'r').read()
c = base64.b64decode(f)
rsa_com = (n,e,int(d),p,q)
rsa = RSA.construct(rsa_com)
key = RSA.importKey(rsa.exportKey())
key = PKCS1_OAEP.new(key)
flag = key.decrypt(c)
print(flag)