参见https://bbs.ichunqiu.com/thread-44069-1-1.html最后一题的分析
首先,SSP利用的是当canary检查失败时候,__stack_chk_fail
中打印程序名时可以泄露内存信息。
而如果我们用socat开程序然后即使转发了stderr,远程打进来的时候也获取不到*** stack smashing detected ***...
的信息。我们用socat把题目搭建起来,发现脚本失效,io.recv()读不到输出,输出只能在socat所在的服务器端显示

理论上这个信息应该在stderr中输出才对。

显然,我们需要继续挖掘__libc_message (2, "*** %s ***: %s terminated\n",msg, __libc_argv[0] ?: "<unknown>");
这行代码。
我们查看__libc_message()这个函数的实现
void
__libc_message (int do_abort, const char *fmt, ...)
{
va_list ap;
va_list ap_copy;
int fd = -1;
.......................//为节省篇幅省略部分无关代码,下同
/* Open a descriptor for /dev/tty unless the user explicitly
requests errors on standard error. */
const char *on_2 = __secure_getenv ("LIBC_FATAL_STDERR_");
if (on_2 == NULL || *on_2 == '\0')
fd = open_not_cancel_2 (_PATH_TTY, O_RDWR | O_NOCTTY | O_NDELAY);
if (fd == -1)
fd = STDERR_FILENO;
...........................
}
这个函数在运行的时候会去搜索一个叫做LIBC_FATAL_STDERR_
的环境变量,如果没有搜索到或者其值为\x00
,则把输出的fd设置为TTY
,否则才会把fd设置成STDERR_FILENO
,即错误输出到stderr
。所以我们部署的时候需要给shell设置环境变量

此时我们再用加了参数stderr的命令搭建题目,测试成功。

网友评论