前言
本来以为社会组没有奖,就只写了crypto和一部分misc,结果结束了又说前十有奖,呜呜呜
题目
我和小蓝鲨的秘密
from PIL import Image
from Crypto.Util.number import bytes_to_long, long_to_bytes
import numpy as np
n = 29869349657224745144762606999
e = 65537
original_image_path = "flag.jpg"
img = Image.open(original_image_path)
img = img.convert("RGB")
img_array = np.array(img)
h, w, _ = img_array.shape
encrypted_array = np.zeros((h, w, 3), dtype=object)
for i in range(h):
for j in range(w):
r, g, b = int(img_array[i, j, 0]), int(img_array[i, j, 1]), int(img_array[i, j, 2])
encrypted_array[i, j, 0] = pow(r, e, n)
encrypted_array[i, j, 1] = pow(g, e, n)
encrypted_array[i, j, 2] = pow(b, e, n)
np.save("encrypted_image.npy", encrypted_array)
print("图片已加密并保存为 encrypted_image.npy")
思路:就是很简单图片rsa,可以直接,遍历,n很小,可以直接分解
exp
from sympy import factorint
from Crypto.Util.number import*
import numpy as np
from PIL import Image
n = 29869349657224745144762606999
p=186431677583461
q=160216064374859
e=65537
phi = (p - 1) * (q - 1)
d = inverse(e, phi)
encrypted_array = np.load("encrypted_image.npy", allow_pickle=True)
h, w, _ = encrypted_array.shape
decrypted_array = np.zeros((h, w, 3), dtype=np.uint8)
for i in range(h):
for j in range(w):
decrypted_array[i, j, 0] = pow(encrypted_array[i, j, 0], d, n)
decrypted_array[i, j, 1] = pow(encrypted_array[i, j, 1], d, n)
decrypted_array[i, j, 2] = pow(encrypted_array[i, j, 2], d, n)
decrypted_img = Image.fromarray(decrypted_array, 'RGB')
decrypted_img.save("decrypted_flag.jpg")
print("Flag 已解密并保存为 decrypted_flag.jpg")
chacha20
task
from Crypto.Cipher import ChaCha20_Poly1305
import os
key = os.urandom(32)
nonce = os.urandom(12)
with open('flag.txt', 'rb') as f:
plaintext = f.read()
cipher = ChaCha20_Poly1305.new(key=key, nonce=nonce)
ct, tag = cipher.encrypt_and_digest(plaintext)
print(f"Encrypted Flag: {ct.hex()}")
print(f"Tag: {tag.hex()}")
print(f"Nonce: {nonce.hex()}")
with open('key.txt', 'w') as key_file:
key_file.write(key.hex())
key?.txt
3=t#sMX3?9GHSPdi4i^gk!3*(cH8S8XT2y&?Tv4!?AGG=R]ZDy/PVVa+DqiXAH*}DS&Nn*a+@<H,=!L
output.txt
Encrypted Flag: 20408b9fc498063ad53a4abb53633a6a15df0ddaf173012d620fa33001794dbb8c038920273464e13170e26d08923aeb
Tag: 70ffcc508bf4519e7616f602123c307b
Nonce: d8ebeedec812a6d71240cc50
思路:chacha20反向解过去就行了,key是个base,至于多少自己试吧,因为我也是一个一个试的(气死我了)
exp
# python
from Crypto.Cipher import ChaCha20_Poly1305
#key是base
# 提供的密钥、Nonce、密文和标签
key_hex = '173974535637a5ef30a116b03d00bd2fe751951ca3eaa62daec2b8f5ca5b6135'
nonce_hex = 'd8ebeedec812a6d71240cc50'
ciphertext_hex = '20408b9fc498063ad53a4abb53633a6a15df0ddaf173012d620fa33001794dbb8c038920273464e13170e26d08923aeb'
tag_hex = '70ffcc508bf4519e7616f602123c307b'
# 转换为字节
key = bytes.fromhex(key_hex)
nonce = bytes.fromhex(nonce_hex)
ciphertext = bytes.fromhex(ciphertext_hex)
tag = bytes.fromhex(tag_hex)
# 创建解密器
cipher = ChaCha20_Poly1305.new(key=key, nonce=nonce)
try:
# 解密并验证
plaintext = cipher.decrypt_and_verify(ciphertext, tag)
print("Flag:", plaintext.decode())
except Exception as e:
print("解密失败:", e)
基础的数学
task
Base和Ciphertext
m = 5321153468370294351697008906248782883193902636120413346203705810525086437271585682015110123362488732193020749380395419994982400888011862076022065339666193
c = 7383779796712259466884236308066760158536557371789388054326630574611014773044467468610300619865230550443643660647968413988480055366698747395046400909922513
思路:写的时候已经有hint了,说是mod是2**512,那么直接解就行了
exp
m = 5321153468370294351697008906248782883193902636120413346203705810525086437271585682015110123362488732193020749380395419994982400888011862076022065339666193
c = 7383779796712259466884236308066760158536557371789388054326630574611014773044467468610300619865230550443643660647968413988480055366698747395046400909922513
n=2**512
from sympy import discrete_log
flag=discrete_log(n,c,m)
from Crypto.Util.number import long_to_bytes
print(long_to_bytes(flag))
小蓝鲨的密码
省略:压缩包密码就是图片的名字,不喜欢
ezmath
task
import random
import base64
from hashlib import md5
from secret import flag
from libnum import s2n
from Crypto.Cipher import AES
INF = 0xff
bigINF = 0xffffffff
# ---------------------error------------------------------
def sumFunc(func):
def wapper(*args,start = 1,end=INF):
sums = 0
for i in trange(start, 0xffff * end):
sums += function(*args,j/0xf) * (1/0xf)
return sums
return wapper
def limitFunc(func):
def wapper(*args, approch = bigINF, pos = "+"):
o = 1/bigINF
return function(args, eval(f"{approch} {pos} {o}"))
return wapper
# -------------------enderror-----------------------------
def pad(data):
data=data.encode('utf8')
while len(data) % 16 !=0:
data+=b'\x00'
return data
def encode(key,m):
mode=AES.MODE_ECB
aes=AES.new(pad(key),mode)
en_m=aes.encrypt(pad(m))
en_m=base64.encodebytes(en_m)
en_m=en_m.decode('utf8')
return en_m
def enc(msg, key):
random.seed(key)
new_key = md5(str(random.getrandbits(256)).encode('utf-8')).hexdigest()
return encode(new_key, msg)
@sumFunc
def gamma(x,t):
data = pow(t,x-1) * pow(magicNumber,-t)
return data
@sumFunc
def common(t):
data = pow(magicNumber,-pow(t,2))
return data
@limitFunc
def getMagicNumber(t):
data = pow(1+1/t,t)
return data
magicNumber = getMagicNumber()
encKey1 = str(gamma(3/2))[2:6]
encKey2 = str(common())[2:6]
assert encKey1 == encKey2
key = int(str(gamma(5/2))[2:])
print(enc(flag, key))
# n2SQK64JMsXstCtZurBiz81pMr3ZmgMjhuyL67hssm3shqJGYGfS/mWubINeE5HZ
思路:代码里面是装饰器,先把代码修复一下,虽然修不修无所谓,计算gamma(5/2)的结果就行,key就是小数部分,直接求就行了
exp
import random
import base64
from hashlib import md5
from Crypto.Cipher import AES
def pad(data):
if isinstance(data, str):
data = data.encode('utf8')
while len(data) % 16 != 0:
data += b'\x00'
return data
random.seed(key)
rand_bits = random.getrandbits(256)
new_key = md5(str(rand_bits).encode('utf-8')).hexdigest()
return new_key
def decode(key, en_m):
new_key = compute_new_key(key)
print(f"New Key: {new_key}")
aes = AES.new(pad(new_key), AES.MODE_ECB)
en_m_bytes = base64.decodebytes(en_m.encode('utf8'))
de_m = aes.decrypt(en_m_bytes)
try:
return de_m.rstrip(b'\x00').decode('utf8')
except UnicodeDecodeError:
print("解密后的字节无法以UTF-8解码。")
return de_m.rstrip(b'\x00')
encrypted_flag = "n2SQK64JMsXstCtZurBiz81pMr3ZmgMjhuyL67hssm3shqJGYGfS/mWubINeE5HZ"
key_str = "1.329340388179137"
key = int(key_str.split('.')[1])
print(f"Computed Key: {key}")
flag = decode(key, encrypted_flag)
print(f"Flag = {flag}")
fermat
task
import libnum
import gmpy2
from Crypto.Util.number import *
flag=b'ISCTF{********}'
m=bytes_to_long(flag)
p=libnum.generate_prime(1024)
q=libnum.generate_prime(1024)
n=p*q
e=0x10001
c=pow(m,e,n)
d=inverse(e,(p-1)*(q-1))
leak = (d+(pow(p,q,n)+pow(q,p,n)))%n
print("c=", c)
print("n=", n)
print("leak=", leak)
"""
c= 8989289659072309605793417141528767265266446236550650613514493589798432446586991233583435051268377555448062724563967695425657559568596372723980081067589103919296476501677424322525079257328042851349095575718347302884996529329066703597604694781627113384086536158793653551546025090807063130353950841148535682974762381044510423210397947080397718080033363000599995100765708244828566873128882878164321817156170983773105693537799111546309755235573342169431295776881832991533489235535981382958295960435126843833532716436804949502318851112378495533302256759494573250596802016112398817816155228378089079806308296705261876583997
n= 13424018200035368603483071894166480724482952594135293395398366121467209427078817227870501294732149372214083432516059795712917132804111155585926502759533393295089100965059106772393520277313184519450478832376508528256865861027444446718552169503579478134286009893965458507369983396982525906466073384013443851551139147777507283791250268462136554061959016630318688169168797939873600493494258467352326974238472394214986505312411729432927489878418792288365594455065912126527908319239444514857325441614280498882524432151918146061570116187524918358453036228204087993064505391742062288050068745930452767100091519798860487150247
leak= 9192002086528025412361053058922669469031188193149143635074798633855112230489479254740324032262690315813650428270911079121913869290893574897752990491429582640499542165616254566396564016734157323265631446079744216458719690853526969359930225042993006404843355356540487296896949431969541367144841985153231095140361069256753593550199420993461786814074270171257117410848796614931926182811404655619662690700351986753661502438299236428991412206196135090756862851230228396476709412020941670878645924203989895008014836619321109848938770269989596541278600166088022166386213646074764712810133558692545401032391239330088256431881
"""
思路:很经典的题目,风二西佬好像讲过,可以直接去看,所以咱们就不写了(懒
exp
import gmpy2
from Crypto.Util.number import long_to_bytes, inverse
import libnum
# 给定的值
c = 8989289659072309605793417141528767265266446236550650613514493589798432446586991233583435051268377555448062724563967695425657559568596372723980081067589103919296476501677424322525079257328042851349095575718347302884996529329066703597604694781627113384086536158793653551546025090807063130353950841148535682974762381044510423210397947080397718080033363000599995100765708244828566873128882878164321817156170983773105693537799111546309755235573342169431295776881832991533489235535981382958295960435126843833532716436804949502318851112378495533302256759494573250596802016112398817816155228378089079806308296705261876583997
n = 13424018200035368603483071894166480724482952594135293395398366121467209427078817227870501294732149372214083432516059795712917132804111155585926502759533393295089100965059106772393520277313184519450478832376508528256865861027444446718552169503579478134286009893965458507369983396982525906466073384013443851551139147777507283791250268462136554061959016630318688169168797939873600493494258467352326974238472394214986505312411729432927489878418792288365594455065912126527908319239444514857325441614280498882524432151918146061570116187524918358453036228204087993064505391742062288050068745930452767100091519798860487150247
leak = 9192002086528025412361053058922669469031188193149143635074798633855112230489479254740324032262690315813650428270911079121913869290893574897752990491429582640499542165616254566396564016734157323265631446079744216458719690853526969359930225042993006404843355356540487296896949431969541367144841985153231095140361069256753593550199420993461786814074270171257117410848796614931926182811404655619662690700351986753661502438299236428991412206196135090756862851230228396476709412020941670878645924203989895008014836619321109848938770269989596541278600166088022166386213646074764712810133558692545401032391239330088256431881
c_1 = inverse(c,n)
m = pow(c_1, n+1-leak,n)
print(long_to_bytes(m))
蓝鲨的RSA
task
from secret import flag
import gmpy2
import decimal
from Crypto.Util.number import *
def gethint(h,p):
decimal.getcontext().prec = 1024
H = decimal.Decimal(int(h))
P = decimal.Decimal(int(p))
leak = decimal.Decimal((8*H*P - 1) / (16*P*P))
return leak
p = getPrime(512)
q = getPrime(512)
f = getPrime(512)
g = getPrime(128)
h = gmpy2.invert(f, p) * g % p
n = f*q
e = 65537
m = bytes_to_long(flag)
c = pow(m,e,n)
print('c =', c)
print('hint =', gethint(h,p))
print('n =',n)
#c = 587245179027322480379581200283415189810421958968516831191660631552695197401940961725169763339428980298128692606951200581483431566182271569207988054537414289564013883171160614196522169980339024564884190765084419167938640701193928669
#hint = 0.2427542737153618793334900104191212626446625872340179613972610728976081994921862517310186626304527115125924716035632505287111236596234811779375148657365336957626454491865164520834975233144235103885081268955448330597818844340656652982593545877449810282619387305007246499089258519062093814083383071737897364213169497762760797899310673216754376885295598952272100016962368762532805864796748393317534908268379601445004775495237901072144236328105526403608646831124542336002540011176406194984370372589752234640498423911217119220030242197564695880261480071310815379681250975672935544404797155655708441222387631967447088319826137200280810029390387418159394276760100487636516708987579464183208860911063948902432948269805493252899815187044807603000344378890835564906163242023600624338694473573763088471321731611077227112205396909637906507673367598721218000123789690455125909411309668615810240938664264212370815385282488986625554704015828254539339719586211726300858711328516487805251366293457402531199532556110786048074755505680210260049
#n = 839799159583571337450826982895478997157381520448790705455708438948150905361244823725400304016136863419723271227616684280477524669207590477657886623628732394537008838314015048569652202355464477680540884654473950183135276735347866051
思路:p和h直接连分数展开,basectf有一个与之类似的题,但是注意到是$$8HP/16PP $$所以展开时其实是leak*2,后面是个基础的格,可以看detex佬的博客
exp
hint = 0.2427542737153618793334900104191212626446625872340179613972610728976081994921862517310186626304527115125924716035632505287111236596234811779375148657365336957626454491865164520834975233144235103885081268955448330597818844340656652982593545877449810282619387305007246499089258519062093814083383071737897364213169497762760797899310673216754376885295598952272100016962368762532805864796748393317534908268379601445004775495237901072144236328105526403608646831124542336002540011176406194984370372589752234640498423911217119220030242197564695880261480071310815379681250975672935544404797155655708441222387631967447088319826137200280810029390387418159394276760100487636516708987579464183208860911063948902432948269805493252899815187044807603000344378890835564906163242023600624338694473573763088471321731611077227112205396909637906507673367598721218000123789690455125909411309668615810240938664264212370815385282488986625554704015828254539339719586211726300858711328516487805251366293457402531199532556110786048074755505680210260049
hint=hint*2
cf = continued_fraction(hint)
for i in range(1000000000000):
k = cf.numerator(i)
x = cf.denominator(i)
if is_prime(x) and x.bit_length() == 512:
print(k,x)
p,q = k,x
break
h=5644635742819829990750561229762805499221246439546826634192809053443196388050776487556004854931490257361050491682744164242094809598515347830480716371931526
p=11626233508536225614198811594320851252696454462193005033285647766940577053402735947923143276545500298338019376937355197687508293952240619015634703176724083
c=587245179027322480379581200283415189810421958968516831191660631552695197401940961725169763339428980298128692606951200581483431566182271569207988054537414289564013883171160614196522169980339024564884190765084419167938640701193928669
n=839799159583571337450826982895478997157381520448790705455708438948150905361244823725400304016136863419723271227616684280477524669207590477657886623628732394537008838314015048569652202355464477680540884654473950183135276735347866051
from Crypto.Util.number import *
Ge = Matrix(ZZ,[[1,h],[0,p]])
print(Ge.LLL())
f,g = Ge.LLL()[0]
f,g = abs(f),abs(g)
q=n//f
phi=(f-1)*(q-1)
d=inverse_mod(65537,phi)
m=pow(c,d,n)
print(long_to_bytes(m))
小蓝鲨的方程
task
from Cryptodome.Util.number import *
from random import *
from gmpy2 import *
import uuid
flag1='ISCTF{'+str(uuid.uuid4())+'}'
m1=bytes_to_long(flag1.encode())
def get_p():
BITS = 256
bits = 777
oder = 4
a = randint(1 << bits, 1 << bits + 1)
p=getPrime(BITS)
p1 = p**oder+a
return p,p1
p,p1=get_p()
s=getPrime(1024)
q=getPrime(512)
n=p*q**4
e=65537
c1=pow(s,e,n)
c=pow(s**3+1,m1,s**5)
print("c1=",c1)
print("c =",c)
print("n =",n)
print("p1 =",p1)
'''
c1= 671390498592586008552998377599101093977542184109077889081448730480869018650843045119891777468161631085086340705902115332025675787789530562679603254577287153918966364523848382506106179394235772395029788721306186952016420794804145631124905952103136061076643266886961178241381892015555099638200222249447194504082451341122502519637821695210573997670753981061458264118355417889153180841281073262935937836447460470926729282834006229571453935760593644658459098721652426154970766417292435960463905367868753821950303919781798234432998272038029063155193184039985018137026245365188171178677898869374676546799536208952198558258306460302868688355653022725288744014143221560882404431652751343944983442109327
c = 8641190030376811670503537177719719233418166235794962118828671236836174132083208517733734760455990850156371205118391537919769888760384574011411232571257192285256730733174399297826587479261381970232162702657952399683882650083181048279650913795429823628186888540572704055008102853692060360140858142686334722286525699998854566609078547487420929457446776757558492454916447188774943818970599916514467335772992690805247630814156710861067503956707301402347944233660194395192354000788262111000900574820275786269075882923600474781645848712157460135387134196156906258218217831988828360827613420801773911833194097791649069743116686685667300622630909231822986237104627385544169938138006242341269672868611269202418482629393372933567053272565557137741441902377611003983050084491513897727856173625922194300103448148829004025229567101761111396110940066254801762424343522707712480796358754008120503317686600144600226149617189681233392693738216138797012278242152852923361635415564580582002132107424154426980566696622448291815571736676562214017436
n = 1076246859437269645898003764327104347852443049519429833372038915264009774423737482018987571807662568251485615769880354898666799006772572239466617428164721157850526408878346223839884319846641438292436373441749602341461361190584638190903978829024853974880636148520803145113551453821058269641304504880310836801494499720662704717315748614372503735165114899680682056477494953525794354656896362929510309669119173103242509398650608116835276076364248473952717811633756784397347121601006659623317417388283638159905288128181587304367489096254611610975352096229116491567502061775862811850081040850421151385474249060884479729988512713640536139010928836126719149031115182144744359297169350288886555784650111
p1 = 145356063641618996012874664536921616978986640263438210169671010403677822239343590475177543891188656103067696467174379510912427160232486984044862545338401652910975162942038201716552753723984593267892098222213049269335313670049037479410635628460505327693176152061750827570561482918795206276991967169087371403553
'''
思路:第一开始没想到和方程有什么关系,然后发现在最后面用到了,前面的p直接开方并且循环爆破一下,asssert一下,保证无错,然后求q,也assert验证一下,然后求出s,发现s很大,更别说s**5了,以下是思路
利用 二项式定理 对 (s^3 + 1)^m1 进行展开,并简化模 s^5 的表达式:
$$ (s^3 + 1)^{m1} \equiv 1 + m1 \cdot s^3 \mod s^5 $$
因此,方程变为: $$ 1 + m1 \cdot s^3 \equiv c \mod s^5 $$
移项后得到: $$ m1 \cdot s^3 \equiv c – 1 \mod s^5 $$
由于 s^3 与 s^5 的关系,可以将 m1 表示为: $$ m1 \equiv \frac{c – 1}{s^3} \mod s^2 $$
这个方程表明,m1 可以通过以下步骤直接计算:
计算 (c – 1) // s^3:
确保 (c – 1) 能被 s^3 整除,否则方程无解。
取模 s^2:因为在模 s^5 下,m1 的值在模 s^2 的范围内是唯一确定的。
exp
c1= 671390498592586008552998377599101093977542184109077889081448730480869018650843045119891777468161631085086340705902115332025675787789530562679603254577287153918966364523848382506106179394235772395029788721306186952016420794804145631124905952103136061076643266886961178241381892015555099638200222249447194504082451341122502519637821695210573997670753981061458264118355417889153180841281073262935937836447460470926729282834006229571453935760593644658459098721652426154970766417292435960463905367868753821950303919781798234432998272038029063155193184039985018137026245365188171178677898869374676546799536208952198558258306460302868688355653022725288744014143221560882404431652751343944983442109327
c = 8641190030376811670503537177719719233418166235794962118828671236836174132083208517733734760455990850156371205118391537919769888760384574011411232571257192285256730733174399297826587479261381970232162702657952399683882650083181048279650913795429823628186888540572704055008102853692060360140858142686334722286525699998854566609078547487420929457446776757558492454916447188774943818970599916514467335772992690805247630814156710861067503956707301402347944233660194395192354000788262111000900574820275786269075882923600474781645848712157460135387134196156906258218217831988828360827613420801773911833194097791649069743116686685667300622630909231822986237104627385544169938138006242341269672868611269202418482629393372933567053272565557137741441902377611003983050084491513897727856173625922194300103448148829004025229567101761111396110940066254801762424343522707712480796358754008120503317686600144600226149617189681233392693738216138797012278242152852923361635415564580582002132107424154426980566696622448291815571736676562214017436
n = 1076246859437269645898003764327104347852443049519429833372038915264009774423737482018987571807662568251485615769880354898666799006772572239466617428164721157850526408878346223839884319846641438292436373441749602341461361190584638190903978829024853974880636148520803145113551453821058269641304504880310836801494499720662704717315748614372503735165114899680682056477494953525794354656896362929510309669119173103242509398650608116835276076364248473952717811633756784397347121601006659623317417388283638159905288128181587304367489096254611610975352096229116491567502061775862811850081040850421151385474249060884479729988512713640536139010928836126719149031115182144744359297169350288886555784650111
p1 = 145356063641618996012874664536921616978986640263438210169671010403677822239343590475177543891188656103067696467174379510912427160232486984044862545338401652910975162942038201716552753723984593267892098222213049269335313670049037479410635628460505327693176152061750827570561482918795206276991967169087371403553
from gmpy2 import*
from Crypto.Util.number import *
from sympy import discrete_log
from gmpy2 import mpz, iroot, is_prime
lower_a = mpz(1) << 777
upper_a = mpz(1) << 778
approx_p, exact = iroot(p1, 4)
if not exact:
approx_p += 1
search_range = 100000
for k in range(-search_range, search_range):
p_candidate = approx_p + k
if not is_prime(p_candidate):
continue
# 计算对应的 a
a_candidate = p1 - p_candidate**4
if lower_a <= a_candidate <= upper_a:
print("找到 p:", p_candidate)
print("对应的 a:", a_candidate)
break
p=109801503867274649798222703146361472504035741051437565219324438087291269873711
assert n%p == 0
q=n//p
q=iroot(q,4)[0]
phi=(p-1)*(q-1)*(q**3)
d=inverse(65537,phi)
s=pow(c1,d,n)
s=94423586985629586109151158736296883361273289450685688621152315803642865015090106522217001407373857704007853280049626049708701029510476587908461385557678191510801074269386297085357100319875645753000245907974169833335293172030062044583394890776091941620200339705124166508737987531884585421144791962938319477479
#c=pow(s**3+1,m1,s**5)
s = 94423586985629586109151158736296883361273289450685688621152315803642865015090106522217001407373857704007853280049626049708701029510476587908461385557678191510801074269386297085357100319875645753000245907974169833335293172030062044583394890776091941620200339705124166508737987531884585421144791962938319477479
c = 8641190030376811670503537177719719233418166235794962118828671236836174132083208517733734760455990850156371205118391537919769888760384574011411232571257192285256730733174399297826587479261381970232162702657952399683882650083181048279650913795429823628186888540572704055008102853692060360140858142686334722286525699998854566609078547487420929457446776757558492454916447188774943818970599916514467335772992690805247630814156710861067503956707301402347944233660194395192354000788262111000900574820275786269075882923600474781645848712157460135387134196156906258218217831988828360827613420801773911833194097791649069743116686685667300622630909231822986237104627385544169938138006242341269672868611269202418482629393372933567053272565557137741441902377611003983050084491513897727856173625922194300103448148829004025229567101761111396110940066254801762424343522707712480796358754008120503317686600144600226149617189681233392693738216138797012278242152852923361635415564580582002132107424154426980566696622448291815571736676562214017436 # 请在此处填入已知的 c 值
from Crypto.Util.number import long_to_bytes
if (c - 1) % (s**3) != 0:
print("方程无解,因为 (c - 1) 不能被 s^3 整除。")
else:
m1 = ((c - 1) // s**3) % (s**2)
print("m1 =", m1)
print("flag1 =", long_to_bytes(m1))
HIM(复现)
task
附件好大的,直接去is下吧(哭哭
思路:这玩意的应该是https://github.com/spawnmason/randar-explanation 这个为基础出来的,代码审计一下,主要的main里边就是HIM会设置两个在-23440 到23440的随机数,分别为X,Z,我们的目标就是恢复这两个随机数,恢复5次即可。其实没啥思路,看了看wp,居然是LLL出来的,大概意思是我们通过到一些地方,生成坐标,然后利用坐标去LLL出seed,然后利用LCG伪随机的特性求出him的坐标正是给了him的范围,我们才能爆出来,挺好玩的,github的文档里面就有做法,直接用改改pwn库就行
exp
from pwn import *
sa = lambda s,n : p.sendafter(s,n)
sla = lambda s,n : p.sendlineafter(s,n)
sl = lambda s : p.sendline(s)
sd = lambda s : p.send(s)
rc = lambda n : p.recv(n)
ru = lambda s : p.recvuntil(s)
rl = lambda : p.recvline()
it = lambda : p.interactive()
ip = ''
port = 0
p = remote(ip , port)
# p = remote("127.0.0.1", 8888)
sla("请输入用户名: ",b"guoql")
sla("=>请选择:",b"start")
for _ in range(5):
sla("输入yes投币开始:",b"yes")
sla("请选择:","2")
sla("请输入想要挖掘的方块坐标(例: (1,1,1) ):",b"(1,1,1)")
data = rl().decode('utf-8')
blockX,blockY,blockZ = tuple([float("0." + i.split(".")[1]) for i in data.split("Block drop in ")[1][:-1][1:-1].split(", ")])
print(data,blockX,blockY,blockZ)
randX = round(2 * 2**24 * (blockX - 0.25))
randY = round(2 * 2**24 * (blockY - 0.25))
randZ = round(2 * 2**24 * (blockZ - 0.25))
# 获取低24位数据
print(f"{randX},{randY},{randZ}")
# 格基规约得到原始seed
def crack(a0,b0,c0):
a=25214903917
b=11
c=281474976710656
a1 = a0 * 2**24 + 2**23
b1 = b0 * 2**24 + 2**23
c1 = c0 * 2**24 + 2**23
v = vector([a1,b1 - b,c1 - b - a*b])
matex = matrix.zero(3)
matex[0] = [1,a,a*a]
matex[1] = [0,c,0]
matex[2] = [0,0,c]
lattice = matex.LLL()
base = lattice.transpose().inverse()
result = base*v
final = vector([round(RDF(i)) for i in result])
solved = lattice.transpose() * final
return solved
seed = int(crack(randX, randY, randZ)[0])
# LCG线性同余求解出来上一个seed
old_seed = ((seed - 11 ) * 246154705703781) % 2**48
# sagemath的异或是^^而不是^
HIM_seed = old_seed ^^ 0x5DEECE66D
print(old_seed,HIM_seed)
world_seed = 14617218721232814696
# input()
# 寻找x,z需要满足在-23440 到 23400 的范围内
for x in range(-23440, 23441):
z = ((HIM_seed - world_seed - 10387319 - x * 341873128712 ) * 211541297333629 ) % 2**48
if z >= 2**48 + -23440 :
z = z - 2**48
print(f"x,z found:{x},{z}")
break
if z <= 23440:
print(f"x,z found:{x},{z}")
break
sla("请选择:", b"1")
sla("请输入HIM所在区块的坐标(例: (10,-25) ):", f"({x},{z})".encode('utf-8'))
print(rl().decode('utf-8'))
print(rl().decode('utf-8'))
总结
总的来说不难,但是那个压缩包我感觉挺没必要的,最后这个him感觉可以放个hint,只有L佬做出来了,害,被折磨了一天,其他的题都挺好的,没有出老套无聊的题,很适合我们这种刚入门的人,嘿嘿。