如何解决使用 Windivert 修改 tcp 数据包负载但连接完成
我正在做一个项目,我需要编辑一个 tcp 数据包数据。我为此使用Windivert,我可以找到我的数据包并进行编辑,我也不会改变数据包长度,只是用随机值替换了一些值(我尝试使用套接字重定向并编辑它会起作用,但我想使用windivert)但是当重新注入时此服务器以 FIN,ACK 标志响应。这是我的代码,如果有人可以帮助我,我无法解决问题,我会很高兴。
#include <winsock2.h>
#include <windows.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "windivert.h"
#define MAXBUF WINdiveRT_MTU_MAX
#define PROXY_PORT 34010
#define ALT_PORT 43010
#define MAX_LINE 65
/*
* Proxy server configuration.
*/
typedef struct
{
UINT16 proxy_port;
UINT16 alt_port;
} PROXY_CONfig,*PPROXY_CONfig;
typedef struct
{
SOCKET s;
UINT16 alt_port;
struct in_addr dest;
} PROXY_CONNECTION_CONfig,*PPROXY_CONNECTION_CONfig;
typedef struct
{
BOOL inbound;
SOCKET s;
SOCKET t;
} PROXY_TRANSFER_CONfig,*PPROXY_TRANSFER_CONfig;
/*
* Lock to sync output.
*/
static HANDLE lock;
/*
* Prototypes.
*/
static DWORD proxy(LPVOID arg);
static DWORD proxy_connection_handler(LPVOID arg);
static DWORD proxy_transfer_handler(LPVOID arg);
/*
* Error handling.
*/
static void message(const char *msg,...)
{
va_list args;
va_start(args,msg);
WaitForSingleObject(lock,INFINITE);
vfprintf(stderr,msg,args);
putc('\n',stderr);
ReleaseMutex(lock);
va_end(args);
}
#define error(msg,...) \
do { \
message("error: " msg,## __VA_ARGS__); \
exit(EXIT_FAILURE); \
} while (FALSE)
#define warning(msg,...) \
message("warning: " msg,## __VA_ARGS__)
int generate_random(int l,int r) { //this will generate random number in range l and r
int rand_num = (rand() % (r - l + 1)) + l;
return rand_num;
}
/*
* Entry.
*/
int __cdecl main(int argc,char **argv)
{
HANDLE handle,thread;
UINT16 port,proxy_port,alt_port;
int r;
char filter[256];
INT16 priority = 123; // Arbitrary.
PPROXY_CONfig config;
unsigned char packet[MAXBUF];
UINT packet_len;
WINdiveRT_ADDRESS addr;
PWINdiveRT_IPHDR ip_header;
PWINdiveRT_TCPHDR tcp_header;
DWORD len;
// Init.
if (argc != 2)
{
fprintf(stderr,"usage: %s dest-port\n",argv[0]);
exit(EXIT_FAILURE);
}
port = (UINT16)atoi(argv[1]);
if (port < 0 || port > 0xFFFF)
{
fprintf(stderr,"error: invalid port number (%d)\n",port);
exit(EXIT_FAILURE);
}
proxy_port = (port == PROXY_PORT? PROXY_PORT+1: PROXY_PORT);
alt_port = (port == ALT_PORT? ALT_PORT+1: ALT_PORT);
lock = CreateMutex(NULL,FALSE,NULL);
if (lock == NULL)
{
fprintf(stderr,"error: Failed to create mutex (%d)\n",GetLastError());
exit(EXIT_FAILURE);
}
// divert all traffic to/from `port',`proxy_port' and `alt_port'.
r = snprintf(filter,sizeof(filter),"tcp and "
"(tcp.DstPort == %d or tcp.DstPort == %d or tcp.DstPort == %d or "
"tcp.SrcPort == %d or tcp.SrcPort == %d or tcp.SrcPort == %d)",port,alt_port,alt_port);
if (r < 0 || r >= sizeof(filter))
{
error("Failed to create filter string");
}
handle = WindivertOpen(filter,WINdiveRT_LAYER_NETWORK,priority,0);
if (handle == INVALID_HANDLE_VALUE)
{
error("Failed to open the Windivert device (%d)",GetLastError());
}
// Spawn proxy thread,config = (PPROXY_CONfig)malloc(sizeof(PROXY_CONfig));
if (config == NULL)
{
error("Failed to allocate memory");
}
config->proxy_port = proxy_port;
config->alt_port = alt_port;
thread = CreateThread(NULL,1,(LPTHREAD_START_ROUTINE)proxy,(LPVOID)config,NULL);
if (thread == NULL)
{
error("Failed to create thread (%d)",GetLastError());
}
CloseHandle(thread);
// Main loop:
while (TRUE)
{
if (!WindivertRecv(handle,packet,sizeof(packet),&packet_len,&addr))
{
warning("Failed to read packet (%d)",GetLastError());
continue;
}
WindivertHelperParsePacket(packet,packet_len,&ip_header,NULL,&tcp_header,NULL);
if (ip_header == NULL || tcp_header == NULL)
{
warning("Failed to parse packet (%d)",GetLastError());
continue;
}
if (addr.Outbound)
{
if (tcp_header->DstPort == htons(port))
{
// Reflect: PORT ---> PROXY
UINT32 dst_addr = ip_header->DstAddr;
tcp_header->DstPort = htons(proxy_port);
ip_header->DstAddr = ip_header->SrcAddr;
ip_header->SrcAddr = dst_addr;
addr.Outbound = FALSE;
if ((UINT8)packet[40] == 128 && (UINT8)packet[41] == 0 && (UINT8)packet[42] == 119 && (UINT8)packet[43] == 162 && (UINT8)packet[172] == 185)
{
srand(time(0));
printf(" \n founded \n");
(UINT8)packet[168] = generate_random(1,155);
(UINT8)packet[172] = generate_random(1,155);
WindivertHelperCalcChecksums(packet,&addr,0);
if (!WindivertSend(handle,&addr))
{
// Handle send error
continue;
}
}
}
else if (tcp_header->SrcPort == htons(proxy_port))
{
// Reflect: PROXY ---> PORT
UINT32 dst_addr = ip_header->DstAddr;
tcp_header->SrcPort = htons(port);
ip_header->DstAddr = ip_header->SrcAddr;
ip_header->SrcAddr = dst_addr;
addr.Outbound = FALSE;
}
else if (tcp_header->DstPort == htons(alt_port))
{
// Redirect: ALT ---> PORT
tcp_header->DstPort = htons(port);
}
}
else
{
if (tcp_header->SrcPort == htons(port))
{
// Redirect: PORT ---> ALT
tcp_header->SrcPort = htons(alt_port);
}
}
WindivertHelperCalcChecksums(packet,0);
if (!WindivertSend(handle,&addr))
{
warning("Failed to send packet (%d)",GetLastError());
continue;
}
}
return 0;
}
/*
* Proxy server thread.
*/
static DWORD proxy(LPVOID arg)
{
PPROXY_CONfig config = (PPROXY_CONfig)arg;
UINT16 proxy_port = config->proxy_port;
UINT16 alt_port = config->alt_port;
int on = 1;
WSADATA wsa_data;
WORD wsa_version = MAKEWORD(2,2);
struct sockaddr_in addr;
SOCKET s;
HANDLE thread;
free(config);
if (WSAStartup(wsa_version,&wsa_data) != 0)
{
error("Failed to start WSA (%d)",GetLastError());
}
s = socket(AF_INET,SOCK_STREAM,0);
if (s == INVALID_SOCKET)
{
error("Failed to create socket (%d)",WSAGetLastError());
}
if (setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(const char*)&on,sizeof(int))
== SOCKET_ERROR)
{
error("Failed to re-use address (%d)",GetLastError());
}
memset(&addr,sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(proxy_port);
if (bind(s,(SOCKADDR *)&addr,sizeof(addr)) == SOCKET_ERROR)
{
error("Failed to bind socket (%d)",WSAGetLastError());
}
if (listen(s,16) == SOCKET_ERROR)
{
error("Failed to listen socket (%d)",WSAGetLastError());
}
while (TRUE)
{
// Wait for a new connection.
PPROXY_CONNECTION_CONfig config;
int size = sizeof(addr);
SOCKET t = accept(s,&size);
if (t == INVALID_SOCKET)
{
warning("Failed to accept socket (%d)",WSAGetLastError());
continue;
}
// Spawn proxy connection handler thread.
config = (PPROXY_CONNECTION_CONfig)
malloc(sizeof(PROXY_CONNECTION_CONfig));
if (config == NULL)
{
error("Failed to allocate memory");
}
config->s = t;
config->alt_port = alt_port;
config->dest = addr.sin_addr;
thread = CreateThread(NULL,(LPTHREAD_START_ROUTINE)proxy_connection_handler,NULL);
if (thread == NULL)
{
warning("Failed to create thread (%d)",GetLastError());
closesocket(t);
free(config);
continue;
}
CloseHandle(thread);
}
}
/*
* Proxy connection handler thread.
*/
static DWORD proxy_connection_handler(LPVOID arg)
{
PPROXY_TRANSFER_CONfig config1,config2;
HANDLE thread;
PPROXY_CONNECTION_CONfig config = (PPROXY_CONNECTION_CONfig)arg;
SOCKET s = config->s,t;
UINT16 alt_port = config->alt_port;
struct in_addr dest = config->dest;
struct sockaddr_in addr;
free(config);
t = socket(AF_INET,0);
if (t == INVALID_SOCKET)
{
warning("Failed to create socket (%d)",WSAGetLastError());
closesocket(s);
return 0;
}
memset(&addr,sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(alt_port);
addr.sin_addr = dest;
if (connect(t,sizeof(addr)) == SOCKET_ERROR)
{
warning("Failed to connect socket (%d)",WSAGetLastError());
closesocket(s);
closesocket(t);
return 0;
}
config1 = (PPROXY_TRANSFER_CONfig)malloc(sizeof(PROXY_TRANSFER_CONfig));
config2 = (PPROXY_TRANSFER_CONfig)malloc(sizeof(PROXY_TRANSFER_CONfig));
if (config1 == NULL || config2 == NULL)
{
error("Failed to allocate memory");
}
config1->inbound = FALSE;
config2->inbound = TRUE;
config2->t = config1->s = s;
config2->s = config1->t = t;
thread = CreateThread(NULL,(LPTHREAD_START_ROUTINE)proxy_transfer_handler,(LPVOID)config1,NULL);
if (thread == NULL)
{
warning("Failed to create thread (%d)",GetLastError());
closesocket(s);
closesocket(t);
free(config1);
free(config2);
return 0;
}
proxy_transfer_handler((LPVOID)config2);
WaitForSingleObject(thread,INFINITE);
CloseHandle(thread);
closesocket(s);
closesocket(t);
return 0;
}
/*
* Handle the transfer of data from one socket to another.
*/
static DWORD proxy_transfer_handler(LPVOID arg)
{
PPROXY_TRANSFER_CONfig config = (PPROXY_TRANSFER_CONfig)arg;
BOOL inbound = config->inbound;
SOCKET s = config->s,t = config->t;
char buf[8192];
int len,len2,i;
HANDLE console;
free(config);
while (TRUE)
{
1
len = recv(s,buf,sizeof(buf),0);
if (len == SOCKET_ERROR)
{
warning("Failed to recv from socket (%d)",WSAGetLastError());
shutdown(s,SD_BOTH);
shutdown(t,SD_BOTH);
return 0;
}
if (len == 0)
{
shutdown(s,SD_RECEIVE);
shutdown(t,SD_SEND);
return 0;
}
// Dump stream information to the screen.
console = GetStdHandle(STD_OUTPUT_HANDLE);
WaitForSingleObject(lock,INFINITE);
printf("[%.4d] ",len);
SetConsoleTextAttribute(console,(inbound? FOREGROUND_RED: FOREGROUND_GREEN));
for (i = 0; i < len && i < MAX_LINE; i++)
{
putchar((isprint(buf[i])? buf[i]: '.'));
}
SetConsoleTextAttribute(console,FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
printf("%s\n",(len > MAX_LINE? "...": ""));
ReleaseMutex(lock);
// Send data to t.
int i;
for (i = 0; i < len; )
{
len2 = send(t,buf+i,len-i,0);
if (len2 == SOCKET_ERROR)
{
warning("Failed to send to socket (%d)",WSAGetLastError());
shutdown(s,SD_BOTH);
shutdown(t,SD_BOTH);
return 0;
}
i += len2;
}
}
return 0;
}
当我不编辑数据包时,这里是wireshark输出;
当我尝试编辑数据包时,它被编辑但wireshark输出是这样的(编辑后的数据包长度为188);
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。