/// <summary>
/// Evaluate the accuracy of our stopguessing service by sending user logins and malicious traffic
/// </summary>
/// <returns></returns>
public void Run()
{
_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);
_simAccounts.Generate(_experimentalConfiguration);
_logger.WriteStatus("Creating login-attempt generator");
_attemptGenerator = new SimulatedLoginAttemptGenerator(_experimentalConfiguration, _simAccounts, _ipPool,
_simPasswords);
_logger.WriteStatus("Finiished creating login-attempt generator");
foreach (
ConcurrentStreamWriter writer in
new[]
{ _AttackAttemptsWithValidPasswords, _LegitimateAttemptsWithValidPasswords, _OtherAttempts })
{
lock (writer)
{
writer.WriteLine(string.Format("{0}\t{1}\t{2}\t{3}\t{4}\t{5}\t{6}\t{7}\t{8}\t{9}\t{10}" +
"\t{11}\t{12}\t{13}\t{14}\t{15}\t{16}\t{17}\t{18}\t{19}\t{20}\t{21}\t{22}\t{23}\t{24}\t{25}",
"Password",
"UserID",
"IP",
"DeviceCookie",
"IsFrequentlyGuessedPw",
"IsPasswordCorrect",
"IsFromAttackAttacker",
"IsAGuess",
"IPInOposingPool",
"IsClientAProxyIP",
"TypeOfMistake",
"DecayedInvalidAttemptsPerPassword",
"DecayedMaxConsecutiveIncorrectAttemptsPerAccount",
"DecayedSuccessfulLogins",
"DecayedAccountFailuresInfrequentPassword",
"DecayedAccountFailuresFrequentPassword",
"DecayedRepeatAccountFailuresInfrequentPassword",
"DecayedRepeatAccountFailuresFrequentPassword",
"DecayedPasswordFailuresNoTypoInfrequentPassword",
"DecayedPasswordFailuresNoTypoFrequentPassword",
"DecayedPasswordFailuresTypoInfrequentPassword",
"DecayedPasswordFailuresTypoFrequentPassword",
"DecayedRepeatPasswordFailuresNoTypoInfrequentPassword",
"DecayedRepeatPasswordFailuresNoTypoFrequentPassword",
"DecayedRepeatPasswordFailuresTypoInfrequentPassword",
"DecayedRepeatPasswordFailuresTypoFrequentPassword"
));
}
}
TimeSpan testTimeSpan = _experimentalConfiguration.TestTimeSpan;
double ticksBetweenLogins = ((double)testTimeSpan.Ticks) /
(double)_experimentalConfiguration.TotalLoginAttemptsToIssue;
int interlockedCount = 0;
Parallel.For(0L, (long)_experimentalConfiguration.TotalLoginAttemptsToIssue, (count, pls) =>
//) TaskParalllel.RepeatWithWorkers(_experimentalConfiguration.TotalLoginAttemptsToIssue,
//async (count, cancelToken) =>
// (count) =>
{
interlockedCount = Interlocked.Add(ref interlockedCount, 1);
if (interlockedCount % 10000 == 0)
{
_logger.WriteStatus("Login Attempt {0:N0}", interlockedCount);
}
DateTime eventTimeUtc = StartTimeUtc.AddTicks((long)(ticksBetweenLogins * interlockedCount));
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 = _ipHistoryCache.GetOrAdd(simAttempt.AddressOfClientInitiatingRequest,
(ip) => new SimIpHistory(
_experimentalConfiguration.BlockingOptions
.NumberOfFailuresToTrackForGoingBackInTimeToIdentifyTypos));
//SimIpHistory ipHistory = await _ipHistoryCache.GetAsync(simAttempt.AddressOfClientInitiatingRequest, cancelToken);
double[] scores = ipHistory.GetAllScores(_experimentalConfiguration.BlockingOptions.BlockScoreHalfLife,
simAttempt.TimeOfAttemptUtc);
simAttempt.UpdateSimulatorState(this, ipHistory);
double decayingInvalidPasswordAttempts = 0d;
if (simAttempt.IsPasswordValid)
{
DecayingDouble incorrectPasswordAttempts;
if (_incorrectPasswordCounts.TryGetValue(simAttempt.Password, out incorrectPasswordAttempts))
{
decayingInvalidPasswordAttempts = incorrectPasswordAttempts.GetValue(_experimentalConfiguration.BlockingOptions.BlockScoreHalfLife, simAttempt.TimeOfAttemptUtc);
}
}
else
{
decayingInvalidPasswordAttempts = 1d;
DecayingDouble incorrectPasswordAttempts;
if (_incorrectPasswordCounts.TryGetValue(simAttempt.Password, out incorrectPasswordAttempts))
{
decayingInvalidPasswordAttempts += incorrectPasswordAttempts.GetValue(_experimentalConfiguration.BlockingOptions.BlockScoreHalfLife, simAttempt.TimeOfAttemptUtc);
}
_incorrectPasswordCounts[simAttempt.Password] = new DecayingDouble(decayingInvalidPasswordAttempts, simAttempt.TimeOfAttemptUtc);
}
var ipInfo = _ipPool.GetIpAddressDebugInfo(simAttempt.AddressOfClientInitiatingRequest);
string outputString = string.Format("{0}\t{1}\t{2}\t{3}\t{4}\t{5}\t{6}\t{7}\t{8}\t{9}\t{10}\t{11}\t{12}\t{13}",
simAttempt.Password,
simAttempt.SimAccount?.UsernameOrAccountId ?? "<null>",
simAttempt.AddressOfClientInitiatingRequest,
simAttempt.DeviceCookieHadPriorSuccessfulLoginForThisAccount ? "HadCookie" : "NoCookie",
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,
decayingInvalidPasswordAttempts,
simAttempt.SimAccount?.MaxConsecutiveIncorrectAttempts.GetValue(_experimentalConfiguration.BlockingOptions.BlockScoreHalfLife, simAttempt.TimeOfAttemptUtc) ?? 0d,
string.Join("\t", scores.Select(s => s.ToString(CultureInfo.InvariantCulture)).ToArray())
);
if (simAttempt.IsFromAttacker && simAttempt.IsPasswordValid)
{
lock (_AttackAttemptsWithValidPasswords)
{
_AttackAttemptsWithValidPasswords.WriteLine(outputString);
//_AttackAttemptsWithValidPasswords.Flush();
}
}
else if (!simAttempt.IsFromAttacker && simAttempt.IsPasswordValid)
{
lock (_LegitimateAttemptsWithValidPasswords)
{
_LegitimateAttemptsWithValidPasswords.WriteLine(outputString);
//_LegitiamteAttemptsWithValidPasswords.Flush();
}
}
else
{
lock (_OtherAttempts)
{
_OtherAttempts.WriteLine(outputString);
//_OtherAttempts.Flush();
}
}
});
//(e) => {
//},
//cancellationToken: cancellationToken).ConfigureAwait(false);
foreach (
ConcurrentStreamWriter writer in
new []
{ _AttackAttemptsWithValidPasswords, _LegitimateAttemptsWithValidPasswords, _OtherAttempts })
{
writer.Close();
}
//_memoryUsageLimiter.Dispose();
}