From c4c1009b0ab638ffcdeee0c194e3ecd0f2fd84d4 Mon Sep 17 00:00:00 2001 From: Lucas Dias Date: Sun, 9 Jun 2024 20:31:38 -0300 Subject: [PATCH] complicate node spoofing DHT allows the impersonation attack because method getNode updates the node's addr in following case: node A (IP address 1.1.1.1) has InfoHash 8ffe0d18748cfc04d1bc0a2e8c3a548e06f3f794 and sends a Ping to node B (IP address 2.2.2.2), then node B sends neighborhood maintenance to 1.1.1.1. Thus, a malicious node (IP Address 3.3.3.3) discovers the InfoHash 8ffe0d18748cfc04d1bc0a2e8c3a548e06f3f794 from Node A and sends DHT packets to Node B. Thus, when node B receives a message, it will update the node A address. Then, it will send the neighborhood maintenance to 3.3.3.3 instead 1.1.1.1. With this change, node A will update the node addr when node B sends a confirmation after 1 minute or it is old. When node B is not old, node A updates the node addr with its actual addr. Signed-off-by: Lucas Dias --- include/opendht/node.h | 6 ++++++ src/node.cpp | 1 + src/node_cache.cpp | 2 +- 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/include/opendht/node.h b/include/opendht/node.h index dec8c75f7..5219226f1 100644 --- a/include/opendht/node.h +++ b/include/opendht/node.h @@ -89,6 +89,9 @@ struct Node { bool isRemovable(const time_point& now) const { return isExpired() and isOld(now); } + bool isUpgradeable(const time_point& now) const { + return time + NODE_UPDATE_TIME < now; + } NodeExport exportNode() const { NodeExport ne; @@ -151,6 +154,9 @@ struct Node { /* The time after which we consider a node to be expirable. */ static constexpr const std::chrono::minutes NODE_EXPIRE_TIME {10}; + /* The time after which we consider a node to be upgradeable. */ + static constexpr const std::chrono::minutes NODE_UPDATE_TIME {1}; + /* Time for a request to timeout */ static constexpr const std::chrono::seconds MAX_RESPONSE_TIME {1}; diff --git a/src/node.cpp b/src/node.cpp index ac2be22df..756beb4de 100644 --- a/src/node.cpp +++ b/src/node.cpp @@ -28,6 +28,7 @@ namespace dht { constexpr std::chrono::minutes Node::NODE_EXPIRE_TIME; constexpr std::chrono::minutes Node::NODE_GOOD_TIME; +constexpr std::chrono::minutes Node::NODE_UPDATE_TIME; constexpr std::chrono::seconds Node::MAX_RESPONSE_TIME; Node::Node(const InfoHash& id, const SockAddr& addr, std::mt19937_64& rd, bool client) diff --git a/src/node_cache.cpp b/src/node_cache.cpp index 58a7018a8..a1b8b0d32 100644 --- a/src/node_cache.cpp +++ b/src/node_cache.cpp @@ -115,7 +115,7 @@ NodeCache::NodeMap::getNode(const InfoHash& id, const SockAddr& addr, time_point cleanup(); cleanup_counter = 0; } - } else if (confirm or node->isOld(now)) { + } else if ((confirm and node->isUpgradeable(now)) or node->isOld(now)) { node->update(addr); } return node;