hbctf---whatiscanary学习

题目中除了能栈溢出实在找不到其他能泄露信息的地方了。而且也没法修改GOT表,始终绕不过stack_chk_fail函数。感到无从下手。只到官方给WP了,才觉得自己基础太过浅薄了。

         如果我们仔细观察崩溃的信息,可以看到stack_chk_fail打印了我们在shell中键入的命令。

 

图1           stack_chk_fail打印程序执行命令

         这个进程名就是传递给main函数的那个argv[0]。

 

图2           stack_chk_fail源码

__stack_chk_fail调用了__fortify_fail函数,__fortify_fail函数调用了__libc_message函数。

 

图3           __fortify_fail函数实现

可以看到__libc_argv是一个指针数组。

那么它在什么时候被赋值的呢?搜索源码可以看到

 

图4           __libc_argv赋值的时机

 

图5          __libc_argv定义

init函数被链接进”.init_array”section中,这个section,其实是一个函数指针数组,放着在main函数执行前需要执行的函数指针。其中的函数会在程序的__libc_start_main中被调用。而编译器会提供一个init函数,用来循环遍历“.init_array”中的指针。

图6           __libc_start_main函数实现

 

图7         LIBC_START_MAIN函数实现

图8           在LIBC_START_MAIN函数中编译器提供的init函数被调用

在LIBC_START_MAIN函数中,init被调用。编译器提供的init函数会调用图4中libc中的init函数。

图9           执行完读取用户输入后

在接收用户输入后,观察栈可以看到,存放输入数据的起始地址是0xffffd04c,而__libc_argv地址在0xffffd134。

所以payload就是

payload = "x00"+"a"*0xe7 + p32(0x0804A0A0)

因为程序还计算输入的字符个数。所以最开始加上”x00”结束符。

原文地址:https://www.cnblogs.com/shangye/p/6692602.html