2

我正在研究一个安全单元,并试图理解格式字符串攻击。有人可以尝试向我解释一下吗?

以下代码取自: 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的?

4

1 回答 1

3

“\x58\x74\x04\x08%d%n”是“外壳代码”。

该文档中非常仔细地解释了该漏洞利用。我想它希望您对堆栈帧的典型布局有所了解,这也在表格中进行了说明。请记住,堆栈地址通常会向下增长,这意味着“弹出”比实际传递给它的参数更多的函数调用将开始从它自己的堆栈帧中读取局部变量。这就是这个 shell 代码所利用的。

它将地址放在的前 4 个字节中buf(因为 snprintf 将其打印到那里),然后它跳过x变量(从它下面的帧),最后从第一部分读取地址buf(但解释为指针)并写入通过 %n 格式代码为其赋值。

于 2011-08-16T03:10:37.557 回答