Visit our newest sister site!
Hundreds of free aircraft flight manuals
Civilian • Historical • Military • Declassified • FREE!

TUCoPS :: Linux :: General :: bt51.txt

Options Parsing Tool library buffer overflows.

X-Enigmail-Supports: pgp-inline, pgp-mime
Content-Type: multipart/mixed;
X-Spam-Status: No, hits=1.1 required=5.0 tests=LARGE_HEX version=2.20
X-Spam-Level: *

Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit

Content-Type: text/plain;
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;

Secure Network Operations, Inc. 
Strategic Reconnaissance Team	  
Team Lead Contact		        

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			:
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.

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
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. 

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
[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

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 for information on how
to obtain exploit information.


TUCoPS is optimized to look best in Firefox® on a widescreen monitor (1440x900 or better).
Site design & layout copyright © 1986-2015 AOH