/*

**************************
for education purpose only
iam not responsible for what you are doing with this software.
**************************

 /                /
(  ___  ___  ___ (
| |   )|   )|   )|
| |__/ |__/ |__/ |
  __/

  lgool   V 0.1

  written by l0om

	  WWW.EXCLUDED.ORG  -  l0om[a7]excluded[d07]org

  idea based on johnny longs gooscan and goole dorking itself. thanks john.

  this is a part of a proof-of-concept project in automate attacks with googles help.

  greets to goolemasters:
    murfie,klouw,ThePsyko,jimmyneutron,
    MILKMAN,Deadlink,crash_monkey,zoro25
          cybercide,wasabi

  greets to geeks/freaks/nice_people like:
  proxy, detach, takt, dna,
  maximilan, capt.boris, dr.dohmen,
  mattball


*/

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <netdb.h>

#define GOOGLE   "www.google.com"               //default google server to send query
#define PATTERN  "<font color=#008000>"          //indentifies links in googles results
#define RESULTS  "<font size=-1 color=#000000>" //show results

char *encode(char *str);                    // NULL on failure / the encoded query on success
int connect_me(char *dest, int port);       // -1 on failure   / connected socket on success
int grep_google(char *host, int port, int proxy, char *query, int mode, int start);

void help(char *usage);
void header(void);

int main(int argc, char **argv)
{
    int i, port, valswap, max = 0, only_results = 0, site = 0, proxl = 0;  // greets at proxy - this variable is dedicated to you ;D  h4h4h4
    char *host, *query = NULL;


    if(argc == 1) {
	help(argv[0]);
	return(1);
    } else for(i = 1; i < argc; i++)
	if(argv[i][0] == '-')
	    switch(argv[i][1]) {
		case 'V':
		    header();
		    return(0);
		case 'r':
		    only_results = 1;
		    break;
		case 'm':
		    max = atoi(argv[++i]);
		    break;
		case 'p':
		    if( (host = strchr(argv[++i], ':')) == NULL) {
			fprintf(stderr, "illegal proxy syntax   [host:port]\n");
			return(1);
		    }
		    port = atoi(strtok(host, ":"));
		    host = strtok(argv[i], ":");
		    proxl = 1;                   // "gib frei ich will rein"
		    break;
		case 'h':
		    help(argv[0]);
		    return(0);
	    } else query = argv[i];

    if(query == NULL) {
	fprintf(stderr, "no query!\n");
        help(argv[0]);
	return(1);
    }

    if( (query = encode(query)) == NULL) {
	fprintf(stderr, "string encoding faild!\n");
	return(2);
    }

    if(!max) {
	if(grep_google(host, port, proxl, query, only_results, site) > 0) return(0);
	else return(1);
    }

    for(i = 0; i < max; )
	if( (valswap = grep_google(host, port, proxl, query, only_results, (site+=10))) <= 0) return(1);
	else i+=valswap;

    return(0);
}

int grep_google(char *host, int port, int proxl, char *query, int mode, int site)
{
    unsigned int results = 0;
    int sockfd, nbytes, stdlen = 31, prxlen = 38+strlen(GOOGLE), buflen = 100;
    char *sendthis, *readbuf, *buffer, *ptr;

   if(proxl) {
       if( (sockfd = connect_me(host, port)) == -1)    // connect to proxy
	   return(-2);
       if( (sendthis = (char *)malloc(prxlen+strlen(query)+7)) == NULL) {
	   perror("malloc");
	   return(-1);
       } else sprintf(sendthis,"GET http://%s/search?q=%s&start=%d HTTP/1.0\n\n",GOOGLE,query,site);
    } else {
	if( (sockfd = connect_me(GOOGLE, 80)) == -1)
	    return(-2);
	if( (sendthis = (char *)malloc(stdlen+strlen(query)+7)) == NULL) {
	    perror("malloc");
	    return(-1);
	} else sprintf(sendthis, "GET /search?q=%s&start=%d HTTP/1.0\n\n",query,site);
    }

   if( (readbuf = (char *)malloc(255)) == NULL) {
       perror("malloc");
       return(-1);
   }
   if( (buffer = (char *)malloc(1)) == NULL) {
       perror("malloc");
       return(-1);
   }

   if(send(sockfd, sendthis, strlen(sendthis),0) <= 0)
       return(-2);

   while( (nbytes = read(sockfd, readbuf, 255)) > 0) {
       if( (buffer = (char *)realloc(buffer, buflen+=nbytes)) == NULL) {
	   perror("realloc");
	   return(-1);
       } else { strcat(buffer, readbuf); memset(readbuf, 0x00, 255); }
   }
   close(sockfd);

   ptr=buffer;
   while(buflen--)
       if(mode) {
	   if(memcmp(ptr++, RESULTS, strlen(RESULTS)) == 0) {
	       ptr += strlen(RESULTS)-1;
	       while(memcmp(ptr, "&", 1) != 0) {
		   if(memcmp(ptr, "<b>", 3) == 0) ptr+=3;
	           else if(memcmp(ptr, "</b>", 4) == 0) ptr+=4;
		   else printf("%c",*ptr++);
	       }
	   } else continue;
	   printf("\n");
	   return(0);
       } else
           if(memcmp(ptr++, PATTERN, strlen(PATTERN)) == 0) {
	   ptr += strlen(PATTERN)-1;
	   results++;
	   while(memcmp(ptr, " - ", 3) && buflen--) printf("%c",*ptr++);
           printf("\n");
	   }

   free(sendthis);
   free(readbuf);
   return(results);
}

char *encode(char *str)
{
    static char *query;
    char *ptr;
    int nlen, i;

    nlen = strlen(str)*3;
    if( (query = (char *)malloc(nlen)) == NULL) {
	perror("malloc");
	return(NULL);
    } else ptr = str;

    for(i = 0; i < nlen; i+=3)
	sprintf(&query[i], "%c%X",'%',*ptr++);
    query[nlen] = '\0';
    return(query);
}

int connect_me(char *dest, int port)
{
    int sockfd;
    struct sockaddr_in servaddr;
    struct hostent *he;

    if( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
	perror("socket");
	return(-1);
    }

    if( (he = gethostbyname(dest)) == NULL) {
	fprintf(stderr, "cannot resovle hostname\n");
	return(-1);
    }

    servaddr.sin_addr   = *((struct in_addr *) he->h_addr);
    servaddr.sin_port = htons(port);
    servaddr.sin_family = AF_INET;

    if(connect(sockfd, (struct sockaddr *)&servaddr, sizeof(struct sockaddr)) == -1) {
	perror("connect");
	return(-1);
    } else return(sockfd);
}

void help(char *usage)
{
    printf("%s help\n",usage);
    printf("%s <query> [options]\n");
    puts("options:");
    puts("-h:   this help menue");
    puts("-p:   request google with a proxy. next argument must be the proxy");
    puts("      and the port in the following format \"host:port\"");
    puts("-m:   next argument must be the count of results you want to see");
    puts("-V:   prints versions info");
    puts("-r:   prints only the results count and exit");
    puts("examples:");
    printf("%s \"filetype:pwd inurl:service.pwd\" -r  # show results\n");
    printf("%s \"filetype:pwd inurl:service.pwd\" -m 30  # print about 30 results\n");
}

void header(void)
{
    puts("\tlgool  V 0.2");
    puts("written by l0om - WWW.EXCLUDED.ORG - l0om[47]excluded[d07]org\n");
}

//phree the cyberspace !


