Nmap Development mailing list archives

Re: GSoC : Proxy support with working Code


From: Rahul Golwalkar <rahulgolwalkar () gmail com>
Date: Mon, 29 Mar 2010 19:10:59 +0530

Comments Please.

On 28 March 2010 10:55, Rahul Golwalkar <rahulgolwalkar () gmail com> wrote:

Hello Everyone,
     Having used nmap for some time I realised the need for proxy support
in nmap. Later I found out that the it was in the TODO list at
http://nmap.org/svn/docs/TODO  (proxy server = relay server)
    As such adding this facility will make nmap more useful as a security
assessment tool and has got several advantages but had has got some
difficulties too in achieving this ability. The benefits and the
difficulties faced are classified as follows

Benefits:
     By adding this support one can route the port scanning through TOR or
an anonymous proxy server, thus concealing his identity.
     Secondly, any person who is forced to use internet via a proxy
server(generally those people using internet while in some organization or
institution) shall be able to use nmap normally.

Difficulties:
   Many times a proxy server does not support all the types of request. As
in, by default a Squid proxy server will not support the CONNECT request on
any port except for port 443. But I guess this short coming cannot be
resolved easily.
   The other problems faced are that it would be really difficult to
program the SYN scanning or the FIN scanning as we cannot manipulate the
packets that are sent by the proxy server.

I have written a sample working code that works for the following set of
constraints.
The Proxy server should be an "http proxy server"(i.e. not SOCKS) and
should support CONNECTing to all port numbers. And shall work only on port
numbers less than 1024. The program tries to CONNECT to each port and waits
for 5 seconds for a response.

I have used multithreading to speed up the port scanning using 10
simultaneous threads(u may increase the threads to speed up the process)
Here is a video of its demo. http://www.youtube.com/watch?v=p9lZ1NRN7c8
I have tested it in Vista with Cygwin along with CCproxy as the proxy
server ,as well as in Ubuntu with squid as the proxy server.  Am attaching
the C source code as well as the windows binary.

@developers: PLEASE SUGGEST WHAT IMPROVEMENTS SHOULD I ADD TO THIS TO MAKE
IT  GOOD GSoC PROPOSAL

Thank You
Rahul Golwalkar

usage :  nproxy.exe [http proxy server] [proxy port] [target address]
[starting port range] [stop port range]
eg. nproxy.exe proxy.server.com 3128 target.com 75 90

nproxy.c

#include<stdio.h>
#include<stdlib.h>
#include<pthread.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <sys/wait.h>
#include <signal.h>
#include <sys/poll.h>
#define MAX_THREADS 10     //Vary this number to create threads as many as
u like
void *functionC();
char host[20];
char proxy[20];
char pport[4];
int port_state[1024]={0};
int main(int argc,char *argv[])
{
    int start=75,stop=82,i,j,temp;
    pthread_t thread_id[MAX_THREADS];
    int counter ;
    counter = start;
    if(argc != 6)
    {
        fprintf(stderr,"Usage: nproxy [proxy server] [proxy port] [dest.
host] [start port range] [stop port range]");
        exit(0);
    }
    strcpy(proxy,argv[1]);       //Converting Args to preferrend names
    strcpy(pport,argv[2]);
    strcpy(host,argv[3]);
    start = atoi(argv[4]);
    stop = atoi(argv[5]);
    while(counter <= stop)
    {
        for( i=0;i<MAX_THREADS && counter <= stop;i++)
        {

            pthread_create(&thread_id[i],NULL,&functionC, counter);
//Multithreading
            counter++;

        }
        temp = i;
        for(i=0;i<temp;i++)
        {
            pthread_join(thread_id[i],NULL);
        }


    }

    for(i=start;i<=stop;i++)
    {
        if(port_state[i]==1)
            fprintf(stderr,"\n%d    open",i);
        else
            fprintf(stderr,"\n%d    timeout",i);
    }

    return 0;

}
void *functionC(int ptr)       // function that scans a single port
{

    //fprintf(stderr,"======== %d",ptr);

    struct addrinfo hints , *res;
    struct pollfd  fds[1];
    int sockfd,k=0;

    char buf[100],msg[50],c_port[4];
    char *msg1 = " \r\n\r\n";
    int len, bytes_sent;

   /*Creating the String to CONNECT*/
    strcat(msg,"CONNECT ");     // msg = "CONNECT google.com:80 \r\n\r\n";
    strcat(msg,host);
    strcat(msg,":");
    sprintf(c_port,"%d",ptr);
    strcat(msg,c_port);
    strcat(msg,msg1);            // fprintf(stderr,"%s",msg);

    memset(&hints,0,sizeof(hints));

    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM ;

    getaddrinfo(proxy,pport,&hints,&res);
    sockfd = socket(res->ai_family,res->ai_socktype,res->ai_protocol);
    fds[0].fd = sockfd;
    fds[0].events = POLLIN ;
    if(connect(sockfd,res->ai_addr,res->ai_addrlen)==-1)
        fprintf(stderr,"Relay server down\n");
    len = strlen(msg);
    bytes_sent = send(sockfd,msg,len,0);
    if(poll(fds,1,5000)>0)            //waiting for 5 secs for a reply
    {
        recv(sockfd,buf,99,0);
        if(strstr(buf,"200")!=NULL)
        {
             port_state[ptr]=1;      //fprintf(stderr,"open");
        }

    }
   else
   {}          //fprintf(stderr,"timeout");

}


_______________________________________________
Sent through the nmap-dev mailing list
http://cgi.insecure.org/mailman/listinfo/nmap-dev
Archived at http://seclists.org/nmap-dev/


Current thread: