Full Disclosure mailing list archives

SRT2003-04-24-1532 - Options Parsing Tool library buffer overflows.


From: KF <dotslash () snosoft com>
Date: Thu, 24 Apr 2003 16:45:38 -0500

Secure Network Operations, Inc.           http://www.secnetops.com
Strategic Reconnaissance Team               research () secnetops com
Team Lead Contact                                 kf () secnetops com


Our Mission:
************************************************************************
Secure Network Operations offers expertise in Networking, Intrusion 
Detection Systems (IDS), Software Security Validation, and 
Corporate/Private Network Security. Our mission is to facilitate a 
secure and reliable Internet and inter-enterprise communications 
infrastructure through the products and services we offer. 


Quick Summary:
************************************************************************
Advisory Number         : SRT2003-04-24-1532.txt
Product                 : Options Parsing Tool shared library
Version                 : <= opt-3.18
Vendor                  : http://nis-www.lanl.gov/~jt/
Class                   : local
Criticality             : Low 
Operating System(s)     : Linux (other unix based?)


High Level Explanation
************************************************************************
High Level Description  : Error messages can cause buffer overflow 
What to do              : recompile and link against newest libopt.a

Technical Details
************************************************************************
Proof Of Concept Status : No PoC needed for this issue. 
Low Level Description   : 

The Options Parsing Tool shared library is a subroutine library which 
facilitates the convenient input of parameters to a C or C++ program.
The package attempts to provide a direct and relatively full-featured 
input interface to the end user of the program, and at the same time 
impose a minimal amount of work on the programmer to "attach" the package 
to his or her software.

I am not aware of any suid programs linking against this library but 
at the very least Debian provides it as a .deb package. Obvious issues 
are raised if a suid application makes use of the OPT libraries. 
http://packages.debian.org/stable/devel/opt.html

The error messages in opt pass through one of several functions in order
to print the error to the screen. Either opt_warn_1(), opt_warn_2(), 
opt_warn_3(), opt_fatal_1(), opt_fatal_2(), or opt_fatal_3() will be 
used when an error occurs. Several similar functions could cause issues
with buffer overflows. 

This simple test will show the problems associated with using <= opt-3.18

[dotslash@vegeta test]$ cat > test.c
main(int *argc, char **argv)
{
        /* use lubc atoi() */
        int x = atoi(argv[1]);
        printf("atoi(): %i\n", x);

        /* use OPT opt_atoi() */
        int y = opt_atoi(argv[2]);
        printf("opt_atoi(): %i\n", y);
}

[dotslash@vegeta test]$ cc -o test test.c ../src/libopt.a
[dotslash@vegeta test]$ ./test 1 2
atoi(): 1
opt_atoi(): 2

[dotslash@vegeta test]$ ./test `perl -e 'print "A" x 986'` B
atoi(): 0
OPT Warning: String [B] is not a valid integer, will use [0]
opt_atoi(): 0

[dotslash@vegeta test]$ ./test A `perl -e 'print "A" x 986'`
atoi(): 0
OPT Warning: String
[AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA...
is not a valid integer, will use [0]
opt_atoi(): 0
Segmentation fault

strace tells us that we are able to overwrite the eip. 
[41414141] --- SIGSEGV (Segmentation fault) @ 0 (0) ---

This occurs because of the following code is triggered when reading
input from the user. 

long
opt_atoi(char *s)
{
  int valid;
  long x;
  x = (long)atof(s); /* Call atof() whether or not string is valid,
                      * because some strings, eg '15x' can still be
                      * interpreted as numeric.  But give a warning
                      * unless the string really is valid
                      */

  valid = opt_isvalidnumber(s);
  if (!valid || (valid & OPT_NUM_FLOAT)) {
    opt_warn_2("String [%s] is not a valid integer, will use [%ld]",s,x);
  }
  return x;
}

This particular segfault was caused by the opt_warn_2 definition in opt_p.h. 
You can see that the data passed on by the user is used in a sprintf() into 
a static sized buffer. 

#define OPT_ERRMAXSTRLEN 1024  /* shouldn't be fixed length, but it is! */
...
#define opt_warn_2(fmt,var1,var2) do { \
    char gstr[OPT_ERRMAXSTRLEN]; sprintf(gstr,fmt,var1,var2); \
        opt_warning(gstr); } while(0)

A diff with the new version shows the implementation of snprintf as a valid fix. 

<     char gstr[OPT_ERRMAXSTRLEN]; sprintf(gstr,fmt,var1,var2,var3); \
---
    char gstr[OPT_ERRMAXSTRLEN]; \
        opt_snprintf_3(gstr,OPT_ERRMAXSTRLEN,fmt,var1,var2,var3); \

A quick test compile against the new version of libopt.a appears to take care 
of the problem.

[dotslash@vegeta test]$ pwd
/home/dotslash/opt/opt-3.19/test
[dotslash@vegeta test]$ cc -o test test.c ../src/libopt.a

[dotslash@vegeta test]$ ltrace ./test A `perl -e 'print "A" x 1986'`
...
snprintf("String [AAAAAAAAAAAAAAAAAAAAAAAA"..., 1024, "String [%s] is not a valid integ"...

Patch or Workaround     : Relink applications that use libopt.a against the 
new version of opt at http://nis-www.lanl.gov/~jt/Software/opt/opt-3.19.tar.gz

Vendor Status           : Author has responded and applied a fix to the problem.

Bugtraq URL             : to be assigned

------------------------------------------------------------------------
This advisory was released by Secure Network Operations,Inc. as a matter
of notification to help administrators protect their networks against
the described vulnerability. Exploit source code is no longer released
in our advisories. Contact research () secnetops com for information on how
to obtain exploit information.


Current thread: