我正在研究一个安全部门,我正在尝试理解格式字符串攻击。有人可以试着向我解释一下吗?
以下代码来自:http://julianor.tripod.com/bc/tn-usfs.pdf:
/*
* fmtme.c
* Format a value into a fixed-size buffer
*/
#include <stdio.h>
int
main(int argc, char **argv)
{
char buf[100];
int x;
if(argc != 2)
exit(1);
x = 1;
snprintf(buf, sizeof buf, argv[1]);
buf[sizeof buf - 1] = 0;
printf("buffer (%d): %s\n", strlen(buf), buf);
printf("x is %d/%#x (@ %p)\n", x, x, &x);
return 0;
}
据我所知,%n
格式说明符用于将指定的地址读回内存,然后当printf
从堆栈中弹出值时,它应该读取我们的地址。我似乎无法解决这个问题。
在文档中,提供了以下示例:
perl -e 'system "./fmtme", "\x58\x74\x04\x08%d%n"'
\x58\x74\x04\x08%d%n
来自哪里?
答案 0 :(得分:3)
“\ x58 \ x74 \ x04 \ x08%d%n”是“shell代码”。
该文档中非常仔细地解释了漏洞利用。我想它希望您对堆栈帧的典型布局有所了解,这也在表中进行了解释。请记住,堆栈地址通常会向下增长,这意味着一个“弹出”参数比实际传递给它的函数调用将开始从它自己的堆栈框架中读取局部变量。这就是这个shell代码所利用的。
它在buf
的前4个字节中放置一个地址(因为snprintf将其打印到那里),然后它跳过x
变量(从它下面的帧),最后从中读取地址buf
的第一部分(但被解释为指针)并通过%n格式代码向其写入值。