1

最近发现一些路由器设备包含后门,其中一些可以通过单个 UDP 数据包被利用。我意识到其中一些后门不一定是恶意的,因为我在自己的产品中做了同样的事情来进行故障排除:打开一个套接字向服务器发送心跳包,并监听来自的命令(例如“ping”)服务器。有些命令居然可以在设备上执行任意代码,让我的心怦怦直跳……

我的问题是,作为一种原始的身份验证形式,如果我将接收到的 UDP 数据包的远程地址和端口与套接字发送数据包的服务器的实际地址和端口进行比较,事情是否足够安全(即,没有攻击可以被利用)?示例代码如下:

if ((bytes = recvfrom(sock, buf, sizeof(buf) - 1, 0, 
                      (sockaddr *)addr, addrlen)) == -1)
{
    perror("recvfrom");
    return -1;
}

buf[bytes] = '\0';
printf("%s: received: %s\n", __func__, buf);

if (addrcmp(addr, (sockaddr_in *)ai_server->ai_addr) == 0)
{
    // do things
}

addrcmp() 的代码:

int addrcmp(sockaddr_in *a1, sockaddr_in *a2)
{
    if (a1->sin_addr.s_addr == a2->sin_addr.s_addr &&
        a1->sin_port == a2->sin_port)
    {
        return 0;
    }
    return 1;
}
4

3 回答 3

2

即使您确保数据包是从您正在与之交谈的地址接收到的,它也不一定是您正在与之交谈的机器。欺骗地址和端口很容易。验证发件人的地址/端口是您可以采取的许多步骤中的第一步 - 如果您正在与某个众所周知的端口通信并且如果有人可以猜出地址,他们仍然可以发送具有正确地址和端口的数据包。因此,您可以在一侧探索使用临时端口 - 如果您选择使用临时端口,那么攻击者仍然可以猜测端口,因为只有 64K 端口。因此,您可以迁移到 TCP。这将使攻击者也猜测序列号。这在某些情况下也被打破了

IMO,您应该假设攻击者知道连接细节来设计系统。无论如何,中间人都知道您的连接详细信息。您可以尝试以下一些方法 - 在数据包被接受之前验证数据包中的字段。确保数据包中各个字段的输入在可接受的范围内 - 验证内容。使用某些东西对数据进行签名 - 加密和验证连接

如果它是用于管理目的的心跳,如果不需要通过互联网,您应该考虑将管理网络与数据端口完全隔离。在这种情况下,您可能可以避免上面列出的一些检查。

此列表并不详尽。大多数商业产品会做所有这些以及更多,但仍然很脆弱。

于 2013-10-21T05:59:36.323 回答
1

您不能在 UDP 中安全地执行此操作。你根本不应该这样做——它被发现并被恶意使用。大多数设备设计人员为此使用电路板上的串行控制台引脚,如果他们在原型阶段之外完全这样做的话。至少这需要对设备进行物理访问。

如果您必须有远程控制连接,请使用经过验证的东西。例如,SSH 或 SSL 加密的 TCP 或 HTTP 连接。

于 2013-10-21T10:30:13.260 回答
1

您的程序实际上是一个小型防火墙。您可以在设备前面使用防火墙来阻止所有流向端口和相关接口的 UDP 流量。如果您的服务器碰巧使用相同的端口和接口,您可以更改它吗?

于 2013-10-21T08:33:32.760 回答