public SimulatedLoginAttempt MaliciousLoginAttemptBreadthFirstAvoidMakingPopular(DateTime eventTimeUtc) { bool invalidAccount = (StrongRandomNumberGenerator.GetFraction() < _experimentalConfiguration.ProbabilityThatAttackerChoosesAnInvalidAccount); ulong breadthFirstAttemptCount; lock (_breadthFirstLock) { breadthFirstAttemptCount = _breadthFirstAttemptCounter; if (!invalidAccount) { _breadthFirstAttemptCounter++; } } int passwordIndex = (int)((breadthFirstAttemptCount / (ulong)_experimentalConfiguration.MaxAttackerGuessesPerPassword)) % _simPasswords.OrderedListOfMostCommonPasswords.Count; int accountIndex = (int)(breadthFirstAttemptCount % (ulong)_simAccounts.BenignAccounts.Count); string mistake = invalidAccount ? "BadAccount" : ""; SimulatedUserAccount targetBenignAccount = invalidAccount ? null : _simAccounts.BenignAccounts[accountIndex]; string password = _simPasswords.OrderedListOfMostCommonPasswords[passwordIndex]; return(new SimulatedLoginAttempt(targetBenignAccount, password, true, true, _ipPool.GetRandomMaliciousIp(), StrongRandomNumberGenerator.Get64Bits().ToString(), mistake, eventTimeUtc)); }
public void AdjustBlockingScoreForPastTyposTreatedAsFullFailures( Simulator simulator, SimulatedUserAccount account, DateTime whenUtc, string correctPassword) { SimLoginAttemptSummaryForTypoAnalysis[] recentPotentialTypos = RecentPotentialTypos.MostRecentFirst.ToArray(); foreach (SimLoginAttemptSummaryForTypoAnalysis potentialTypo in recentPotentialTypos) { if (account == null || potentialTypo.UsernameOrAccountId != account.UsernameOrAccountId) { continue; } bool likelyTypo = EditDistance.Calculate(potentialTypo.Password, correctPassword) <= simulator._experimentalConfiguration.BlockingOptions.MaxEditDistanceConsideredATypo; TimeSpan halfLife = simulator._experimentalConfiguration.BlockingOptions.BlockScoreHalfLife; DecayingDouble value = new DecayingDouble(1d, potentialTypo.WhenUtc); if (potentialTypo.WasPasswordFrequent) { PasswordFailuresNoTypoFrequentPassword.SubtractInPlace(halfLife, value); PasswordFailuresTypoFrequentPassword.AddInPlace(halfLife, value); } RecentPotentialTypos.Remove(potentialTypo); } }
public SimulatedLoginAttempt MaliciousAttemptToSantiizeIpViaAValidLogin(IPAddress ipAddressToSanitizeThroughLogin) { SimulatedUserAccount simAccount = _simAccounts.GetMaliciousAccountAtRandomUniform(); return(new SimulatedLoginAttempt(simAccount, simAccount.Password, true, false, ipAddressToSanitizeThroughLogin, StrongRandomNumberGenerator.Get64Bits().ToString(), "", DateTime.UtcNow)); }
public SimulatedLoginAttempt MaliciousLoginAttemptWeighted(DateTime eventTimeUtc) { SimulatedUserAccount targetBenignAccount = (StrongRandomNumberGenerator.GetFraction() < _experimentalConfiguration.ProbabilityThatAttackerChoosesAnInvalidAccount) ? null : _simAccounts.GetBenignAccountAtRandomUniform(); return(new SimulatedLoginAttempt( targetBenignAccount, _simPasswords.GetPasswordFromWeightedDistribution(), true, true, _ipPool.GetRandomMaliciousIp(), StrongRandomNumberGenerator.Get64Bits().ToString(), "", eventTimeUtc)); }
public SimulatedLoginAttempt(SimulatedUserAccount account, string password, bool isFromAttacker, bool isGuess, IPAddress clientAddress, string cookieProvidedByBrowser, string mistakeType, DateTime eventTimeUtc ) { SimAccount = account; UserNameOrAccountId = account != null ? account.UsernameOrAccountId : StrongRandomNumberGenerator.Get64Bits().ToString(); IsPasswordValid = account != null && account.Password == password; AddressOfClientInitiatingRequest = clientAddress; TimeOfAttemptUtc = eventTimeUtc; CookieProvidedByBrowser = cookieProvidedByBrowser; Password = password; IsFromAttacker = isFromAttacker; IsGuess = isGuess; MistakeType = mistakeType; }
public SimulatedLoginAttempt BenignLoginAttempt(DateTime eventTimeUtc) { lock (ScheduledBenignAttempts) { if (ScheduledBenignAttempts.Count > 0 && ScheduledBenignAttempts.First().TimeOfAttemptUtc < eventTimeUtc) { SimulatedLoginAttempt result = ScheduledBenignAttempts.First(); ScheduledBenignAttempts.Remove(result); return(result); } } string mistake = ""; SimulatedUserAccount account = _simAccounts.BenignAccountSelector.GetItemByWeightedRandom(); string cookie; if (account.Cookies.Count == 0 || (account.Cookies.Count < _experimentalConfiguration.MaxCookiesPerUserAccount && StrongRandomNumberGenerator.GetFraction() > _experimentalConfiguration.ChanceOfCoookieReUse)) { cookie = StrongRandomNumberGenerator.Get64Bits().ToString(); account.Cookies.Add(cookie); } else { cookie = account.Cookies.ToArray()[(int)StrongRandomNumberGenerator.Get32Bits(account.Cookies.Count)]; } IPAddress clientIp; if (account.ClientAddresses.Count == 0 || (account.ClientAddresses.Count < _experimentalConfiguration.MaxIpPerUserAccount && StrongRandomNumberGenerator.GetFraction() < _experimentalConfiguration.ChanceOfIpReUse)) { account.ClientAddresses.Add(clientIp = _ipPool.GetNewRandomBenignIp()); } else { clientIp = account.ClientAddresses.ToArray()[(int)StrongRandomNumberGenerator.Get32Bits(account.ClientAddresses.Count)]; } string password = account.Password; if (StrongRandomNumberGenerator.GetFraction() < _experimentalConfiguration.ChanceOfLongRepeatOfStalePassword) { string newPassword = _simPasswords.GetPasswordFromWeightedDistribution(); _userAccountController.SetPassword(account, newPassword, account.Password); mistake += "StalePassword"; lock (ScheduledBenignAttempts) { double additionalMistakes = 0; DateTime currentTimeUtc = eventTimeUtc; for (additionalMistakes = 1; additionalMistakes < _experimentalConfiguration.LengthOfLongRepeatOfOldPassword; additionalMistakes++) { currentTimeUtc = currentTimeUtc.AddSeconds(_experimentalConfiguration.MinutesBetweenLongRepeatOfOldPassword); ScheduledBenignAttempts.Add(new SimulatedLoginAttempt( account, password, false, false, clientIp, cookie, mistake, currentTimeUtc)); } for (uint correctLogins = 1; correctLogins < _experimentalConfiguration.LengthOfLongRepeatOfOldPassword; correctLogins++) { currentTimeUtc = currentTimeUtc.AddSeconds(_experimentalConfiguration.MinutesBetweenLongRepeatOfOldPassword); ScheduledBenignAttempts.Add(new SimulatedLoginAttempt( account, newPassword, false, false, clientIp, cookie, mistake, currentTimeUtc)); } } } if (StrongRandomNumberGenerator.GetFraction() < _experimentalConfiguration.ChanceOfBenignPasswordTypo) { mistake += "Typo"; lock (ScheduledBenignAttempts) { double additionalMistakes = 0; while (StrongRandomNumberGenerator.GetFraction() < _experimentalConfiguration.ChanceOfRepeatTypo) { ScheduledBenignAttempts.Add(new SimulatedLoginAttempt( account, AddTypoToPassword(password), false, false, clientIp, cookie, mistake, eventTimeUtc.AddSeconds(_experimentalConfiguration.DelayBetweenRepeatBenignErrorsInSeconds * ++additionalMistakes))); } ScheduledBenignAttempts.Add(new SimulatedLoginAttempt( account, password, false, false, clientIp, cookie, "", eventTimeUtc.AddSeconds( _experimentalConfiguration.DelayBetweenRepeatBenignErrorsInSeconds * (1 + additionalMistakes)))); } password = AddTypoToPassword(password); } if (StrongRandomNumberGenerator.GetFraction() < _experimentalConfiguration.ChanceOfAccidentallyUsingAnotherAccountPassword) { mistake += "WrongPassword"; lock (ScheduledBenignAttempts) { double additionalMistakes = 0; while (StrongRandomNumberGenerator.GetFraction() < _experimentalConfiguration.ChanceOfRepeatUseOfPasswordFromAnotherAccount) { ScheduledBenignAttempts.Add(new SimulatedLoginAttempt( account, _simPasswords.GetPasswordFromWeightedDistribution(), false, false, clientIp, cookie, mistake, eventTimeUtc.AddSeconds(_experimentalConfiguration.DelayBetweenRepeatBenignErrorsInSeconds * ++additionalMistakes))); } ScheduledBenignAttempts.Add(new SimulatedLoginAttempt( account, password, false, false, clientIp, cookie, "", eventTimeUtc.AddSeconds( _experimentalConfiguration.DelayBetweenRepeatBenignErrorsInSeconds * (additionalMistakes + 1)))); } password = _simPasswords.GetPasswordFromWeightedDistribution(); } if (StrongRandomNumberGenerator.GetFraction() < _experimentalConfiguration.ChanceOfBenignAccountNameTypoResultingInAValidUserName) { mistake += "WrongAccountName"; lock (ScheduledBenignAttempts) { double additionalMistakes = 0; while (StrongRandomNumberGenerator.GetFraction() < _experimentalConfiguration.ChanceOfRepeatWrongAccountName) { ScheduledBenignAttempts.Add(new SimulatedLoginAttempt( _simAccounts.GetBenignAccountAtRandomUniform(), password, false, false, clientIp, cookie, mistake, eventTimeUtc.AddSeconds( _experimentalConfiguration.DelayBetweenRepeatBenignErrorsInSeconds * ++additionalMistakes))); } ScheduledBenignAttempts.Add(new SimulatedLoginAttempt( account, password, false, false, clientIp, cookie, "", eventTimeUtc.AddSeconds( _experimentalConfiguration.DelayBetweenRepeatBenignErrorsInSeconds * (additionalMistakes + 1)))); account = _simAccounts.GetBenignAccountAtRandomUniform(); } } return(new SimulatedLoginAttempt(account, password, false, false, clientIp, cookie, mistake, eventTimeUtc)); }
public void Generate(ExperimentalConfiguration experimentalConfiguration) { SimulatedUserAccountController simUserAccountController = new SimulatedUserAccountController(); _logger.WriteStatus("Creating accounts"); ConcurrentBag <SimulatedUserAccount> benignSimulatedAccountBag = new ConcurrentBag <SimulatedUserAccount>(); Parallel.For(0, (int)experimentalConfiguration.NumberOfBenignAccounts, (index) => { //if (index > 0 && index % 10000 == 0) // _logger.WriteStatus("Created {0:N0} benign accounts", index); SimulatedUserAccount userAccount = simUserAccountController.Create( "user_" + index.ToString(), _simPasswords.GetPasswordFromWeightedDistribution() ); userAccount.ClientAddresses.Add(_ipPool.GetNewRandomBenignIp()); string initialCookie = StrongRandomNumberGenerator.Get64Bits().ToString(); userAccount.Cookies.Add(initialCookie); userAccount.HashesOfCookiesOfClientsThatHaveSuccessfullyLoggedIntoThisAccount[initialCookie] = true; benignSimulatedAccountBag.Add(userAccount); double inverseFrequency = Distributions.GetLogNormal(0, 1); if (inverseFrequency < 0.01d) { inverseFrequency = 0.01d; } if (inverseFrequency > 50d) { inverseFrequency = 50d; } double frequency = 1 / inverseFrequency; lock (BenignAccountSelector) { BenignAccountSelector.AddItem(userAccount, frequency); } }); BenignAccounts = benignSimulatedAccountBag.ToList(); // _logger.WriteStatus("Finished creating {0:N0} benign accounts", // experimentalConfiguration.NumberOfBenignAccounts); //_logger.WriteStatus("Creating attacker IPs"); _ipPool.GenerateAttackersIps(); //_logger.WriteStatus("Creating {0:N0} attacker accounts", // experimentalConfiguration.NumberOfAttackerControlledAccounts); ConcurrentBag <SimulatedUserAccount> maliciousSimulatedAccountBag = new ConcurrentBag <SimulatedUserAccount>(); Parallel.For(0, (int)experimentalConfiguration.NumberOfAttackerControlledAccounts, (index) => { SimulatedUserAccount userAccount = simUserAccountController.Create( "attacker_" + index.ToString(), _simPasswords.GetPasswordFromWeightedDistribution()); userAccount.ClientAddresses.Add(_ipPool.GetRandomMaliciousIp()); maliciousSimulatedAccountBag.Add(userAccount); }); AttackerAccounts = maliciousSimulatedAccountBag.ToList(); _logger.WriteStatus("Finished creating accounts", experimentalConfiguration.NumberOfAttackerControlledAccounts); Parallel.ForEach(BenignAccounts.Union(AttackerAccounts), (simAccount, loopState) => { simAccount.CreditHalfLife = experimentalConfiguration.BlockingOptions.AccountCreditLimitHalfLife; simAccount.CreditLimit = experimentalConfiguration.BlockingOptions.AccountCreditLimit; foreach (string cookie in simAccount.Cookies) { simUserAccountController.HasClientWithThisHashedCookieSuccessfullyLoggedInBefore( simAccount, LoginAttempt.HashCookie(cookie)); } }); //_logger.WriteStatus("Finished creating user accounts for each simluated account record"); }