/***************************************************************************
 *  chimera.cc : This file is part of 'chimera'
 *
 *  (c) 2003,2004 by Lukasz Tomicki <tomicki@o2.pl>
 *
 ****************************************************************************/

/*
 *  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 <tomicki@o2.pl>");
	puts(" usage: chimera [-s service] [-h host/IP] [-u/-U user/userlist]");
	puts("   [-p/-P/-c/-C password/passwordlist/charset/user-charset] <options>\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 <n> 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);
}
