http隧道版lcx

标 题:  【原创】http隧道版lcx
作 者: wwwkx
时 间: 2013-03-10,10:07:45
链 接: http://bbs.pediy.com/showthread.php?t=165143

潜水好几年了,还没有发过贴,这个工具是我几年前为了突破代理网络,在lcx源码的基础上改进的,http隧道通讯代码是在pcshare里面扣出来的,主要完成改的是-listen和-slave那块,-trans因为没有用到,所以就没有改。
   代码虽然有点粗糙,但工具用起来效果还不错,拿出来和大家分享一下。废话不多说了,看代码。

//-listen参数的主要功能函数
//说明:与普通套接字可以双向收发信息不通的是 http隧道一般只支持数据单向传输,所以采用http隧道需要建立两个连接通道。
void httpbind2bind(int port1, int port2)
{
  SOCKET fd1,fd2, sockfd2;
  SOCKET SoSend, SoRecv;
  struct sockaddr_in client1,client2;
  int size1,size2;
  int nCmd;

  HANDLE hThread=NULL;
  httptransocket hsock;
  DWORD dwThreadID;
  
  if((fd1=create_socket())==0) return;
  if((fd2=create_socket())==0) return;
  
  printf("[+] Listening port %d ......\r\n",port1);
  fflush(stdout);
  
  if( (fd1 = StartTcp(port1))==SOCKET_ERROR)
  {
    closesocket(fd1);
    return;
  }
  
  printf("[+] Listen OK!\r\n");
  printf("[+] Listening port %d ......\r\n",port2);
  fflush(stdout);
  if(create_server(fd2, port2)==0)
  {
    closesocket(fd2);
    return;
  }
  
  
  printf("[+] Listen OK!\r\n");
  size1=size2=sizeof(struct sockaddr);
  while(1)
  {    
    printf("[+] Waiting for Client on port:%d ......\r\n",port1);
    //建立接收通道
    if((SoSend = accept(fd1,(struct sockaddr *)&client1,&size1))<0)
    {
      printf("[-] Accept Recv Socket error.\r\n");
      continue;
    }

    nCmd = AcceptClientMain(SoSend);   //去掉http头部信息,获取命令
    if(nCmd == -1){ 
      closesocket(SoSend); 
      printf("[-] Accept Recv Socket error.\r\n");
      continue; 
    }


    if( !SendKeepAlive(SoSend) )    //发送数据包,保持连接。    
    {
      closesocket(SoSend);
      printf("[-] Accept Recv Socket error.\r\n");
      continue;
    }
    
    
    printf("[+] Accept a Recv Socket on port %d from %s ......\r\n", port1, inet_ntoa(client1.sin_addr));

    //建立发送通道
    if((SoRecv = accept(fd1,(struct sockaddr *)&client1,&size1))<0)
    {
      printf("[-] Accept Send Socket error.\r\n");
      closesocket(SoRecv);
      continue;
    }

    nCmd = AcceptClientMain(SoRecv);
    if(nCmd == -1){ 
      closesocket(SoRecv);
      closesocket(SoSend);
      printf("[-] Accept Send Socket error.\r\n");
      continue; 
    }

    printf("[+] Accept a Send Socket on port %d from %s ......\r\n", port1, inet_ntoa(client1.sin_addr));

    //建立另一个端口的接收通道,改通道一般来说是本地连接,采用普通sock通信比如mstsc.exe    
    printf("[+] Waiting another Client on port:%d....\r\n", port2);
    if((sockfd2 = accept(fd2, (struct sockaddr *)&client2, &size2))<0)
    {
      printf("[-] Accept2 error.\r\n");
      closesocket(SoRecv);
      closesocket(SoSend);
      continue;
    }
    
    printf("[+] Accept a Client on port %d from %s\r\n",port2, inet_ntoa(client2.sin_addr));
    printf("[+] Accept Connect OK!\r\n");
    
                //创建转发线程
    hsock.SoSend = SoSend;
    hsock.SoRecv = SoRecv;
    hsock.fd2    = sockfd2;
    
    HANDLE hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)httpLocaltransmit,(LPVOID)&hsock, 0, &dwThreadID); 
    if(hThread == NULL) 
    {
      TerminateThread(hThread, 0);
      return;
    }
    
    Sleep(1000);
    printf("[+] CreateThread OK!\r\n\n");
  }
}

//http转发线程函数
//说明,有三个通讯套接字
//SoSend用于http隧道通讯发送数据
//SoRecv用于http隧道通讯接收数据
//fd2用于和本地进程进行数据收发,普通sock通讯。
void httpLocaltransmit(LPVOID data)
{
  SOCKET SoSend, SoRecv, fd2;
  httptransocket *hsock;
  struct timeval timeset;
  fd_set readfd,writefd;
  int result,i=0;
  char read_in1[MAXSIZE],send_out1[MAXSIZE];
  char read_in2[MAXSIZE],send_out2[MAXSIZE];
  int read1=0,totalread1=0,send1=0;
  int read2=0,totalread2=0,send2=0;
  int sendcount1;//,sendcount2;
  int maxfd;
  struct sockaddr_in client1,client2;
  int structsize1,structsize2;
  char host1[20],host2[20];
  int port1=0,port2=0;
  char tmpbuf[100];
  
  hsock = (httptransocket *)data;
  SoSend = hsock->SoSend;
  SoRecv = hsock->SoRecv;
  fd2    = hsock->fd2;
  
  memset(host1,0,20);
  memset(host2,0,20);
  memset(tmpbuf,0,100);
  
  structsize1=sizeof(struct sockaddr);
  structsize2=sizeof(struct sockaddr);
  
  if(getpeername(SoSend,(struct sockaddr *)&client1,&structsize1)<0)
  {
    strcpy(host1, "fd1");
  }
  else
  { 
    printf("[+]got, ip:%s, port:%d\r\n",inet_ntoa(client1.sin_addr),ntohs(client1.sin_port));
    strcpy(host1, inet_ntoa(client1.sin_addr));
    port1=ntohs(client1.sin_port);
  }
  
  if(getpeername(fd2,(struct sockaddr *)&client2,&structsize2)<0)
  {
    strcpy(host2,"fd2");
  }
  else
  { 
    printf("[+]got, ip:%s, port:%d\r\n",inet_ntoa(client2.sin_addr),ntohs(client2.sin_port));
    strcpy(host2, inet_ntoa(client2.sin_addr));
    port2=ntohs(client2.sin_port);
  }
  
  printf("[+] Start Transmit (%s:%d <-> %s:%d) ......\r\n\n", host1, port1, host2, port2);
  
  maxfd=max(max(SoRecv, SoSend),fd2)+1;
  memset(read_in1,0,MAXSIZE);
  memset(read_in2,0,MAXSIZE);
  memset(send_out1,0,MAXSIZE);
  memset(send_out2,0,MAXSIZE);
  
  timeset.tv_sec=TIMEOUT;
  timeset.tv_usec=0;
  
  while(1)
  {
    FD_ZERO(&readfd);
    FD_ZERO(&writefd);
    
    FD_SET((UINT)SoRecv, &readfd);
    FD_SET((UINT)SoSend, &writefd);
    FD_SET((UINT)fd2, &writefd);
    FD_SET((UINT)fd2, &readfd);
    
    result=select(maxfd,&readfd,&writefd,NULL,×et);
    if((result<0) && (errno!=EINTR))
    {
      printf("[-] Select error.\r\n");
      break;
    }
    else if(result==0)
    {
      printf("[-] Socket time out.\r\n");
      break;
    }
    
    if(FD_ISSET(SoRecv, &readfd))
    {
      /* must < MAXSIZE-totalread1, otherwise send_out1 will flow */
      if(totalread1 < MAXSIZE) {
        if( !ReadBag(SoRecv,read_in1,read1) )
        {
          printf("[-] Read SoRecv data error,maybe close?\r\n");
          break;
        }
        
        if( read1 > 0 )
        {
          memcpy(send_out1+totalread1,read_in1,read1);
          //sprintf(tmpbuf,"\r\nRecv %5d bytes from %s:%d\r\n", read1, host1, port1);
          printf(" Recv %5d bytes %16s:%d\r\n", read1, host1, port1);
          //makelog(tmpbuf,strlen(tmpbuf));
          //makelog(read_in1,read1);
          totalread1+=read1;
          memset(read_in1,0,MAXSIZE);
        }
        
      }
    }
    
    if(FD_ISSET(fd2, &writefd))
    {
      int err=0;
      sendcount1=0;
      while(totalread1>0)
      {
        send1=send(fd2, send_out1+sendcount1, totalread1, 0);
        if(send1==0)break;
        if((send1<0) && (errno!=EINTR))
        {
          printf("[-] Send to fd2 unknow error.\r\n");
          err=1;
          break;
        }
        
        if((send1<0) && (errno==ENOSPC)) break;
        sendcount1+=send1;
        totalread1-=send1;
        
        printf(" Send %5d bytes %16s:%d\r\n", send1, host2, port2);
      }
      
      if(err==1) break;
      if((totalread1>0) && (sendcount1>0))
      {
        /* move not sended data to start addr */
        memcpy(send_out1,send_out1+sendcount1,totalread1);
        memset(send_out1+totalread1,0,MAXSIZE-totalread1);
      }
      else
        memset(send_out1,0,MAXSIZE);
    }
    
    if(FD_ISSET(fd2, &readfd))
    {
      if(totalread2 < MAXSIZE) {
        read2=recv(fd2,read_in2,MAXSIZE-totalread2, 0); 
        if(read2==0)break;
        if((read2<0) && (errno!=EINTR))
        {
          printf("[-] Read fd2 data error,maybe close?\r\n\r\n");
          break;
        }
        
        memcpy(send_out2+totalread2,read_in2,read2);
        sprintf(tmpbuf, "\r\nRecv %5d bytes from %s:%d\r\n", read2, host2, port2);
        printf(" Recv %5d bytes %16s:%d\r\n", read2, host2, port2);
        makelog(tmpbuf,strlen(tmpbuf));
        makelog(read_in2,read2);
        totalread2+=read2;
        memset(read_in2,0,MAXSIZE);
      }
    }
    
    if(FD_ISSET(SoSend, &writefd))
    {
      int err2=0;
      if(totalread2>0)
      {
        if( !SendBag(SoSend, send_out2, totalread2) )
        //send2=send(SoSend, send_out2+sendcount2, totalread2, 0);
        //if(send2==0)break;
        //if((send2<0) && (errno!=EINTR))
        {
          printf("[-] Send to fd1 unknow error.\r\n");
          err2=1;
          break;
        }
        //if((send2<0) && (errno==ENOSPC)) break;
        //sendcount2+=send2;
        //totalread2-=send2;
        
        printf(" Send %5d bytes %16s:%d\r\n", totalread2, host1, port1);
      }
      if(err2==1) break;

      totalread2 = 0;
      memset(send_out2,0,MAXSIZE);
    }
    
    Sleep(5);
  }

  closesocket(SoRecv);
  closesocket(SoSend);
  closesocket(fd2);

  if(method == 3)
  connectnum --;

  printf("\r\n[+] OK! I Closed The Three Socket.\r\n"); 
}

//-slave主要函数实现
//该函数功能简单,建立反向连接通道后,创建httptransmitdata2线程函数转发。
void httpconn2conn(char *host1,int port1,char *host2,int port2)
{
    
  SOCKET sockfd2;
  
  HANDLE hThread=NULL;
  httptransocket2 sock;
  DWORD dwThreadID;

  

  DWORD l;
  char buffer[MAXSIZE];
      
  while(1)
  {    
    if((sockfd2=create_socket())==0) return;

    printf("[+] Make a Connection to %s:%d....\r\n",host1,port1);
    fflush(stdout);

    CMyHttpPipeBase *MyPipe = new CMyHttpPipeBase;                  
    //创建接收和发送管道    
    if(!MyPipe->StartWork(host1, port1) ) 
    {
      MyPipe->StopWork();
      continue;
    }
    
    l=0;
    memset(buffer,0,MAXSIZE);
    while(1)
    {
      if( !MyPipe->ReadBag(buffer,l) )
      //if( (l = MyPipe->RecvData(buffer, MAXSIZE)) == -1 )
        break;

      if(l==0) 
      { 
        Sleep(5);
        continue;
      }

      break;
    }
    
    if(l<=0) 
    { 
      printf("[-] There is a error...Create a new connection.\r\n");
      MyPipe->StopWork();
      continue;
    }
      
    while(1)
    {
      printf("[+] Connect OK!\r\n");
      printf("[+] Make a Connection to %s:%d....\r\n", host2,port2);
      fflush(stdout);

      if(client_connect(sockfd2,host2,port2)==0) 
      {
        closesocket(sockfd2);
        continue;
      }
      
      if( !SendData(sockfd2,buffer,(int&)l) )
      //if(send(sockfd2,buffer,l,0)==SOCKET_ERROR)
      { 
        printf("[-] Send failed.\r\n");
        continue;
      }
      
      l=0;
      memset(buffer,0,MAXSIZE);
      break;
    }
    
    printf("[+] All Connect OK!\r\n");
    
    sock.MyPipe = (void *)MyPipe;
    sock.fd2    = sockfd2;
    
    hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)httpRemotetransmit, (LPVOID)&sock, 0, &dwThreadID); 
    if(hThread == NULL) 
    {
      TerminateThread(hThread, 0);
      return;
    }
    
    connectnum++;
    
    Sleep(1000);
    printf("[+] CreateThread OK!\r\n\n");
    WaitForSingleObject(hThread, INFINITE);
  }
}

//实现数据转发,与httptransmitdata有所不同,主要处理远程进程的数据收发,与远程进行使用的是普通sock通讯,转发通道使用了两个http通讯pipe。
void httpRemotetransmit(LPVOID data)
{
  SOCKET fd2;
  httptransocket2 *hsock;
  struct timeval timeset;
  fd_set readfd;
  int result,i=0;
  char read_in2[MAXSIZE],send_out2[MAXSIZE];
  int read2=0,totalread2=0,send2=0;


  int structsize2;
  char host1[20],host2[20];
  int port1=0,port2=0;

  
  hsock = (httptransocket2 *)data;
  CMyHttpPipeBase *MyPipe = (CMyHttpPipeBase *)hsock->MyPipe;
  fd2    = hsock->fd2;

  memset(host1,0,20);
  memset(host2,0,20);

  structsize2=sizeof(struct sockaddr);
  

  memset(read_in2,0,MAXSIZE);
  memset(send_out2,0,MAXSIZE);
  
  timeset.tv_sec=TIMEOUT;
  timeset.tv_usec=0;
  
  DWORD dwThreadID;
  HANDLE hThread = hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)httpReadBag, data, 0, &dwThreadID); 
  while(1)
  {

    //接收数据    
    FD_ZERO(&readfd);
    
    FD_SET((UINT)fd2, &readfd);
        
    result=select(fd2+1,&readfd,NULL,NULL,×et);
    if((result<0) && (errno!=EINTR))
    {
      printf("[-] Select error.\r\n");
      break;
    }
    else if(result==0)
    {
      printf("[-] Socket time out.\r\n");
      break;
    }
                          
    if(FD_ISSET(fd2, &readfd))
    {
      if(totalread2 < MAXSIZE) {        
        read2=recv(fd2,read_in2,MAXSIZE-totalread2, 0); 
        if(read2==0)break;
        if((read2<0) && (errno!=EINTR))
        {
          DWORD error = GetLastError();
          printf("[-] Read fd2 data error,maybe close?\r\n\r\n");
          break;
        }
        
        memcpy(send_out2+totalread2,read_in2,read2);

        printf(" Recv %5d bytes\r\n", read2);

        totalread2+=read2;
        memset(read_in2,0,MAXSIZE);

        int err2=0;
        if(totalread2>0)
        {
          if(!MyPipe->SendBag(send_out2, (DWORD &)totalread2))
          {
            printf("[-] Send to fd1 unknow error.\r\n");
            err2=1;
            break;
          }
          
          printf(" Send %5d bytes\r\n", totalread2);
        }
        if(err2==1) break;
        totalread2 = 0;
        
        memset(send_out2,0,MAXSIZE);
        
      }
    }        
    Sleep(5);
  }

  closesocket(fd2);
  MyPipe->StopWork();

  TerminateThread(hThread, 0);
  delete MyPipe;
  

  if(method == 3)
  connectnum --;

  printf("\r\n[+] OK! I Closed The Three Socket.\r\n"); 

上传的附件
httplcx.rar (14.5 KB, 461 次下载) [谁下载?]

你可能感兴趣的:(windows应用编程)