/* * ftelnetd - fake telnet daemon * * fake_get_login.c * Fakes the telnetd and router with its banner and data, which will be sent * after the three-way-handshake and which will be sent before RST! * * Tue Dec 12 22:47:31 CET 2006 * * by Levent Kayan * levent[at]corehack[dot]org * www.corehack.org */ #include "ftelnetd.h" #include "sighandle.h" #include "banner.h" #include "ferror.h" #include "wrapper.h" #include "log.h" #include #include #include #include /* max username and password length to read */ #define MAX_CHAR 24 /* fake mode */ extern int mode; extern int connfd; /* timeout messages and RST*/ void alarm_handle() { xwrite(connfd, banner[mode].timeout_msg, strlen(banner[mode].timeout_msg)); exit(EXIT_SUCCESS); } /* sends given telnet data and banner message */ int fake_banner_msg(int connfd) { /* telnet protocol handling and banner message */ xwrite(connfd, banner[mode].telnet_data, strlen(banner[mode].telnet_data)); return 1; } /* sends user string and gets user */ char *fake_get_user(int connfd) { char *user = NULL; /* we don't want to handle this, if $device doesn't need a user */ if (banner[mode].user_retries > 0) { /* sending user string, look at banner_t in banner.c! */ xwrite(connfd, banner[mode].user_string, strlen(banner[mode].user_string)); /* user timeout */ signal(SIGALRM, alarm_handle); alarm(banner[mode].time_out); user = xmalloc(MAX_CHAR); /* get user :) */ get_line(connfd, user, MAX_CHAR, 0xff); } return user; } /* sends pass string and gets pass */ char *fake_get_pass(int connfd) { char *pass = NULL; /* sending pass string, look at banner_t in banner.h! */ xwrite(connfd, banner[mode].pass_string, strlen(banner[mode].pass_string)); pass = xmalloc(MAX_CHAR); /* if mode is cisco, then we have to call our alarm_handle() for the * passsword timeout handle */ if (mode == 1) { signal(SIGALRM, alarm_handle); alarm(banner[mode].time_out); } /* get pass :) */ get_line(connfd, pass, MAX_CHAR, banner[mode].echo_char); return pass; } /* sends "access denied" message */ int fake_access_denied_msg(int connfd) { /* fake "access denied" message -> saying, that the passes were wrong ;) */ xwrite(connfd, banner[mode].ad_msg, strlen(banner[mode].ad_msg)); return 1; } int fake_login(struct sockaddr_in caddr, int connfd) { char *user = NULL; char *pass = NULL; char *ipaddr = NULL; uint16_t port = 0; int i = 0, j; int limit = 0; ipaddr = inet_ntoa(caddr.sin_addr); port = ntohs(caddr.sin_port); fake_banner_msg(connfd); /* some devices don't need a user */ limit = (banner[mode].user_retries == 0 ? 1 : banner[mode].user_retries); for (i = 0; i < limit; i++) { user = fake_get_user(connfd); for (j = 0; j < banner[mode].pass_retries; j++) { pass = fake_get_pass(connfd); log_login(user, pass, ipaddr, port); free(pass); /* how many time "pass wrong"-messages should be send? */ if ((j + 1) % banner[mode].timeout_flag == 0) { fake_access_denied_msg(connfd); } } free(user); } /* RST, close connection */ xshutdown(connfd, SHUT_RDWR); return 1; } /* EOF */