/*************************************************************************** * chimera.cc : This file is part of 'chimera' * * (c) 2003,2004 by Lukasz Tomicki * ****************************************************************************/ /* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "chimera.h" #include "new_on.h" #include "MemoryManager.h" using namespace std; FILE *hFile = 0; const char *passwd = 0; CServiceAttack *crack = 0; const char* get_single_passwd(bool r) { static bool t(true); if (r) { t = true; return 0; } if (t) { t = false; return ( passwd ); } else return 0; } /* rev 1.1.4 */ const char* get_passwd(bool r) { if (r) { rewind(hFile); return 0; } const char *p = CServiceAttack::get_next_line(hFile); if (!p) rewind(hFile); return ( p ); } void print_data(const char *p) { printf("%s", p); // fflush(stdout); } void deal_with_results(CServiceAttack::target_output_data *p) { char *ptr = 0; printf("service: "); // inet6_ntoa(p->addr.sin6_addr); switch (p->type) { case CServiceAttack::SERVICE_POP3: printf("pop3"); if (p->ipv6) printf(" host: %s port: %d user: %s password: %s\n", inet_ntoa(*((in_addr*)&p->addr.sin6_addr)), ntohs(p->addr.sin6_port), p->user, p->passwd ? p->passwd : "(null)"); else printf(" host: %s port: %d user: %s password: %s\n", inet_ntoa(((sockaddr_in*)&p->addr)->sin_addr), ntohs(((sockaddr_in*)&p->addr)->sin_port), p->user, p->passwd ? p->passwd : "(null)"); break; case CServiceAttack::SERVICE_FTP: printf("ftp"); if (p->ipv6) printf(" host: %s port: %d user: %s password: %s\n", inet_ntoa(*((in_addr*)&p->addr.sin6_addr)), ntohs(p->addr.sin6_port), p->user, p->passwd ? p->passwd : "(null)"); else printf(" host: %s port: %d user: %s password: %s\n", inet_ntoa(((sockaddr_in*)&p->addr)->sin_addr), ntohs(((sockaddr_in*)&p->addr)->sin_port), p->user, p->passwd ? p->passwd : "(null)"); break; case CServiceAttack::SERVICE_GG: printf("gg"); if (p->ipv6) printf(" host: %s port: %d user: %s password: %s\n", inet_ntoa(*((in_addr*)&p->addr.sin6_addr)), ntohs(p->addr.sin6_port), p->user, p->passwd ? p->passwd : "(null)"); else printf(" host: %s port: %d user: %s password: %s\n", inet_ntoa(((sockaddr_in*)&p->addr)->sin_addr), ntohs(((sockaddr_in*)&p->addr)->sin_port), p->user, p->passwd ? p->passwd : "(null)"); break; case CServiceAttack::SERVICE_TELNET: printf("telnet"); if (p->ipv6) printf(" host: %s port: %d user: %s password: %s\n", inet_ntoa(*((in_addr*)&p->addr.sin6_addr)), ntohs(p->addr.sin6_port), p->user, p->passwd ? p->passwd : "(null)"); else printf(" host: %s port: %d user: %s password: %s\n", inet_ntoa(((sockaddr_in*)&p->addr)->sin_addr), ntohs(((sockaddr_in*)&p->addr)->sin_port), p->user, p->passwd ? p->passwd : "(null)"); break; case CServiceAttack::SERVICE_IMAP: printf("imap"); if (p->ipv6) printf(" host: %s port: %d user: %s password: %s\n", inet_ntoa(*((in_addr*)&p->addr.sin6_addr)), ntohs(p->addr.sin6_port), p->user, p->passwd ? p->passwd : "(null)"); else printf(" host: %s port: %d user: %s password: %s\n", inet_ntoa(((sockaddr_in*)&p->addr)->sin_addr), ntohs(((sockaddr_in*)&p->addr)->sin_port), p->user, p->passwd ? p->passwd : "(null)"); break; case CServiceAttack::SERVICE_VNC: printf("vnc"); if (p->ipv6) printf(" host: %s port: %d user: %s password: %s\n", inet_ntoa(*((in_addr*)&p->addr.sin6_addr)), ntohs(p->addr.sin6_port), p->user, p->passwd ? p->passwd : "(null)"); else printf(" host: %s port: %d user: %s password: %s\n", inet_ntoa(((sockaddr_in*)&p->addr)->sin_addr), ntohs(((sockaddr_in*)&p->addr)->sin_port), p->user, p->passwd ? p->passwd : "(null)"); break; case CServiceAttack::SERVICE_NNTP: printf("nntp"); if (p->ipv6) printf(" host: %s port: %d user: %s password: %s\n", inet_ntoa(*((in_addr*)&p->addr.sin6_addr)), ntohs(p->addr.sin6_port), p->user, p->passwd ? p->passwd : "(null)"); else printf(" host: %s port: %d user: %s password: %s\n", inet_ntoa(((sockaddr_in*)&p->addr)->sin_addr), ntohs(((sockaddr_in*)&p->addr)->sin_port), p->user, p->passwd ? p->passwd : "(null)"); break; case CServiceAttack::SERVICE_SSH: printf("ssh"); if (p->ipv6) printf(" host: %s port: %d user: %s password: %s\n", inet_ntoa(*((in_addr*)&p->addr.sin6_addr)), ntohs(p->addr.sin6_port), p->user, p->passwd ? p->passwd : "(null)"); else printf(" host: %s port: %d user: %s password: %s\n", inet_ntoa(((sockaddr_in*)&p->addr)->sin_addr), ntohs(((sockaddr_in*)&p->addr)->sin_port), p->user, p->passwd ? p->passwd : "(null)"); break; case CServiceAttack::SERVICE_MYSQL: printf("mysql"); if (p->ipv6) printf(" host: %s port: %d user: %s password: %s\n", inet_ntoa(*((in_addr*)&p->addr.sin6_addr)), ntohs(p->addr.sin6_port), p->user, p->passwd ? p->passwd : "(null)"); else printf(" host: %s port: %d user: %s password: %s\n", inet_ntoa(((sockaddr_in*)&p->addr)->sin_addr), ntohs(((sockaddr_in*)&p->addr)->sin_port), p->user, p->passwd ? p->passwd : "(null)"); break; case CServiceAttack::SERVICE_LDAP: printf("ldap"); if (p->ipv6) printf(" host: %s port: %d user: %s password: %s\n", inet_ntoa(*((in_addr*)&p->addr.sin6_addr)), ntohs(p->addr.sin6_port), p->user, p->passwd ? p->passwd : "(null)"); else printf(" host: %s port: %d user: %s password: %s\n", inet_ntoa(((sockaddr_in*)&p->addr)->sin_addr), ntohs(((sockaddr_in*)&p->addr)->sin_port), p->user, p->passwd ? p->passwd : "(null)"); break; case CServiceAttack::SERVICE_HTTP: printf("http"); if (p->misc) { ptr = p->misc + 4; } if (p->ipv6) printf(" host: %s request: %s port: %d user: %s password: %s\n", inet_ntoa(*((in_addr*)&p->addr.sin6_addr)), ptr, ntohs(p->addr.sin6_port), p->user, p->passwd ? p->passwd : "(null)"); else printf(" host: %s request: %s port: %d user: %s password: %s\n", inet_ntoa(((sockaddr_in*)&p->addr)->sin_addr), ptr, ntohs(((sockaddr_in*)&p->addr)->sin_port), p->user, p->passwd ? p->passwd : "(null)"); break; case CServiceAttack::SERVICE_HTTP_PROXY: printf("http-proxy"); if (p->misc) { ptr = p->misc + 4; } if (p->ipv6) printf(" host: %s", inet_ntoa(*((in_addr*)&p->addr.sin6_addr))); else printf(" host: %s", inet_ntoa(((sockaddr_in*)&p->addr)->sin_addr)); printf(" proxy request: %s", ptr ? ptr : "http://www.google.com/"); if (p->ipv6) printf(" port: %d user: %s password: %s\n", ntohs(p->addr.sin6_port), p->user, p->passwd ? p->passwd : "(null)"); else printf(" port: %d user: %s password: %s\n", ntohs(((sockaddr_in*)&p->addr)->sin_port), p->user, p->passwd ? p->passwd : "(null)"); break; } fflush(stdout); delete p; } bool parse_command_line_args(CServiceAttack *p, int argc, char **argv) { CServiceAttack::target_input_data target_host; char *host = 0; char *host_file = 0; char *user_file = 0; bool ret(true); u16 port(0); uint mlevel(CServiceAttack::MSG_ERROR); FILE *hHost = 0; bool bHost = true; char *misc = 0; char *proxy_request = 0; char o; while ((o = getopt(argc, argv, "s:u:U:p:P:c:C:m:M:h:H:g:e:lqvt:T:nyrab:B:6")) != -1) { switch (o) { case 'b': p->set_thread_creation_speed(atoi(optarg)); break; case 'a': p->set_thread_reduction(false); break; case 's': if (!strcmp(optarg, "pop3")) target_host.type = CServiceAttack::SERVICE_POP3; else if (!strcmp(optarg, "ftp")) target_host.type = CServiceAttack::SERVICE_FTP; else if (!strcmp(optarg, "vnc")) target_host.type = CServiceAttack::SERVICE_VNC; else if (!strcmp(optarg, "gg")) target_host.type = CServiceAttack::SERVICE_GG; else if (!strcmp(optarg, "mysql")) target_host.type = CServiceAttack::SERVICE_MYSQL; else if (!strcmp(optarg, "http")) target_host.type = CServiceAttack::SERVICE_HTTP; else if (!strcmp(optarg, "http-proxy")) target_host.type = CServiceAttack::SERVICE_HTTP_PROXY; else if (!strcmp(optarg, "imap")) target_host.type = CServiceAttack::SERVICE_IMAP; else if (!strcmp(optarg, "telnet")) target_host.type = CServiceAttack::SERVICE_TELNET; else if (!strcmp(optarg, "ssh")) target_host.type = CServiceAttack::SERVICE_SSH; else if (!strcmp(optarg, "nntp")) target_host.type = CServiceAttack::SERVICE_NNTP; else if (!strcmp(optarg, "nntp")) target_host.type = CServiceAttack::SERVICE_LDAP; break; case 'u': target_host.user = alloc_copy(optarg); break; case 'U': user_file = alloc_copy(optarg); break; case 'p': passwd = alloc_copy(optarg); break; case 'P': if (!strcmp(optarg, "stdin")) hFile = stdin; else { hFile = fopen(optarg, "r"); if (!hFile) { printf("***unable to open password file\n"); perror("***fopen"); ret = false; goto clean_up; } } break; case 'c': switch (optarg[0]) { case '1': target_host.charset = "abcdefghijklmnopqrstuvwyxz"; break; case '2': target_host.charset = "abcdefghijklmnopqrstuvwyxzABCDEFGHIJKLMNOPQRSTUVWYXZ"; break; case '3': target_host.charset = "abcdefghijklmnopqrstuvwyxzABCDEFGHIJKLMNOPQRSTUVWYXZ1234567890"; break; case '4': target_host.charset = "abcdefghijklmnopqrstuvwyxzABCDEFGHIJKLMNOPQRSTUVWYXZ1234567890!@#$%^&*()_-+=]}[{'\";:/?.>,<\\|"; break; } break; case 'C': target_host.charset = alloc_copy(optarg); break; case 'm': target_host.min_chars = max(0, min(30, atoi(optarg))); break; case 'M': target_host.max_chars = max(0, min(30, atoi(optarg))); break; case 'h': host = alloc_copy(optarg); break; case 'H': host_file = alloc_copy(optarg); break; case '6': target_host.ipv6 = true; break; case 'g': proxy_request = alloc_copy(optarg); break; case 'e': port = max(0, atoi(optarg)); break; case 'l': #ifdef OPENSSL target_host.ssl = true; #else printf("***please compile chimera with OpenSSL support!\n"); #endif break; case 'q': mlevel = CServiceAttack::MSG_NONE; break; case 'v': mlevel = CServiceAttack::MSG_VERBOSE; break; case 't': p->set_threads(max(0, min(16384, atoi(optarg)))); break; case 'T': p->set_conn_timeout(atoi(optarg)); break; case 'B': p->set_conn_errors_max(atoi(optarg)); break; case 'n': target_host.passwd_options = CServiceAttack::PasswdOptions(target_host.passwd_options | CServiceAttack::PASSWD_OPTIONS_NULL); break; case 'y': target_host.passwd_options = CServiceAttack::PasswdOptions(target_host.passwd_options | CServiceAttack::PASSWD_OPTIONS_LOGIN); break; case 'r': target_host.passwd_options = CServiceAttack::PasswdOptions(target_host.passwd_options | CServiceAttack::PASSWD_OPTIONS_LOGIN_REV); break; } } p->set_output_level((CServiceAttack::MessageLevel) mlevel); p->set_output(print_data); p->set_notice(deal_with_results); if (!port) { switch (target_host.type) { case CServiceAttack::SERVICE_MYSQL: port = 3306; break; case CServiceAttack::SERVICE_SSH: port = 22; break; case CServiceAttack::SERVICE_FTP: if (!target_host.ssl) port = 21; else port = 990; break; case CServiceAttack::SERVICE_POP3: if (!target_host.ssl) port = 110; else port = 995; break; case CServiceAttack::SERVICE_HTTP: if (!target_host.ssl) port = 80; else port = 443; break; case CServiceAttack::SERVICE_HTTP_PROXY: if (!target_host.ssl) port = 8080; else port = 3128; break; case CServiceAttack::SERVICE_NNTP: if (!target_host.ssl) port = 119; else port = 563; break; case CServiceAttack::SERVICE_TELNET: if (!target_host.ssl) port = 23; else port = 992; break; case CServiceAttack::SERVICE_VNC: if (!target_host.ssl) port = 5900; else port = 5901; break; case CServiceAttack::SERVICE_IMAP: if (!target_host.ssl) port = 143; else port = 993; break; case CServiceAttack::SERVICE_LDAP: if (!target_host.ssl) port = 389; else port = 636; break; } } if (passwd) p->set_passwd_func(get_single_passwd); else if (hFile) { p->set_passwd_func(get_passwd); } else if (target_host.charset) { if (!target_host.min_chars) target_host.min_chars = 1; if (!target_host.max_chars) target_host.max_chars = 8; if (target_host.max_chars < target_host.min_chars) { printf("***incorrect value of max-chars. max-chars must be >= min-chars\n"); ret = false; goto clean_up; } } else if (!(target_host.passwd_options & CServiceAttack::PASSWD_OPTIONS_NULL) && !(target_host.passwd_options & CServiceAttack::PASSWD_OPTIONS_LOGIN) && !(target_host.passwd_options & CServiceAttack::PASSWD_OPTIONS_LOGIN_REV)) { printf("***no password source set. Use at least one of the below.\n"); printf(" a single password (-p password)\n"); printf(" a password file (-P password file)\n"); printf(" stdin (-P stdin)\n"); printf(" a pre-defined brute force charset (-c 1-4)\n"); printf(" a user-defined brute force charset (-C charset)\n"); printf(" null passwords (-n)\n"); printf(" passwords same as login (-y)\n"); printf(" passwords same as reversed login (-r)\n"); ret = false; goto clean_up; } if (target_host.type == CServiceAttack::SERVICE_NONE) { printf("***no service selected - use the syntax '-s service' to select one\n"); ret = false; goto clean_up; } if ((target_host.type == CServiceAttack::SERVICE_HTTP || target_host.type == CServiceAttack::SERVICE_HTTP_PROXY)) { char *ptr, *ptr2; if (proxy_request && (ptr2 = strstr(proxy_request , "://"))) { ptr2 += 3; if (ptr = index(ptr2, '/')) { u8 extra(0); if (*(ptr + strlen(ptr) - 1) != '/') extra = 1; u32 request_size = strlen(proxy_request) + extra + 1 /* null term */; u32 remote_path_size = (ptr - ptr2) + 1 /* null term */; u32 misc_size = 4 /* 4 byte request size */ + request_size /* request */ + 4 /* 4 byte remote path size */ + remote_path_size /* remote path */; misc = new char[misc_size]; memset(misc, 0, misc_size); *misc = request_size; memcpy(misc + 4, proxy_request, request_size - extra - 1); *(misc + request_size + 4) = remote_path_size; memcpy(misc + 8 + request_size, ptr2, remote_path_size - extra - 1); *(misc + 4 + request_size - 1) = 0; *(misc + 8 + request_size + remote_path_size - 1) = 0; if (extra) { *(misc + 4 + request_size - 2) = '/'; } target_host.misc_size = misc_size; target_host.misc = misc; } else { printf("***bad proxy request supplied. the proper format is:\n"); printf(" http://remote_server/remote_path/\n"); printf(" will default to http://www.google.com/"); } } else { if (target_host.type == CServiceAttack::SERVICE_HTTP) { printf("***no http request or bad request supplied.\n"); printf(" example: -g http://hostname/remote_server_path/\n"); ret = false; goto clean_up; } else { printf("***bad proxy request supplied. the proper format is:\n"); printf(" http://remote_server/remote_path/\n"); printf(" will default to http://www.google.com/"); } } } while (bHost) { if (host && port) { void *host_data = CServiceAttack::get_host_data(host, port, target_host.ipv6); if (!host_data) { perror("***unable to resolve host name"); ret = false; goto clean_up; } memcpy(&target_host.addr, host_data, sizeof(target_host.addr)); bHost = false; } else if (host_file) { hHost = fopen(host_file, "r"); if (!hHost) { printf("***unable to open hostname file\n"); perror("***fopen"); ret = false; goto clean_up; } } else { printf("***no hostname supplied\n"); bHost = false; continue; } FILE *hUser = 0; if (user_file) { hUser = fopen(user_file, "r"); if (!hUser) { printf("***unable to open username file\n"); perror("***fopen"); ret = false; goto clean_up; } if (hUser) { const char *user_name = 0; while (user_name = alloc_copy(CServiceAttack::get_next_line(hUser))) { target_host.user = user_name; p->add_target(target_host); } fclose(hUser); } } else { if (!target_host.user) { printf("***no username set\n"); ret = false; goto clean_up; } p->add_target(target_host); } } clean_up: if (host != 0) delete [] host; if (host_file != 0) delete [] host_file; if (user_file != 0) delete [] user_file; if (target_host.user != 0) delete [] target_host.user; if (target_host.charset != 0) delete [] target_host.charset; if (target_host.misc != 0) delete [] target_host.misc; if (proxy_request != 0) delete [] proxy_request; return ( ret ); } void clean_up() { if (passwd) delete [] passwd; if (hFile && hFile != stdin) fclose(hFile); if (crack) delete crack; } void print_usage() { puts("chimera - remote passwd cracking tool v0.29.6"); puts("(c) 2003,2004,2005 by Lukasz Tomicki "); puts(" usage: chimera [-s service] [-h host/IP] [-u/-U user/userlist]"); puts(" [-p/-P/-c/-C password/passwordlist/charset/user-charset] \n"); puts(" options:"); puts(" -s sets the service you want to attack to the given type"); puts(" ftp, http, http-proxy, imap, ldap, mysql, nntp, pop3, telnet"); puts(" -h host to attack"); puts(" -H sets a file of hosts to attack"); puts(" -e port to attack on the remote host (if not standard)"); //puts(" -6 use IPv6 (default: no)"); puts(" -u sets the user name for the service we are attacking"); puts(" -U sets a file of user names to use"); puts(" -p sets a passwd to check"); puts(" -P sets a file of passwords to check"); puts(" use 'stdin' to feed from standard input"); puts(" -n check for null passwords"); puts(" -y check for passwords same as the user name"); puts(" -r check for passwords same as the reversed user name"); puts(" -c use pre-defined charset"); puts(" 1 abcdefghijklmnopqrstuvwyxz"); puts(" 2 abcdefghijklmnopqrstuvwyxzABCDEFGHIJKLMNOPQRSTUVWYXZ"); puts(" 3 abcdefghijklmnopqrstuvwyxzABCDEFGHIJKLMNOPQRSTUVWYXZ1234567890"); puts(" 4 abcdefghijklmnopqrstuvwyxzABCDEFGHIJKLMNOPQRSTUVWYXZ1234567890"); puts(" !@#$%^&*()_-+=]}[{'\";:/?.>,<\\|\n"); puts(" -C sets a user-defined brute force charset"); puts(" example: -C qwerty1234567890\n"); puts(" -m mininum number of characters to use (default: 1)"); puts(" -M maximum number of characters to use (default: 8)"); puts(" -l use ssl (default: no)"); puts(" -t number of threads to use (default: 64)"); puts(" -T set connection timeout (default: 60) setting to zero means unlimited"); puts(" -B set max connection errors (default: 5) setting to zero means unlimited"); puts(" -b number of microseconds between creating new threads (default: 2500)"); puts(" -a do not reduce thread number on connection errors (experts only)"); puts(" -q quiet mode - output only successfully cracked accounts"); puts(" -v verbose mode - output every password attempt"); puts(" -g http request (only applicable for http and http-proxy attacks)"); puts(" mandatory for http attacks, optional for http-proxy"); puts(" format: http://remote_server/remote_path/"); puts(" default for http-proxy: http://www.google.com/"); } int main(int argc, char **argv) { if (argc == 1) { print_usage(); return 0; } crack = new CServiceAttack(); if (parse_command_line_args(crack, argc, argv)) crack->run_atack(); clean_up(); return (0); }