纪实:校内线上训练——Crypto
近日,学校俱乐部举办了有关网安的比赛,不去不知道,真的是一句“我好菜”走天下……在此就是记录一下那些我做过的和没做上的题,其实看了一下别人的wp总是就差临门一脚,心情很糟 v_v
接下来会按照顺序呢会连续记录PWN、REVERSE、MISC、WEB、CRYPTO的……
1.babyRSA
n = 2175688405733541703870452086626738401792220260185622845647
e = 0x10001
c = 909189959980475048848571460773306576585339198658788147448
这道题真的是刷新我对RSA的认知:
对于这道题,当你分解n时会发现分解出三个质数,我当时十分诧异,因为从来没听说过RSA的p、q之外还能有其他参数,同时如果当做一个p×q、k的话存在一个合数是不是会出问题,但是后来通过查询资料,我才明白
费马小定理是对于每一个质数都存在正确性的,所以说n分解出来的质数的个数不会影响最终的解码过程
其余部分就比较简单,直接按照正常过程走即可
2.Random
main函数源码:
import random import socketserver from Crypto.Util import number import os flag = os.environ.get('flag', 'flag{test_flag}') class EncryptHandler(socketserver.BaseRequestHandler): p = 1543 iv = 792 def encrypt(self, m: list): self.r1.seed(self.r1_key) self.r2.seed(self.r2_key) res = [] w = self.iv for i in m: w = ((i + w + self.r1.randrange(0, self.p)) % self.p) * self.r2.randrange(0, self.p) % self.p res.append(w) w ^= self.random_key return res def setup(self): self.random_key = random.randrange(0, self.p) self.r1_key = random.randrange(0, self.p) self.r2_key = random.randrange(0, self.p) self.r1 = random.Random() self.r2 = random.Random() self.enc_flag = self.encrypt(list(flag.encode())) def handle(self): hello_msg = ('Hello, here gives you the encrypted Flag:\n' '{}\n' 'You can type any msg, and I will give you the encrypted message\n' ).format(self.enc_flag) self.request.sendall(hello_msg.encode()) while True: msg = self.request.recv(1024)[:-1] self.request.sendall((str(self.encrypt(msg)) + '\n').encode()) if __name__ == '__main__': HOST, PORT = with socketserver.ThreadingTCPServer((HOST, PORT), EncryptHandler) as server: try: server.serve_forever() except KeyboardInterrupt: server.shutdown()
这道题代码挺复杂,但是看起来还是比较方便的。整个流程就是通过随机数一次加密一个flag,但是连接没有断,可以持续发送,这样就造成了漏洞。我们可以像背包算法一样(?算法误入?),但是这里比较暴力,一个一个试过去即可。
上一发我自己的payload:
from pwn import * import ast io=remote() #这里是为了方便后面byte列表直接转换成列表 io.recvuntil("\n") byt=io.recvuntil("]") # print(byt) io.recv() #这里是将byte类型的列表转换成List rule=ast.literal_eval(byt.decode()) print (rule) stmp="1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz|{},:;.? !@_-+=#$%^&*()<>~`/\\"+'\''+'\"' length=len(rule) test="" for i in range(length): print(i) print(test) for j in stmp: #print(j) io.sendline(test+j) res=io.recv()[:-1].decode() res=ast.literal_eval(res) #print(res) if res[i]==rule[i]: test+=j break; print(test)
3.Small e
main函数源码:
from flag import flag from Crypto.Util import number import os assert type(flag) == str flag_b = flag.encode() + os.urandom(128 - len(flag)) p = [number.getPrime(1024) for _ in range(3)] q = [number.getPrime(1024) for _ in range(3)] n = [_p * _q for _p, _q in zip(p, q)] e = 3 m = number.bytes_to_long(flag_b) for i in range(3): print("n{} = {}".format(i, n[i])) print("c{} = {}".format(i, pow(m, e, n[i])))
Output.txt内容:
n0 = 16067817932594307041570490664780805848472742222521209486359183294876659529608435557600537260250449433611595173684925374508467672404417859479495004093579610726032262914323802262015761804257474778421075371915604733039622965481151880946821099347099589181944483948769906556017986079391359211585782596464924468208449010284942962635113163737362978946256184113197172628780615797285233916435176242221439390878162794629364484926505774613228229646458189210171950867198879934364120504046273177961083687027937189811732509344365844834160229805810205081446686611488115226014344875552419979932806334691942178914927653481984541110621 c0 = 9879971463914625690975893241580185387981496369356734957012721513373144938753569045503323744985869516225432489622517950293366904764152664636972215860898639778481845669980292323448545868723176321988532040102362409575435129737188286227622375002577654117407187235639039788403421568330907783489740293783760374579674272228953702822209345735718037784007905107507640441789566148023418182843850856028272425280660185409774791229291736804113219546032069271224441643592470352853688723172019556711071350797050854277490132448056258928350601925843959503438270798312618141538795176843674864017991973083157087900179066637653967471786 n1 = 27220804436805864442162182442813759263069372128468811270228757759122242102746634331274204813645700606025198464757315069476396636457109385709010309093761124250367793217269514777894950749932026790104944920542415154470272710654996775902535083921322900858510081080526361203971974235685839596700898966986819478871421472486198215667112358892381840624555494963218129513959117765033488219148477371667129956523403726492811804971592929874287476692563269065787601147950636445646208059251015601569921025370871805357871922113088791024382926047840273911791193990034677955545643860434985638900984527560552087922124397003230357748287 c1 = 18601174471639330838673755997627097179717053665843260588739160926694895023115719989743218032177933064024790567417281962648968287556842258818888225805040849173826497707326525590383774570277339562504216146208571367319040674013938991326596042075188486353554578994481344994910413567203491400010042812019323116569805264327599429345975064505984904064402357370098622911816024581171930600566133580491190247014980742239289588062485016239992005485018607729737084787372336151888759198583123570341162243303928994460199822642294565067160393816192370390199699022295478284192467413238687379911409873590966380239175755869062503249758 n2 = 18003911632122599813425550392025295318460144538002420546091473342504066065913374478380723966510863927323450160422323963085439934919821408030000597030220444017446677275520530600602313223716913843706289020789546341254298514327568202682323289952838243830866298465249322960573348784191060837060844553425424656343221015762038900638842760791476620770787585512880263777811650363550291113188707834451876652168342500756621692207745249699478983220317963165032407100517970067554347460807373078643124640438035329791669756566825583763144347915561928759654089817337965531158175165510730703911869587267266225122572337924741504872421 c2 = 16232129131608810282413937706144487240626338624250308577834225698445782468881682329646696899789457330498386668165599055270602304521900866238477820450745745574235835329025428831975135564432471301944638869445512637388111199953848153394755434332731325017811903037131194504517921570433491911858368670794242170207150194844396867824699460595352243616284981999437646934978307049377044110514736105768616893202608779347282837560546402961227548577594166063494153158225233408919063945070416486278018607780042733335959208255707942063870095648981102997015240784176457028384300754675188591655968245197618705494443537255712721037015
这道题就是典型的中国剩余定理的应用啦。由于ci≡m^e(modni),我们直接可以套公式(x1*y1*M/n1+x2*y2*M/n2+x3*y+*M/n3+……x=ci,y≡1(mod ni),M=n1*n2*n3*……),即可得到flag,这里直接上我的payload:
import gmpy2 e=3 n = [16067817932594307041570490664780805848472742222521209486359183294876659529608435557600537260250449433611595173684925374508467672404417859479495004093579610726032262914323802262015761804257474778421075371915604733039622965481151880946821099347099589181944483948769906556017986079391359211585782596464924468208449010284942962635113163737362978946256184113197172628780615797285233916435176242221439390878162794629364484926505774613228229646458189210171950867198879934364120504046273177961083687027937189811732509344365844834160229805810205081446686611488115226014344875552419979932806334691942178914927653481984541110621, 27220804436805864442162182442813759263069372128468811270228757759122242102746634331274204813645700606025198464757315069476396636457109385709010309093761124250367793217269514777894950749932026790104944920542415154470272710654996775902535083921322900858510081080526361203971974235685839596700898966986819478871421472486198215667112358892381840624555494963218129513959117765033488219148477371667129956523403726492811804971592929874287476692563269065787601147950636445646208059251015601569921025370871805357871922113088791024382926047840273911791193990034677955545643860434985638900984527560552087922124397003230357748287, 18003911632122599813425550392025295318460144538002420546091473342504066065913374478380723966510863927323450160422323963085439934919821408030000597030220444017446677275520530600602313223716913843706289020789546341254298514327568202682323289952838243830866298465249322960573348784191060837060844553425424656343221015762038900638842760791476620770787585512880263777811650363550291113188707834451876652168342500756621692207745249699478983220317963165032407100517970067554347460807373078643124640438035329791669756566825583763144347915561928759654089817337965531158175165510730703911869587267266225122572337924741504872421] c = [9879971463914625690975893241580185387981496369356734957012721513373144938753569045503323744985869516225432489622517950293366904764152664636972215860898639778481845669980292323448545868723176321988532040102362409575435129737188286227622375002577654117407187235639039788403421568330907783489740293783760374579674272228953702822209345735718037784007905107507640441789566148023418182843850856028272425280660185409774791229291736804113219546032069271224441643592470352853688723172019556711071350797050854277490132448056258928350601925843959503438270798312618141538795176843674864017991973083157087900179066637653967471786, 18601174471639330838673755997627097179717053665843260588739160926694895023115719989743218032177933064024790567417281962648968287556842258818888225805040849173826497707326525590383774570277339562504216146208571367319040674013938991326596042075188486353554578994481344994910413567203491400010042812019323116569805264327599429345975064505984904064402357370098622911816024581171930600566133580491190247014980742239289588062485016239992005485018607729737084787372336151888759198583123570341162243303928994460199822642294565067160393816192370390199699022295478284192467413238687379911409873590966380239175755869062503249758, 16232129131608810282413937706144487240626338624250308577834225698445782468881682329646696899789457330498386668165599055270602304521900866238477820450745745574235835329025428831975135564432471301944638869445512637388111199953848153394755434332731325017811903037131194504517921570433491911858368670794242170207150194844396867824699460595352243616284981999437646934978307049377044110514736105768616893202608779347282837560546402961227548577594166063494153158225233408919063945070416486278018607780042733335959208255707942063870095648981102997015240784176457028384300754675188591655968245197618705494443537255712721037015] N=n[0]*n[1]*n[2] res=0 for i in range(3): m=N//n[i] d,r,s=gmpy2.gcdext(n[i],m) #d=r*n[i]+s*m res+=c[i]*s*m x=res%N n=N m=gmpy2.iroot(gmpy2.mpz(x), e) print(m)
4.babyDES
main函数代码:
import os import base64 from Crypto.Util import number, strxor from flag import flag assert(len(flag) == 34) def gen_key(): return [os.urandom(17) for _ in range(8)] def rnd(x: bytes, k: bytes): assert(len(x) == 34) l = x[:17] r = x[17:] _r = l _l = strxor.strxor(strxor.strxor(r, k), l) return _l + _r def enc(x: bytes, keys): res = x for i in range(8): res = rnd(res, keys[i]) return res if __name__ == '__main__': test = os.urandom(34) keys = gen_key() enc_test = enc(test, keys) enc_flag = enc(flag.encode(), keys) print(base64.b64encode(test).decode()) print(base64.b64encode(enc_test).decode()) print(base64.b64encode(enc_flag).decode())
output.txt内容:
w4C2TsB73uEIwk14cvQMP9m/nakb+Wh1ZvF70o6BZuHy9w== 5+AplczBBKDQCWgudMjj8sLxU1K5mvFS7JS9xg1QdFxiJg== L03S5WraHoNkN//llN17IUicEn7gh9elR1s1L9KduKa9AQ==
我们得到了test的内容以及加密过的test内容和加密过的flag内容。我们只需要得到key的内容从而解密flag内容。
通过计算可以得到l8、r8和l、r的直接关系,因此我们就能求出结果。
这道题当时觉得太麻烦就没做,所以上一发官方payload:
import base64 from Crypto.Util import number, strxor def getK(a,enc_a): l=a[:17] r=a[17:] _l=enc_a[:17] _r=enc_a[17:] kl=strxor.strxor(strxor.strxor(r,l),_r) kr=strxor.strxor(_l,r) return [kl,kr] def dec(enc_a,kl,kr): _l=enc_a[:17] _r=enc_a[17:] r=strxor.strxor(_l,kr) l=strxor.strxor(strxor.strxor(_r,kl),r) return l+r test="w4C2TsB73uEIwk14cvQMP9m/nakb+Wh1ZvF70o6BZuHy9w==" enc_test="5+AplczBBKDQCWgudMjj8sLxU1K5mvFS7JS9xg1QdFxiJg==" enc_flag="L03S5WraHoNkN//llN17IUicEn7gh9elR1s1L9KduKa9AQ==" test=base64.b64decode(test.encode()) enc_test=base64.b64decode(enc_test.encode()) enc_flag=base64.b64decode(enc_flag.encode()) kkey=[] kkey=getK(test,enc_test) fle=dec(enc_flag,kkey[0],kkey[1]) print(fle)
5.babyHash
main函数代码:
import socketserver from Crypto.Util import number import itertools from flag import flag class HashHandler(socketserver.BaseRequestHandler): iv = b'"[\xc3\x02D( \xf1' def __padding(self, x: bytes): if len(x) % 8: pad_len = 8 - len(x) % 8 return x + bytes([pad_len] * pad_len) else: return x def __compress(self, x: bytes): num = number.bytes_to_long(x) r = pow(num, 361268568442343347925, 664882992644331722007361840306123225067) & (2 ** 128 - 1) m = int(bin(r)[2::2], 2) s = m ^ (num >> 64) return number.long_to_bytes(s) def md(self, m: bytes): m = self.__padding(m) h = self.iv for i in range(0, len(m), 8): subm = m[i: i+8] h = self.__compress(h + subm) return h def handle(self): self.request.sendall(b'input a: ') a = self.request.recv(1024)[:-1] self.request.sendall(b'input b: ') b = self.request.recv(1024)[:-1] if a != b and self.md(a) == self.md(b): self.request.sendall((flag + '\n').encode()) else: self.request.sendall(b'nononono') if __name__ == '__main__': HOST, PORT = '0.0.0.0', 12002 with socketserver.ThreadingTCPServer((HOST, PORT), HashHandler) as server: server.serve_forever()
代码整体就是收到对方发出的两组byte,判断二者是否相同,在进行MD5加密:现将两组64位平衡,之后在进行MD5操作。代码很难,如果从加密处攻入反正我是不知道可不可以qwq……其实代码中补全8位那里其实挺怪的,从这里可以作为突破口:
“1234567” #a “1234567\x01” #b
这样就可以满足所有要求!