C 中的格式化字符串攻击
我正在研究安全单元,并试图理解格式字符串攻击。有人可以尝试向我解释一下吗?
以下代码取自: 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
来自哪里?
I'm studying a security unit and I'm attempting to understand format string attacks. Could somebody please attempt to explain this to me?
The following code is taken from: 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;
}
As I understand it, the %n
format specifier is used to read a specified address back into memory, then when printf
pops values off the stack, it should read our address. I can't seem to pull this off.
In the document, the following example is provided:
perl -e 'system "./fmtme", "\x58\x74\x04\x08%d%n"'
Where did \x58\x74\x04\x08%d%n
come from?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
“\x58\x74\x04\x08%d%n”是“shell代码”。
该文档中对该漏洞进行了非常详细的解释。我想它希望您对堆栈帧的典型布局有一些了解,表中也对此进行了解释。请记住,堆栈地址通常向下增长,这意味着“弹出”比实际传递给它的参数更多的参数的函数调用将开始从其自身下方的堆栈帧中读取局部变量。这就是这个 shell 代码所利用的。
它将一个地址放入
buf
的前 4 个字节中(因为 snprintf 将其打印到那里),然后跳过x
变量(从它下面的帧开始),最后读取buf 第一部分的地址(但解释为指针)并通过 %n 格式代码向其写入一个值。"\x58\x74\x04\x08%d%n" is the "shell code".
The exploit is explained very carefully in that document. I suppose it expects you to have some understanding of the typical layout of stack frames, which also is explained in the table . Keep in mind that stack addresses typically grows downwards, which means that a function call that "pops" more arguments than was actually passed to it will start reading local variables from the stack frame below its own. This is what this shell code exploits.
It puts an address in the first 4 bytes of
buf
(because snprintf prints it into there) and then it skips thex
variable (from the frame below it) and finally reads the address from the first part ofbuf
(but interpreted as a pointer) and write a value to it, via the %n format code.