public async Task LoginWithIpWithBadReputationParallelLoadAsync()
        {
            TestConfiguration configuration = InitTest();

            string[] usernames = CreateUserAccounts(configuration, 250);
            CreateTestAccount(configuration, Username1, Password1);

            await TaskParalllel.ForEachWithWorkers(usernames.Skip(20), async (username, itemNumber, cancelToken) =>
                                                   await AuthenticateAsync(configuration, username, Password1, clientAddress: AttackersIp, cancellationToken: cancelToken));

            Thread.Sleep(2000);

            LoginAttempt firstAttackersAttempt = await AuthenticateAsync(configuration, Username1, Password1, clientAddress : AttackersIp);

            Assert.Equal(AuthenticationOutcome.CredentialsValidButBlocked, firstAttackersAttempt.Outcome);

            foreach (string username in usernames.Skip(1).Take(19))
            {
                await AuthenticateAsync(configuration, username, Password1, AnotherAttackersIp);
            }

            await AuthenticateAsync(configuration, usernames[0], Password1, AnotherAttackersIp);

            LoginAttempt anotherAttackersAttempt = await AuthenticateAsync(configuration, Username1, Password1, clientAddress : AnotherAttackersIp);

            Assert.Equal(AuthenticationOutcome.CredentialsValidButBlocked, anotherAttackersAttempt.Outcome);
        }
示例#2
0
        public async Task LoginWithIpWithBadReputationParallelLoadAsync()
        {
            TestConfiguration configuration = InitTest();

            //((MemoryOnlyStableStore) configuration.StableStore).Accounts = null;
            string[] usernames = CreateUserAccounts(configuration, 250);
            CreateTestAccount(configuration, Username1, Password1);

            // Have one attacker make the password popular by attempting to login to every account with it.
            await TaskParalllel.ForEachWithWorkers(usernames.Skip(20), async (username, itemNumber, cancelToken) =>
                                                   await AuthenticateAsync(configuration, username, Password1, clientAddress: AttackersIp, cancellationToken: cancelToken));

            Thread.Sleep(2000);

            LoginAttempt firstAttackersAttempt = await AuthenticateAsync(configuration, Username1, Password1, clientAddress : AttackersIp);

            Assert.Equal(AuthenticationOutcome.CredentialsValidButBlocked, firstAttackersAttempt.Outcome);

            // Now the second attacker should be flagged after using that password 10 times on different accounts.
            foreach (string username in usernames.Skip(1).Take(19))
            {
                await AuthenticateAsync(configuration, username, Password1, AnotherAttackersIp);
            }

            await AuthenticateAsync(configuration, usernames[0], Password1, AnotherAttackersIp);

            LoginAttempt anotherAttackersAttempt = await AuthenticateAsync(configuration, Username1, Password1, clientAddress : AnotherAttackersIp);

            Assert.Equal(AuthenticationOutcome.CredentialsValidButBlocked, anotherAttackersAttempt.Outcome);
        }
示例#3
0
        /// <summary>
        /// Evaluate the accuracy of our stopguessing service by sending user logins and malicious traffic
        /// </summary>
        /// <returns></returns>
        public async Task Run(CancellationToken cancellationToken = default(CancellationToken))
        {
            _logger.WriteStatus("In RunInBackground");

            _logger.WriteStatus("Priming password-tracking with known common passwords");
            _simPasswords.PrimeWithKnownPasswordsAsync(_binomialLadderFilter, 40);
            _logger.WriteStatus("Finished priming password-tracking with known common passwords");

            _logger.WriteStatus("Creating IP Pool");
            _ipPool = new IpPool(_experimentalConfiguration);
            _logger.WriteStatus("Generating simualted account records");
            _simAccounts = new SimulatedAccounts(_ipPool, _simPasswords, _logger);
            await _simAccounts.GenerateAsync(_experimentalConfiguration, cancellationToken);

            _logger.WriteStatus("Creating login-attempt generator");
            _attemptGenerator = new SimulatedLoginAttemptGenerator(_experimentalConfiguration, _simAccounts, _ipPool, _simPasswords);
            _logger.WriteStatus("Finiished creating login-attempt generator");


            foreach (TextWriter writer in new TextWriter[] { _AttackAttemptsWithValidPasswords, _LegitiamteAttemptsWithValidPasswords, _OtherAttempts })
            {
                writer.WriteLine("{0},{1},{2},{3},{4},{5},{6},{7},{8},{9}", //,{9}
                                 "Password",
                                 "UserID",
                                 "IP",
                                 "IsFrequentlyGuessedPw",
                                 "IsPasswordCorrect",
                                 "IsFromAttackAttacker",
                                 "IsAGuess",
                                 "IPInOposingPool",
                                 "IsClientAProxyIP",
                                 "TypeOfMistake"
                                 //string.Join(",")
                                 );
            }

            TimeSpan testTimeSpan       = _experimentalConfiguration.TestTimeSpan;
            double   ticksBetweenLogins = ((double)testTimeSpan.Ticks) / (double)_experimentalConfiguration.TotalLoginAttemptsToIssue;

            await TaskParalllel.RepeatWithWorkers(_experimentalConfiguration.TotalLoginAttemptsToIssue, async (count, cancelToken) =>
            {
                if (count % 10000 == 0)
                {
                    _logger.WriteStatus("Login Attempt {0:N0}", count);
                }
                DateTime eventTimeUtc = StartTimeUtc.AddTicks((long)(ticksBetweenLogins *count));
                SimulatedLoginAttempt simAttempt;
                if (StrongRandomNumberGenerator.GetFraction() <
                    _experimentalConfiguration.FractionOfLoginAttemptsFromAttacker)
                {
                    switch (_experimentalConfiguration.AttackersStrategy)
                    {
                    case ExperimentalConfiguration.AttackStrategy.UseUntilLikelyPopular:
                        simAttempt = _attemptGenerator.MaliciousLoginAttemptBreadthFirstAvoidMakingPopular(eventTimeUtc);
                        break;

                    case ExperimentalConfiguration.AttackStrategy.Weighted:
                        simAttempt = _attemptGenerator.MaliciousLoginAttemptWeighted(eventTimeUtc);
                        break;

                    case ExperimentalConfiguration.AttackStrategy.BreadthFirst:
                    default:
                        simAttempt = _attemptGenerator.MaliciousLoginAttemptBreadthFirst(eventTimeUtc);
                        break;
                    }
                }
                else
                {
                    simAttempt = _attemptGenerator.BenignLoginAttempt(eventTimeUtc);
                }

                // Get information about the client's IP
                SimIpHistory ipHistory = await _ipHistoryCache.GetAsync(simAttempt.AddressOfClientInitiatingRequest, cancelToken);

                double[] scores = ipHistory.GetAllScores(_experimentalConfiguration.BlockingOptions.BlockScoreHalfLife,
                                                         simAttempt.TimeOfAttemptUtc);

                simAttempt.UpdateSimulatorState(this, ipHistory);

                var ipInfo          = _ipPool.GetIpAddressDebugInfo(simAttempt.AddressOfClientInitiatingRequest);
                string outputString = string.Format("{0},{1},{2},{3},{4},{5},{6},{7},{8},{9},{10}",
                                                    simAttempt.Password,
                                                    simAttempt.SimAccount?.UsernameOrAccountId ?? "<null>",
                                                    simAttempt.AddressOfClientInitiatingRequest,
                                                    simAttempt.IsFrequentlyGuessedPassword ? "Frequent" : "Infrequent",
                                                    simAttempt.IsPasswordValid ? "Correct" : "Incorrect",
                                                    simAttempt.IsFromAttacker ? "FromAttacker" : "FromUser",
                                                    simAttempt.IsGuess ? "IsGuess" : "NotGuess",
                                                    simAttempt.IsFromAttacker ? (ipInfo.UsedByBenignUsers ? "IsInBenignPool" : "NotUsedByBenign") :
                                                    (ipInfo.UsedByAttackers ? "IsInAttackersIpPool" : "NotUsedByAttacker"),
                                                    ipInfo.IsPartOfProxy ? "ProxyIP" : "NotAProxy",
                                                    string.IsNullOrEmpty(simAttempt.MistakeType) ? "-" : simAttempt.MistakeType,

                                                    string.Join(",", scores.Select(s => s.ToString(CultureInfo.InvariantCulture)).ToArray())
                                                    );

                if (simAttempt.IsFromAttacker && simAttempt.IsPasswordValid)
                {
                    await _AttackAttemptsWithValidPasswords.WriteLineAsync(outputString);
                    await _AttackAttemptsWithValidPasswords.FlushAsync();
                }
                else if (!simAttempt.IsFromAttacker && simAttempt.IsPasswordValid)
                {
                    await _LegitiamteAttemptsWithValidPasswords.WriteLineAsync(outputString);
                    await _LegitiamteAttemptsWithValidPasswords.FlushAsync();
                }
                else
                {
                    await _OtherAttempts.WriteLineAsync(outputString);
                    await _OtherAttempts.FlushAsync();
                }
            },
                                                  //(e) => {
                                                  //},
                                                  cancellationToken : cancellationToken);

            _memoryUsageLimiter.Dispose();
        }