/*
* 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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
/* 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 */
syntax highlighted by Code2HTML, v. 0.9.1