gpt4 book ai didi

c - 获取 UDP 目标地址 :Port from TPROXY'd Traffic

转载 作者:太空宇宙 更新时间:2023-11-04 04:11:35 24 4
gpt4 key购买 nike

我正在尝试从已通过 iptables TPROXY 规则重定向的 UDP 数据包中获取原始目的地。然而,有几种方法都失败了,使用原始套接字从 IP header 中获取数据包似乎是乱码。

混淆实际上是双重的。后一个小数据包是通过 SOCK_DGRAM 获得的 UDP 有效载荷,但是将其更改为 SOCK_RAW 会返回此乱码,其中不包含有效载荷的痕迹,也不包含 IP header 。

错误的东西:

Port: 0 -- 45 00 00 48 1c ac 00 00 6e 11 7b f6 1b 46 8b 53 8b 63 82 06 69 7d 69 b4 00 34 29 5f 00 ba 03 00 47 20 01 00 30 2b ca 00 01 7d 8d 58 e8 89 88 0e 60 7f ee 00 c0 0b e3 01 00 00 00 00 00 00 00 06 0d e3 01 80 83 06 85 80 received 74 bytes

正确的负载:端口:0 -- ff ff ff ff 55 4b a1 d5 77 收到 9 个字节

未受 TPROXY 影响的正确原始数据包如下所示:

45-00-00-65-17-4B-40-00-3A-11-46-F8-2D-23-01-BA-4E-9F-64-C9-69-CD-26-8F-00-51-C2-C9-FF-FF-FF-FF-52-4C-20-30-36-2F.....

FF-FF-FF-FF-5x 是所需负载的开始,端口位于 69CD。

由于 C# 似乎没有显然需要 TPROXY 工作所需的 IP_TRANSPARENT 标志,我已经转移到 C/C++ 套接字代码,我尝试为 IP_TRANSPARENT、IP_RECVORIGSTDADDR、IP_HDRINCL 设置套接字选项。

我从 recvfrom 更改为 recvmsg 和 msghdrs,以便尝试循环遍历辅助数据以从 sockaddr_in 结果中获取 sin_port。我从不同的 SO 问题中拼凑了很多尝试,诚然,我真的不知道在这个级别的套接字代码中发生了什么,像 cmsghdr、cmsg、msghdr、iovecs 等对我来说都是新的。这里似乎没有任何作用,无论 TPROXY 对这些数据包做了什么,它们无论如何都无法使用。

下面是获取数据包、打印十六进制并尝试获取端口的内容(无论如何结果都是 0)

recvlen = recvmsg(fd, &message, 0);
printf("received %d bytes\n", recvlen);

for (cmsghdr *cmsg = CMSG_FIRSTHDR(&message); cmsg != NULL; cmsg = CMSG_NXTHDR(&message, cmsg))
{
if (cmsg->cmsg_level != SOL_IP || cmsg->cmsg_type != IP_ORIGDSTADDR) continue;
printf("copying port\n");
std::memcpy(&dstIpAddr, CMSG_DATA(cmsg), sizeof(sockaddr_in));
dstPort = ntohs(dstIpAddr.sin_port);
}

printf("Port: %i -- ", dstPort);
//std::cout << "Destination port: " << dstPort << std::endl;
for (int i = 0; i < recvlen; i++)
{
printf("%02x ", buf[i]);
}

iptables 规则将匹配十六进制字符串的数据包重定向到此套接字绑定(bind)到的端口:

TPROXY     udp  --  anywhere             anywhere             udp dpts:27000:28000 STRING match  "|ffffffff54|" ALGO name bm TO 65535 TPROXY redirect 0.0.0.0:29000 mark 0x1/0x1
TPROXY udp -- anywhere anywhere udp dpts:27000:28000 STRING match "|ffffffff55|" ALGO name bm TO 65535 TPROXY redirect 0.0.0.0:29000 mark 0x1/0x1
TPROXY udp -- anywhere anywhere udp dpts:27000:28000 STRING match "|ffffffff56|" ALGO name bm TO 65535 TPROXY redirect 0.0.0.0:29000 mark 0x1/0x1
TPROXY udp -- anywhere anywhere udp dpts:27000:28000 STRING match "|ffffffff57|" ALGO name bm TO 65535 TPROXY redirect 0.0.0.0:29000 mark 0x1/0x1

我只需要获取目标地址:端口,以便转发流量以有条件地将其转发到它应该去的地方,并将结果发回。如果我可以使用 UDP 套接字执行此操作并以某种方式获取有效负载,然后从某些函数获取端口,fab。如果我必须获取原始数据包然后从 IP header 中获取它,那也没关系,除非我不能,因为 TPROXY 似乎在混淆这些数据包。

最佳答案

相信我通过 sizeof(buffer) 将 iov_len 设置为 const char* 的大小,因此基本上没有可写空间。在摆弄声明并以此结束后,我使用 cmsg 循环正确获得了 IP 和端口。我仍然不知道为什么 TPROXY 在通过原始套接字查看数据包时会扭曲数据包,这很有趣。

iov.iov_base = cPacket;
iov.iov_len = BUFSIZE;

mHeader.msg_name = &sSourceAddr; //sockaddr_storage
mHeader.msg_namelen = sizeof(struct sockaddr_in);
mHeader.msg_iov = &iov;
mHeader.msg_iovlen = 1;
mHeader.msg_control = cControl;
mHeader.msg_controllen = BUFSIZE;

for (cmsghdr *cmsg = CMSG_FIRSTHDR(&mHeader); cmsg != NULL; cmsg = CMSG_NXTHDR(&mHeader, cmsg))
{
if (cmsg->cmsg_level != SOL_IP || cmsg->cmsg_type != IP_ORIGDSTADDR) continue;
std::memcpy(&sDestIP, CMSG_DATA(cmsg), sizeof(sockaddr_in));
iPort = ntohs(sDestIP.sin_port);
sAddress = sDestIP.sin_addr;
}

关于c - 获取 UDP 目标地址 :Port from TPROXY'd Traffic,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56727876/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com