紀實:校內線上訓練——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 importos 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
這樣就可以滿足所有要求!