diff --git a/src/DarkNet/effects/authentication.ts b/src/DarkNet/effects/authentication.ts index 77b4aa6ba..fab147ffc 100644 --- a/src/DarkNet/effects/authentication.ts +++ b/src/DarkNet/effects/authentication.ts @@ -124,6 +124,23 @@ export const checkPassword = ( `${altitude}`, ); } + case ModelIds.SortedEchoVuln: { + if (server.password.length < 5 || attemptedPassword.length !== server.password.length) { + return getFailureResponse(attemptedPassword, server.staticPasswordHint, server.passwordHintData); + } + let squaredError = 0; + for (let i = 0; i < attemptedPassword.length; i++) { + const attempted = Number(attemptedPassword[i]); + const actual = Number(server.password[i]); + if (!Number.isFinite(attempted)) { + return getFailureResponse(attemptedPassword, server.staticPasswordHint, server.passwordHintData); + } + squaredError += (attempted - actual) ** 2; + } + const rmsd = Math.sqrt(squaredError / attemptedPassword.length); + const rmsdMessage = `${server.passwordHintData}; RMS Deviation:${rmsd.toFixed(3)}`; + return getFailureResponse(attemptedPassword, server.staticPasswordHint, rmsdMessage); + } default: return getFailureResponse(attemptedPassword, server.staticPasswordHint, server.passwordHintData); } diff --git a/test/jest/Darknet/Darknet.test.ts b/test/jest/Darknet/Darknet.test.ts index ca158a5d9..cc7a281dc 100644 --- a/test/jest/Darknet/Darknet.test.ts +++ b/test/jest/Darknet/Darknet.test.ts @@ -26,6 +26,7 @@ import { getXorMaskEncryptedPasswordConfig, getTripleModuloConfig, getKingOfTheHillConfig, + getSortedEchoVulnConfig, } from "../../../src/DarkNet/controllers/ServerGenerator"; import { commonPasswordDictionary, @@ -616,6 +617,33 @@ describe("Password Tests", () => { expect(successResult.response.code).toBe(ResponseCodeEnum.Success); }); + test("sortedEchoVuln creates a valid password and hint", () => { + const sortedEchoVulnServer = serverFactory(getSortedEchoVulnConfig, 20, 0, 0); + sortedEchoVulnServer.password = "12345"; + sortedEchoVulnServer.passwordHintData = "41532"; + + expect(sortedEchoVulnServer).toBeDefined(); + const failedAttemptResponse = getAuthResult(sortedEchoVulnServer, "23456", 1); + expect(failedAttemptResponse.result.code).toBe(ResponseCodeEnum.AuthFailure); + const logs1 = getMostRecentAuthLog(sortedEchoVulnServer.hostname); + expect(logs1?.data).toBe(`${sortedEchoVulnServer.passwordHintData}; RMS Deviation:1.000`); + + getAuthResult(sortedEchoVulnServer, "23579", 1); + expect(failedAttemptResponse.result.code).toBe(ResponseCodeEnum.AuthFailure); + const logs2 = getMostRecentAuthLog(sortedEchoVulnServer.hostname); + expect(logs2?.data).toBe(`${sortedEchoVulnServer.passwordHintData}; RMS Deviation:2.490`); + + getAuthResult(sortedEchoVulnServer, "12355", 1); + expect(failedAttemptResponse.result.code).toBe(ResponseCodeEnum.AuthFailure); + const logs3 = getMostRecentAuthLog(sortedEchoVulnServer.hostname); + expect(logs3?.data).toBe(`${sortedEchoVulnServer.passwordHintData}; RMS Deviation:0.447`); + + expect(getAuthResult(sortedEchoVulnServer, sortedEchoVulnServer.password, 1).result.code).toBe( + ResponseCodeEnum.Success, + ); + expect(sortedEchoVulnServer.hasAdminRights).toBe(true); + }); + test("kingOfTheHill server creates a valid password and hint", () => { const kingOfTheHillServer = serverFactory(getKingOfTheHillConfig, 60, 0, 0); const password = Number(kingOfTheHillServer.password);