private TimeSpan DefaultTimeout { get; } = new TimeSpan(0, 0, 0, 0, 500); // FUTURE use configuration value

        public LoginAttemptController(
            LoginAttemptClient loginAttemptClient,
            UserAccountClient userAccountClient,
            MemoryUsageLimiter memoryUsageLimiter,
            BlockingAlgorithmOptions blockingOptions,
            IStableStore stableStore)
        {
            _options = blockingOptions;//optionsAccessor.Options;
            _stableStore = stableStore;
            _passwordPopularityTracker = new PasswordPopularityTracker("FIXME-uniquekeyfromconfig"
                //FIXME -- use configuration to get options here"FIXME-uniquekeyfromconfig", thresholdRequiredToTrackPreciseOccurrences: 10);
                );
            
            _loginAttemptCache = new FixedSizeLruCache<string, LoginAttempt>(80000);  // FIXME -- use configuration file for size
            _loginAttemptsInProgress = new Dictionary<string, Task<LoginAttempt>>();
            _ipHistoryCache = new SelfLoadingCache<IPAddress, IpHistory>(
                (id, cancellationToken) =>
                {
                    return Task.Run(() => new IpHistory(id), cancellationToken);
                    // FUTURE -- option to load from stable store
                });
            _loginAttemptClient = loginAttemptClient;
            _loginAttemptClient.SetLocalLoginAttemptController(this);     
            SetUserAccountClient(userAccountClient);
            memoryUsageLimiter.OnReduceMemoryUsageEventHandler += ReduceMemoryUsage;
        }
Ejemplo n.º 2
0
        // This method gets called by a runtime.
        // Use this method to add services to the container
        public void ConfigureServices(IServiceCollection services)
        {
            // Add Application Insights data collection services to the services container.
            services.AddApplicationInsightsTelemetry(Configuration);

            services.AddMvc();
            // Uncomment the following line to add Web API services which makes it easier to port Web API 2 controllers.
            // You will also need to add the Microsoft.AspNet.Mvc.WebApiCompatShim package to the 'dependencies' section of project.json.
            // services.AddWebApiConventions();

            var hosts = new MaxWeightHashing<RemoteHost>("FIXME-uniquekeyfromconfig");
            RemoteHost localHost = new RemoteHost {Uri = new Uri("http://localhost:35358")};

            services.AddSingleton<RemoteHost>(x => localHost);
            hosts.Add("localhost", localHost);

            // Use memory only stable store if none other is available.  FUTURE -- use azure SQL or tables
            services.AddSingleton<IStableStore, MemoryOnlyStableStore>();

            var options = new BlockingAlgorithmOptions();


            services.AddSingleton<BlockingAlgorithmOptions>(x => options);
            services.AddSingleton<BlockingAlgorithmOptions>(x => options);

            services.AddSingleton<MemoryUsageLimiter, MemoryUsageLimiter>();

            services.AddSingleton<IDistributedResponsibilitySet<RemoteHost>>(x => hosts);
            services.AddSingleton<UserAccountClient>();
            services.AddSingleton<LoginAttemptClient>();
            services.AddSingleton<UserAccountController>();
            services.AddSingleton<LoginAttemptController>();
        }
Ejemplo n.º 3
0
 public IpHistory(
     IPAddress address,
     BlockingAlgorithmOptions options)
 {
     Address = address;
     CurrentBlockScore = new DecayingDouble();
     RecentPotentialTypos =
         new SmallCapacityConstrainedSet<LoginAttemptSummaryForTypoAnalysis>(options.NumberOfFailuresToTrackForGoingBackInTimeToIdentifyTypos);
 }
Ejemplo n.º 4
0
 public IpHistory(
     IPAddress address,
     BlockingAlgorithmOptions options)
 {
     Address              = address;
     CurrentBlockScore    = new DecayingDouble();
     RecentPotentialTypos =
         new SmallCapacityConstrainedSet <LoginAttemptSummaryForTypoAnalysis>(options.NumberOfFailuresToTrackForGoingBackInTimeToIdentifyTypos);
 }
Ejemplo n.º 5
0
        public void Init()
        {
            var builder = new ConfigurationBuilder()
                .SetBasePath("")
                .AddJsonFile("appsettings.json");

            builder.AddEnvironmentVariables();
            Configuration = builder.Build();

            sqlConnectionString = Configuration["Data:ConnectionString"];
            string cloudStorageConnectionString = Configuration["Data:StorageConnectionString"];

            _options = new BlockingAlgorithmOptions();

            DbContextOptionsBuilder<DbUserAccountContext> dbOptionsBuilder = new DbContextOptionsBuilder<DbUserAccountContext>();
            dbOptionsBuilder.UseSqlServer(sqlConnectionString);
            dbOptions = dbOptionsBuilder.Options;

            _CloudStorageAccount = CloudStorageAccount.Parse(cloudStorageConnectionString);
            userAccountControllerFactory = new DbUserAccountControllerFactory(_CloudStorageAccount, dbOptions);
            userAccountController = userAccountControllerFactory.CreateDbUserAccountController();

            RemoteHost localHost = new RemoteHost { Uri = new Uri("http://localhost:35358") };
            MaxWeightHashing<RemoteHost> hosts = new MaxWeightHashing<RemoteHost>(Configuration["Data:UniqueConfigurationSecretPhrase"]);

            LoginAttemptClient<DbUserAccount> loginAttemptClient = new LoginAttemptClient<DbUserAccount>(hosts, localHost);

            _UserAccountRepositoryFactory = new DbUserAccountRepositoryFactory(dbOptions);

            BinomialLadderFilter localPasswordBinomialLadderFilter = new BinomialLadderFilter(
                _options.NumberOfBitsInBinomialLadderFilter_N, _options.HeightOfBinomialLadder_H);

            _loginAttemptController = new LoginAttemptController<DbUserAccount>(
                userAccountControllerFactory, _UserAccountRepositoryFactory,
                localPasswordBinomialLadderFilter,
                new MemoryUsageLimiter(), _options);

            //services.AddEntityFramework()
            //    .AddSqlServer()
            //    .AddDbContext<DbUserAccountContext>(opt => opt.UseSqlServer(sqlConnectionString));
            //DbUserAccountContext context = new DbUserAccountContext();

            //var db = new DbContextOptionsBuilder();
            //db.UseInMemoryDatabase();
            //_context = new MyContext(db.Options);

        }
        public UserAccountController(
            UserAccountClient userAccountClient,
            LoginAttemptClient loginAttemptClient,
            MemoryUsageLimiter memoryUsageLimiter,
            BlockingAlgorithmOptions options,
            IStableStore stableStore,
            LimitPerTimePeriod[] creditLimits)
        {
//            _options = optionsAccessor.Options;
            _options = options;
            _stableStore = stableStore;
            _userAccountClient = userAccountClient;
            CreditLimits = creditLimits;
            _userAccountCache = new SelfLoadingCache<string, UserAccount>(_stableStore.ReadAccountAsync);
            SetLoginAttemptClient(loginAttemptClient);
            userAccountClient.SetLocalUserAccountController(this);
            memoryUsageLimiter.OnReduceMemoryUsageEventHandler += ReduceMemoryUsage;
        }
Ejemplo n.º 7
0
        public static TestConfiguration InitTest(BlockingAlgorithmOptions options = default(BlockingAlgorithmOptions))
        {
            if (options == null)
                options = new BlockingAlgorithmOptions();

            TestConfiguration configuration = new TestConfiguration();
            configuration.MyBlockingAlgorithmOptions = options ?? new BlockingAlgorithmOptions();

            //configuration.MyResponsibleHosts = new MaxWeightHashing<RemoteHost>("FIXME-uniquekeyfromconfig");
            //RemoteHost localHost = new RemoteHost { Uri = new Uri("http://localhost:80") };
            //configuration.MyResponsibleHosts.Add("localhost", localHost);
            //IStableStore stableStore = configuration.StableStore = new MemoryOnlyStableStore();
            
            //configuration.MyLoginAttemptClient = new LoginAttemptClient(configuration.MyResponsibleHosts, localHost);

            MemoryUsageLimiter memoryUsageLimiter = new MemoryUsageLimiter();

            BinomialLadderFilter localPasswordBinomialLadderFilter =
            new BinomialLadderFilter(options.NumberOfBitsInBinomialLadderFilter_N, options.HeightOfBinomialLadder_H);

            //MultiperiodFrequencyTracker<string> localPasswordFrequencyTracker =
            //        new MultiperiodFrequencyTracker<string>(
            //            options.NumberOfPopularityMeasurementPeriods,
            //            options.LengthOfShortestPopularityMeasurementPeriod,
            //            options.FactorOfGrowthBetweenPopularityMeasurementPeriods);
            
            configuration.MyAccountFactory = new MemoryOnlyUserAccountFactory();
            configuration.MemUserAccountController = new MemoryUserAccountController();

            LoginAttemptController<MemoryUserAccount> myLoginAttemptController = 
                new LoginAttemptController<MemoryUserAccount>(
                new MemoryUserAccountControllerFactory(),
                configuration.MyAccountFactory,
                localPasswordBinomialLadderFilter,
                memoryUsageLimiter, configuration.MyBlockingAlgorithmOptions);

            configuration.MyLoginAttemptClient = myLoginAttemptController;

            //configuration.MyLoginAttemptClient.SetLocalLoginAttemptController(myLoginAttemptController);
            return configuration;
        }
Ejemplo n.º 8
0
        public Simulator(ExperimentalConfiguration myExperimentalConfiguration, BlockingAlgorithmOptions options = default(BlockingAlgorithmOptions))
        {
            MyExperimentalConfiguration = myExperimentalConfiguration;
            if (options == null)
                options = new BlockingAlgorithmOptions();
            CreditLimits = new[]
            {
                // 3 per hour
                new LimitPerTimePeriod(new TimeSpan(1, 0, 0), 3f),
                // 6 per day (24 hours, not calendar day)
                new LimitPerTimePeriod(new TimeSpan(1, 0, 0, 0), 6f),
                // 10 per week
                new LimitPerTimePeriod(new TimeSpan(6, 0, 0, 0), 10f),
                // 15 per month
                new LimitPerTimePeriod(new TimeSpan(30, 0, 0, 0), 15f)
            };
            //We are testing with local server now
            MyResponsibleHosts = new MaxWeightHashing<RemoteHost>("FIXME-uniquekeyfromconfig");
            //configuration.MyResponsibleHosts.Add("localhost", new RemoteHost { Uri = new Uri("http://localhost:80"), IsLocalHost = true });
            RemoteHost localHost = new RemoteHost { Uri = new Uri("http://localhost:80") };
            MyResponsibleHosts.Add("localhost", localHost);

            MyUserAccountClient = new UserAccountClient(MyResponsibleHosts, localHost);
            MyLoginAttemptClient = new LoginAttemptClient(MyResponsibleHosts, localHost);

            MemoryUsageLimiter memoryUsageLimiter = new MemoryUsageLimiter();

            MyUserAccountController = new UserAccountController(MyUserAccountClient,
                MyLoginAttemptClient, memoryUsageLimiter, options, StableStore,
                CreditLimits);
            MyLoginAttemptController = new LoginAttemptController(MyLoginAttemptClient, MyUserAccountClient,
                memoryUsageLimiter, options, StableStore);

            MyUserAccountController.SetLoginAttemptClient(MyLoginAttemptClient);
            MyUserAccountClient.SetLocalUserAccountController(MyUserAccountController);

            MyLoginAttemptController.SetUserAccountClient(MyUserAccountClient);
            MyLoginAttemptClient.SetLocalLoginAttemptController(MyLoginAttemptController);
            //fix outofmemory bug by setting the loginattempt field to null
            StableStore.LoginAttempts = null;
        }
Ejemplo n.º 9
0
        public static TestConfiguration InitTest(BlockingAlgorithmOptions options = default(BlockingAlgorithmOptions))
        {
            TestConfiguration configuration = new TestConfiguration();
            if (options == null)
                options = new BlockingAlgorithmOptions();
            configuration.CreditLimits = new[]
            {
                // 3 per hour
                new LimitPerTimePeriod(new TimeSpan(1, 0, 0), 3f),
                // 6 per day (24 hours, not calendar day)
                new LimitPerTimePeriod(new TimeSpan(1, 0, 0, 0), 6f),
                // 10 per week
                new LimitPerTimePeriod(new TimeSpan(6, 0, 0, 0), 10f),
                // 15 per month
                new LimitPerTimePeriod(new TimeSpan(30, 0, 0, 0), 15f)
            };

            configuration.MyResponsibleHosts = new MaxWeightHashing<RemoteHost>("FIXME-uniquekeyfromconfig");
            RemoteHost localHost = new RemoteHost { Uri = new Uri("http://localhost:80") };
            configuration.MyResponsibleHosts.Add("localhost", localHost);
            IStableStore stableStore = configuration.StableStore = new MemoryOnlyStableStore();
            
            configuration.MyUserAccountClient = new UserAccountClient(configuration.MyResponsibleHosts, localHost);
            configuration.MyLoginAttemptClient = new LoginAttemptClient(configuration.MyResponsibleHosts, localHost);

            MemoryUsageLimiter memoryUsageLimiter = new MemoryUsageLimiter();

            configuration.MyUserAccountController = new UserAccountController(configuration.MyUserAccountClient,
                configuration.MyLoginAttemptClient, memoryUsageLimiter, options, stableStore, 
                configuration.CreditLimits);
            LoginAttemptController myLoginAttemptController = new LoginAttemptController(configuration.MyLoginAttemptClient, configuration.MyUserAccountClient,
                memoryUsageLimiter, options, stableStore);

            configuration.MyUserAccountController.SetLoginAttemptClient(configuration.MyLoginAttemptClient);
            configuration.MyUserAccountClient.SetLocalUserAccountController(configuration.MyUserAccountController);

            myLoginAttemptController.SetUserAccountClient(configuration.MyUserAccountClient);
            configuration.MyLoginAttemptClient.SetLocalLoginAttemptController(myLoginAttemptController);
            return configuration;
        }
Ejemplo n.º 10
0
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            // Add framework services.
            services.AddMvc();

            string sqlConnectionString = Configuration["Data:ConnectionString"];
            services.AddDbContext<DbUserAccountContext>(
                opt => opt.UseSqlServer(sqlConnectionString));

            // Uncomment the following line to add Web API services which makes it easier to port Web API 2 controllers.
            // You will also need to add the Microsoft.AspNet.Mvc.WebApiCompatShim package to the 'dependencies' section of project.json.
            // services.AddWebApiConventions();

            BlockingAlgorithmOptions options = new BlockingAlgorithmOptions();

            services.AddSingleton<BlockingAlgorithmOptions>(x => options);

            RemoteHost localHost = new RemoteHost { Uri = new Uri("http://localhost:35358") };
            services.AddSingleton<RemoteHost>(x => localHost);

            MaxWeightHashing<RemoteHost> hosts = new MaxWeightHashing<RemoteHost>(Configuration["Data:UniqueConfigurationSecretPhrase"]);
            hosts.Add("localhost", localHost);
            services.AddSingleton<IDistributedResponsibilitySet<RemoteHost>>(x => hosts);

            string cloudStorageConnectionString = Configuration["Data:StorageConnectionString"];
            CloudStorageAccount cloudStorageAccount = CloudStorageAccount.Parse(cloudStorageConnectionString);
            services.AddSingleton<CloudStorageAccount>(a => cloudStorageAccount);

            services.AddSingleton<MemoryUsageLimiter, MemoryUsageLimiter>();

            if (hosts.Count > 0)
            {
                DistributedBinomialLadderFilterClient dblfClient = new DistributedBinomialLadderFilterClient(
                    options.NumberOfVirtualNodesForDistributedBinomialLadder,
                    options.HeightOfBinomialLadder_H,
                    hosts,
                    options.PrivateConfigurationKey,
                    options.MinimumBinomialLadderFilterCacheFreshness);
                // If running as a distributed system
                services.AddSingleton<IBinomialLadderFilter, DistributedBinomialLadderFilterClient>(x => dblfClient);

                DistributedBinomialLadderFilterController filterController =
                    new DistributedBinomialLadderFilterController(dblfClient, options.NumberOfBitsPerShardInBinomialLadderFilter, options.PrivateConfigurationKey);
                services.AddSingleton<DistributedBinomialLadderFilterController>(x => filterController);

                //services.AddSingleton<IFrequenciesProvider<string>>(x =>
                //    new IncorrectPasswordFrequencyClient(hosts, options.NumberOfRedundantHostsToCachePasswordPopularity));
            }
            else
            {
                BinomialLadderFilter localPasswordBinomialLadderFilter =
                    new BinomialLadderFilter(options.NumberOfBitsInBinomialLadderFilter_N, options.HeightOfBinomialLadder_H);
                services.AddSingleton<IBinomialLadderFilter>(x => localPasswordBinomialLadderFilter);
            }

            LoginAttemptClient<DbUserAccount> loginAttemptClient = new LoginAttemptClient<DbUserAccount>(hosts, localHost);
            services.AddSingleton<IUserAccountRepositoryFactory<DbUserAccount>, DbUserAccountRepositoryFactory>();
            services.AddSingleton<IUserAccountControllerFactory<DbUserAccount>, DbUserAccountControllerFactory>();
            //LoginAttemptController<DbUserAccount> loginAttemptController = new LoginAttemptController<DbUserAccount>( 
            //     new DbUserAccountControllerFactory(cloudStorageAccount), new DbUserAccountRepositoryFactory());
            services.AddSingleton<ILoginAttemptClient, LoginAttemptClient<DbUserAccount>>(i => loginAttemptClient);
            services.AddSingleton<ILoginAttemptController, LoginAttemptController<DbUserAccount>>();
        }
Ejemplo n.º 11
0
        public async Task Main(string[] args)
        {
            //for (int i = 1; i < 10; i++)
            //{
            //    ExperimentalConfiguration expConfig1 = new ExperimentalConfiguration();
            //    BlockingAlgorithmOptions blockConfig1 = new BlockingAlgorithmOptions();
            //    blockConfig1.FOR_SIMULATION_ONLY_TURN_ON_SSH_STUPID_MODE = true;
            //    //blockConfig1.BlockThresholdUnpopularPassword = 1 * i;
            //    //blockConfig1.BlockThresholdPopularPassword = blockConfig1.BlockThresholdUnpopularPassword;
            //    //
            //    // Industrial-best-practice baseline
            //    //

            //    // Use the same threshold regardless of the popularity of the account password
            //    blockConfig1.BlockThresholdPopularPassword =
            //        blockConfig1.BlockThresholdUnpopularPassword =1*i;
            //    // Make all failures increase the count towards the threshold by one
            //    blockConfig1.PenaltyForInvalidAccount =
            //        blockConfig1.PenaltyMulitiplierForTypo =
            //        blockConfig1.BasePenaltyForInvalidPassword =
            //        1d;
            //    // If the below is empty, the multiplier for any popularity level will be 1.
            //    blockConfig1.PenaltyForReachingEachPopularityThreshold = new List<PenaltyForReachingAPopularityThreshold>();
            //    // Correct passwords shouldn't help
            //    blockConfig1.RewardForCorrectPasswordPerAccount = 0;

            //    //


            //    expConfig1.TotalLoginAttemptsToIssue = 5000;
            //    expConfig1.RecordUnitAttempts = 5000;
            //    //expConfig1.ChanceOfBenignPasswordTypo = 0.2d;
            //    Simulator simulator = new Simulator(expConfig1, blockConfig1);
            //    Console.WriteLine("Unpopularpassword {0}", blockConfig1.BlockThresholdUnpopularPassword);

            //  //  await simulator.Run(blockConfig1);
            //}

            ulong TotalLoginAttemptsToIssue = 200000;
            ulong RecordUnitAttempts = 200000;
            uint MaliciousIP = 2000;
            //1. Vary BlockThresholdUnpopularPassword from 100 to 2100  (in steps of 200)
            for (int i = 0; i < 11; i++)
            {
                ExperimentalConfiguration expConfig1 = new ExperimentalConfiguration();
                BlockingAlgorithmOptions blockConfig1 = new BlockingAlgorithmOptions();
                //blockConfig1.RewardForCorrectPasswordPerAccount = -10 * i - 10;
                //blockConfig1.PenaltyForInvalidAccount = 1 +  (int)(i/3);
                //blockConfig1.BlockThresholdPopularPassword = 20 + 10 * i;
                //blockConfig1.BlockThresholdUnpopularPassword = 4*blockConfig1.BlockThresholdPopularPassword;
                blockConfig1.BlockThresholdUnpopularPassword = 100 + 200 * i;
                expConfig1.TotalLoginAttemptsToIssue = TotalLoginAttemptsToIssue;
                expConfig1.RecordUnitAttempts = RecordUnitAttempts;
                expConfig1.NumberOfIpAddressesControlledByAttacker = MaliciousIP;
                //blockConfig1.BlockThresholdPopularPassword = 60;
                //blockConfig1.BlockThresholdUnpopularPassword = 900;
                //blockConfig1.PenaltyForInvalidAccount = 35;




                //blockConfig1.PenaltyForReachingEachPopularityThreshold = new List<PenaltyForReachingAPopularityThreshold>
                //{
                //    new PenaltyForReachingAPopularityThreshold { PopularityThreshold = 1d/(100*1000d), Penalty = 10*Math.Pow(2,0.3*i)},
                //    new PenaltyForReachingAPopularityThreshold { PopularityThreshold = 1d/(10*1000d), Penalty = 20*Math.Pow(2,0.3*i)},
                //    new PenaltyForReachingAPopularityThreshold { PopularityThreshold = 1d/(1*1000d), Penalty = 25*Math.Pow(2,0.3*i)},
                //    new PenaltyForReachingAPopularityThreshold { PopularityThreshold = 1d/(100d), Penalty = 30*Math.Pow(2,0.3*i)},
                //};
                Simulator simulator = new Simulator(expConfig1, blockConfig1);
                Console.WriteLine("unpopularpassword {0}", blockConfig1.BlockThresholdUnpopularPassword);

                await simulator.Run(blockConfig1, "BlockThresholdUnpopularPassword");
            }

            //2. Vary blockthresholdpopularpassword from 20 - 120 and unpopularpassword is 4 times



            for (int i = 0; i < 10; i++)
            {
                ExperimentalConfiguration expConfig1 = new ExperimentalConfiguration();
                BlockingAlgorithmOptions blockConfig1 = new BlockingAlgorithmOptions();
                //blockConfig1.RewardForCorrectPasswordPerAccount = -10 * i - 10;
                //blockConfig1.PenaltyForInvalidAccount = 1 +  (int)(i/3);
                blockConfig1.BlockThresholdPopularPassword = 20 + 10 * i;
                blockConfig1.BlockThresholdUnpopularPassword = 4 * blockConfig1.BlockThresholdPopularPassword;
                //blockConfig1.BlockThresholdUnpopularPassword = 100 + 200 * i;
                expConfig1.TotalLoginAttemptsToIssue = TotalLoginAttemptsToIssue;
                expConfig1.RecordUnitAttempts = RecordUnitAttempts;
                expConfig1.NumberOfIpAddressesControlledByAttacker = 100;
                //blockConfig1.BlockThresholdPopularPassword = 60;
                //blockConfig1.BlockThresholdUnpopularPassword = 900;
                //blockConfig1.PenaltyForInvalidAccount = 35;




                //blockConfig1.PenaltyForReachingEachPopularityThreshold = new List<PenaltyForReachingAPopularityThreshold>
                //{
                //    new PenaltyForReachingAPopularityThreshold { PopularityThreshold = 1d/(100*1000d), Penalty = 10*Math.Pow(2,0.3*i)},
                //    new PenaltyForReachingAPopularityThreshold { PopularityThreshold = 1d/(10*1000d), Penalty = 20*Math.Pow(2,0.3*i)},
                //    new PenaltyForReachingAPopularityThreshold { PopularityThreshold = 1d/(1*1000d), Penalty = 25*Math.Pow(2,0.3*i)},
                //    new PenaltyForReachingAPopularityThreshold { PopularityThreshold = 1d/(100d), Penalty = 30*Math.Pow(2,0.3*i)},
                //};
                Simulator simulator = new Simulator(expConfig1, blockConfig1);
                Console.WriteLine("Popularpassword {0}", blockConfig1.BlockThresholdPopularPassword);

                await simulator.Run(blockConfig1, "BlockThresholdPopularPassword");
            }

            //3.Vary PenaltyForInvalidAccount from 1 to 10 (in steps of 1)
            for (int i = 0; i < 10; i++)
            {
                ExperimentalConfiguration expConfig1 = new ExperimentalConfiguration();
                BlockingAlgorithmOptions blockConfig1 = new BlockingAlgorithmOptions();
                //blockConfig1.RewardForCorrectPasswordPerAccount = -10 * i - 10;
                blockConfig1.PenaltyForInvalidAccount = 1 + i;
                //blockConfig1.BlockThresholdPopularPassword = 20 + 10 * i;
                //blockConfig1.BlockThresholdUnpopularPassword = 4 * blockConfig1.BlockThresholdPopularPassword;
                //blockConfig1.BlockThresholdUnpopularPassword = 100 + 200 * i;
                expConfig1.TotalLoginAttemptsToIssue = TotalLoginAttemptsToIssue;
                expConfig1.RecordUnitAttempts = RecordUnitAttempts;
                expConfig1.NumberOfIpAddressesControlledByAttacker = MaliciousIP;
                //blockConfig1.BlockThresholdPopularPassword = 60;
                //blockConfig1.BlockThresholdUnpopularPassword = 900;
                //blockConfig1.PenaltyForInvalidAccount = 35;





                //blockConfig1.PenaltyForReachingEachPopularityThreshold = new List<PenaltyForReachingAPopularityThreshold>
                //{
                //    new PenaltyForReachingAPopularityThreshold { PopularityThreshold = 1d/(100*1000d), Penalty = 10*Math.Pow(2,0.3*i)},
                //    new PenaltyForReachingAPopularityThreshold { PopularityThreshold = 1d/(10*1000d), Penalty = 20*Math.Pow(2,0.3*i)},
                //    new PenaltyForReachingAPopularityThreshold { PopularityThreshold = 1d/(1*1000d), Penalty = 25*Math.Pow(2,0.3*i)},
                //    new PenaltyForReachingAPopularityThreshold { PopularityThreshold = 1d/(100d), Penalty = 30*Math.Pow(2,0.3*i)},
                //};
                Simulator simulator = new Simulator(expConfig1, blockConfig1);
                Console.WriteLine("PenaltyForInvalidAccount {0}", blockConfig1.PenaltyForInvalidAccount);

                await simulator.Run(blockConfig1, "PenaltyForInvalidAccount");
            }
            //4.Vary RewardForCorrectPasswordPerAccount from -10 to -100 
            for (int i = 0; i < 10; i++)
            {
                ExperimentalConfiguration expConfig1 = new ExperimentalConfiguration();
                BlockingAlgorithmOptions blockConfig1 = new BlockingAlgorithmOptions();
                blockConfig1.RewardForCorrectPasswordPerAccount = -10 * i - 10;
                //blockConfig1.PenaltyForInvalidAccount = 1 +  (int)(i/3);
                // blockConfig1.BlockThresholdPopularPassword = 20 + 10 * i;
                //blockConfig1.BlockThresholdUnpopularPassword = 4 * blockConfig1.BlockThresholdPopularPassword;
                //blockConfig1.BlockThresholdUnpopularPassword = 100 + 200 * i;
                expConfig1.TotalLoginAttemptsToIssue = TotalLoginAttemptsToIssue;
                expConfig1.RecordUnitAttempts = RecordUnitAttempts;
                expConfig1.NumberOfIpAddressesControlledByAttacker = MaliciousIP;
                //blockConfig1.BlockThresholdPopularPassword = 60;
                //blockConfig1.BlockThresholdUnpopularPassword = 900;
                //blockConfig1.PenaltyForInvalidAccount = 35;




                //blockConfig1.PenaltyForReachingEachPopularityThreshold = new List<PenaltyForReachingAPopularityThreshold>
                //{
                //    new PenaltyForReachingAPopularityThreshold { PopularityThreshold = 1d/(100*1000d), Penalty = 10*Math.Pow(2,0.3*i)},
                //    new PenaltyForReachingAPopularityThreshold { PopularityThreshold = 1d/(10*1000d), Penalty = 20*Math.Pow(2,0.3*i)},
                //    new PenaltyForReachingAPopularityThreshold { PopularityThreshold = 1d/(1*1000d), Penalty = 25*Math.Pow(2,0.3*i)},
                //    new PenaltyForReachingAPopularityThreshold { PopularityThreshold = 1d/(100d), Penalty = 30*Math.Pow(2,0.3*i)},
                //};
                Simulator simulator = new Simulator(expConfig1, blockConfig1);
                Console.WriteLine("RewardForCorrectPasswordPerAccount {0}", blockConfig1.RewardForCorrectPasswordPerAccount);

                await simulator.Run(blockConfig1, "RewardForCorrectPasswordPerAccount");
            }



            //5.PenaltyForReachingEachPopularityThreshold multiply each by 2 ^{ 0.3 * k} k0-10



            for (int i = 0; i < 11; i++)
            {
                ExperimentalConfiguration expConfig1 = new ExperimentalConfiguration();
                BlockingAlgorithmOptions blockConfig1 = new BlockingAlgorithmOptions();
                //blockConfig1.RewardForCorrectPasswordPerAccount = -10 * i - 10;
                //blockConfig1.PenaltyForInvalidAccount = 1 +  (int)(i/3);
                // blockConfig1.BlockThresholdPopularPassword = 20 + 10 * i;
                //blockConfig1.BlockThresholdUnpopularPassword = 4 * blockConfig1.BlockThresholdPopularPassword;
                //blockConfig1.BlockThresholdUnpopularPassword = 100 + 200 * i;
                expConfig1.TotalLoginAttemptsToIssue = TotalLoginAttemptsToIssue;
                expConfig1.RecordUnitAttempts = RecordUnitAttempts;
                expConfig1.NumberOfIpAddressesControlledByAttacker = MaliciousIP;
                //blockConfig1.BlockThresholdPopularPassword = 60;
                //blockConfig1.BlockThresholdUnpopularPassword = 900;
                //blockConfig1.PenaltyForInvalidAccount = 35;




                blockConfig1.PenaltyForReachingEachPopularityThreshold = new List<PenaltyForReachingAPopularityThreshold>
                {
                    new PenaltyForReachingAPopularityThreshold { PopularityThreshold = 1d/(100*1000d), Penalty = 10*Math.Pow(2,0.3*i)},
                    new PenaltyForReachingAPopularityThreshold { PopularityThreshold = 1d/(10*1000d), Penalty = 20*Math.Pow(2,0.3*i)},
                    new PenaltyForReachingAPopularityThreshold { PopularityThreshold = 1d/(1*1000d), Penalty = 25*Math.Pow(2,0.3*i)},
                    new PenaltyForReachingAPopularityThreshold { PopularityThreshold = 1d/(100d), Penalty = 30*Math.Pow(2,0.3*i)},
                };
                Simulator simulator = new Simulator(expConfig1, blockConfig1);
                Console.WriteLine("PenaltyForReachingEachPopularityThreshold{0}", blockConfig1.PenaltyForReachingEachPopularityThreshold);

                await simulator.Run(blockConfig1, "PenaltyForReachingEachPopularityThreshold");
            }










            //ExperimentalConfiguration expConfig = new ExperimentalConfiguration();
            //BlockingAlgorithmOptions blockConfig = new BlockingAlgorithmOptions();
            //Simulator simulator = new Simulator(expConfig, blockConfig);
            //await simulator.Run();
        }
Ejemplo n.º 12
0
        public async Task TestAccountingForTypoDetection()
        {
            BlockingAlgorithmOptions options = new BlockingAlgorithmOptions
            {
                BasePenaltyForInvalidPassword = 1,
                BlockThresholdPopularPassword = 1,
                BlockThresholdUnpopularPassword = 1,
                PenaltyMulitiplierForTypo = .25d
            };

            //
            // Configure so that a single login attempt with an incorrect password
            // login will block future logins with correct passwords... unless
            // the incorrect login was the result of a typo.
            //
            TestConfiguration configuration = InitTest(options);

            const string userName = "******";
            await CreateTestAccountAsync(configuration, userName, "IRunESPStudies");

            // First, make sure we are correctly blocking when the failed login is not a typo.
            
            // Login attempt with incorrect password that is not a typo
            LoginAttempt attempt = await AuthenticateAsync(configuration, userName, "AndNowForAPasswordThat'sCompletelyDifferent", clientAddress: AttackersIp);
            Assert.Equal(AuthenticationOutcome.CredentialsInvalidIncorrectPassword, attempt.Outcome);

            // Login attempt that should be blocked
            attempt = await AuthenticateAsync(configuration, userName, "IRunESPStudies", clientAddress: AttackersIp);
            Assert.Equal(AuthenticationOutcome.CredentialsValidButBlocked, attempt.Outcome);

            // With another IP, lgoin with an incorrect password that IS a typo
            attempt = await AuthenticateAsync(configuration, userName, "IRunEPSStudies", clientAddress: ClientsIp);
            Assert.Equal(AuthenticationOutcome.CredentialsInvalidIncorrectPassword, attempt.Outcome);

            // Login attempt should be allowed through once typo is accounted for.
            attempt = await AuthenticateAsync(configuration, userName, "IRunESPStudies", clientAddress: ClientsIp);
            Assert.Equal(AuthenticationOutcome.CredentialsValid, attempt.Outcome);

        }
Ejemplo n.º 13
0
        /// <summary>
        /// Evaluate the accuracy of our stopguessing service by sending user logins and malicious traffic
        /// </summary>
        /// <returns></returns>
        public async Task Run(BlockingAlgorithmOptions options, string ParameterSweep, CancellationToken cancellationToken = default(CancellationToken))
        {
            //1.Create account from Rockyou 
            //Create 2*accountnumber accounts, first half is benign accounts, and second half is correct accounts owned by attackers

            //Record the accounts into stable store 
            try
            {
                GenerateSimulatedAccounts();

                List<SimulatedAccount> allAccounts = new List<SimulatedAccount>(BenignAccounts);
                allAccounts.AddRange(MaliciousAccounts);
                Parallel.ForEach(allAccounts, async simAccount =>
                {
                    UserAccount account = UserAccount.Create(simAccount.UniqueId, (int)CreditLimits.Last().Limit,
                            simAccount.Password, "PBKDF2_SHA256", 1);
                    foreach (string cookie in simAccount.Cookies)
                        account.HashesOfDeviceCookiesThatHaveSuccessfullyLoggedIntoThisAccount.Add(LoginAttempt.HashCookie(cookie));
                    await MyUserAccountController.PutAsync(account, cancellationToken: cancellationToken);
                });
            }
            catch (Exception e)
            {
                using (StreamWriter file = new StreamWriter(@"account_error.txt"))
                {
                    file.WriteLine("{0} Exception caught in account creation.", e);
                    file.WriteLine("time is {0}", DateTime.Now.ToString(CultureInfo.InvariantCulture));
                    //                    file.WriteLine("How many requests? {0}", i);
                }
            }

            //using (StreamWriter file = new StreamWriter(@"account.txt"))
            //{
            //    file.WriteLine("time is {0}", DateTime.Now.ToString(CultureInfo.InvariantCulture));
            //    file.WriteLine("How many requests? {0}", i);
            //}


            Stopwatch sw = new Stopwatch();
            sw.Start();

            Stats stats = new Stats();

            //ulong maliciouscount = 0;
            //ulong benigncount = 0;
            double falsePositiveRate = 0;
            double falseNegativeRate = 0;
            //The percentage of malicious attempts get caught (over all malicious attempts)
            double detectionRate = 0;
            //The percentage of benign attempts get labeled as malicious (over all benign attempts)
            double falseDetectionRate = 0;



            //            List<int> Runtime = new List<int>(new int[MyExperimentalConfiguration.TotalLoginAttemptsToIssue]);

            for (int bigi = 0; bigi < (int)(MyExperimentalConfiguration.TotalLoginAttemptsToIssue / MyExperimentalConfiguration.RecordUnitAttempts); bigi++)
            {

                await TaskParalllel.ParallelRepeat(MyExperimentalConfiguration.RecordUnitAttempts, async () =>
                {
                    SimulatedLoginAttempt simAttempt;
                    if (StrongRandomNumberGenerator.GetFraction() <
                        MyExperimentalConfiguration.FractionOfLoginAttemptsFromAttacker)
                    {
                        simAttempt = MaliciousLoginAttemptBreadthFirst();
                    }
                    else
                    {
                        simAttempt = BenignLoginAttempt();
                    }

                    LoginAttempt attemptWithOutcome = await
                        MyLoginAttemptController.LocalPutAsync(simAttempt.Attempt, simAttempt.Password);//,
                                                                                                        // cancellationToken: cancellationToken);
                    AuthenticationOutcome outcome = attemptWithOutcome.Outcome;

                    lock (stats)
                    {
                        stats.TotalLoopIterationsThatShouldHaveRecordedStats++;
                        if (stats.TruePositives == 1)
                        {
                            stats.bootstrapsuccess = stats.FalseNegatives;
                            stats.bootstrapall = stats.MaliciousCount;

                        }
                        if (simAttempt.IsGuess)
                        {
                            stats.MaliciousCount++;
                            if (outcome == AuthenticationOutcome.CredentialsValidButBlocked)
                                stats.TruePositives++;
                            else if (outcome == AuthenticationOutcome.CredentialsValid)
                                stats.FalseNegatives++;
                            else
                                stats.GuessWasWrong++;
                        }
                        else
                        {
                            stats.BenignCount++;
                            if (outcome == AuthenticationOutcome.CredentialsValid)
                                stats.TrueNegatives++;
                            else if (outcome == AuthenticationOutcome.CredentialsValidButBlocked)
                                stats.FalsePositives++;
                            else
                                stats.BenignErrors++;
                        }
                    }
                },
            (e) => {
                lock (stats)
                {
                    stats.TotalExceptions++;
                }
                Console.Error.WriteLine(e.ToString());
                //count++; 
            });
                if (((double)stats.FalsePositives + stats.TruePositives) != 0)
                {
                    falsePositiveRate = ((double)stats.FalsePositives) / ((double)stats.FalsePositives + stats.TruePositives);


                }
                if (((double)stats.FalseNegatives + stats.TrueNegatives) != 0)
                    falseNegativeRate = ((double)stats.FalseNegatives) / ((double)stats.FalseNegatives + stats.TrueNegatives);
                if (((double)stats.TruePositives + stats.FalseNegatives) != 0)
                    detectionRate = ((double)stats.TruePositives) / ((double)stats.TruePositives + stats.FalseNegatives);
                if (((double)stats.FalsePositives + stats.TrueNegatives) != 0)
                    falseDetectionRate = ((double)stats.FalsePositives) / ((double)stats.FalsePositives + stats.TrueNegatives);
                //using (StringWriter filename = new StringWriter())
                //{
                //    filename.Write("Detailed_PenaltyForReachingAPopularityThreshold{0}.txt", options.PenaltyForReachingEachPopularityThreshold[0]);

                //    //string filename = "Detailed_Log_Unpopular{0}.txt", options.BlockThresholdUnpopularPassword;
                //    using (StreamWriter detailed = File.AppendText(@filename.ToString()))
                //    {
                //        detailed.WriteLine("The false postive rate is {0}/({0}+{1}) ({2:F20}%)", stats.FalsePositives, stats.TruePositives, falsePositiveRate * 100d);
                //        detailed.WriteLine("The false negative rate is {0}/({0}+{1}) ({2:F20}%)", stats.FalseNegatives, stats.TrueNegatives, falseNegativeRate * 100d);
                //        detailed.WriteLine("The detection rate is {0}/({0}+{1}) ({2:F20}%)", stats.TruePositives, stats.FalseNegatives, detectionRate * 100d);
                //        detailed.WriteLine("The false detection rate is {0}/{0}+({1}) ({2:F20}%)", stats.FalsePositives, stats.TrueNegatives, falseDetectionRate * 100d);
                //        detailed.WriteLine("Start to catch attacker after {0} requests and attackers have login {1} times into users accounts successfully.", stats.bootstrapall, stats.bootstrapsuccess);
                //    }
                //}
                //using (StringWriter filename = new StringWriter())
                //{
                //    // filename.Write("Result.csv", options.BlockThresholdUnpopularPassword);

                //    //string filename = "Detailed_Log_Unpopular{0}.txt", options.BlockThresholdUnpopularPassword;
                //    using (StreamWriter CSV = File.AppendText(@"ResultDetail.csv"))
                //    {
                //        CSV.WriteLine("{0},{1},{2},{3},{4},{5},{6}, {7}", options.PenaltyForInvalidAccount, falsePositiveRate * 100d,
                //            falseNegativeRate * 100d, detectionRate * 100d, falseDetectionRate * 100d, stats.bootstrapall, stats.bootstrapsuccess, falsePositiveRate * 10000d);

                //    }
                //}

            }



            sw.Stop();

            Console.WriteLine("Time Elapsed={0}", sw.Elapsed);
            Console.WriteLine("the new count is {0}", stats.MaliciousCount + stats.BenignCount);

            //falsePositiveRate = ((double)stats.FalsePositives) / ((double)stats.FalsePositives + stats.TruePositives);
            //falseNegativeRate = ((double)stats.FalseNegatives) / ((double)stats.FalseNegatives + stats.TrueNegatives);

            //using (System.IO.StreamWriter file =
            //new System.IO.StreamWriter(@"result_log.txt"))
            //{
            //    file.WriteLine("The false postive rate is {0}/({0}+{1}) ({2:F20}%)", stats.FalsePositives, stats.TruePositives, falsePositiveRate * 100d);
            //    file.WriteLine("The false negative rate is {0}/({0}+{1}) ({2:F20}%)", stats.FalseNegatives, stats.TrueNegatives, falseNegativeRate * 100d);
            //    file.WriteLine("Time Elapsed={0}", sw.Elapsed);
            //}

            using (StringWriter filename = new StringWriter())
            {
                // filename.Write("Result.csv", options.BlockThresholdUnpopularPassword);

                if (ParameterSweep == "BlockThresholdUnpopularPassword")
                {
                    string csvname = "Log_BlockThresholdUnpopularPassword.csv";
                    using (StreamWriter CSV = File.AppendText(@csvname))
                    {
                        CSV.WriteLine("{0},{1},{2},{3},{4},{5},{6},{7}", options.BlockThresholdUnpopularPassword, falsePositiveRate * 100d,
                            falseNegativeRate * 100d, detectionRate * 100d, falseDetectionRate * 100d, stats.bootstrapall, stats.bootstrapsuccess, falsePositiveRate * 10000d);

                    }


                }
                else if (ParameterSweep == "BlockThresholdPopularPassword")
                {
                    string csvname = "Log_BlockThresholdPopularPassword.csv";
                    using (StreamWriter CSV = File.AppendText(@csvname))
                    {
                        CSV.WriteLine("{0},{1},{2},{3},{4},{5},{6},{7}", options.BlockThresholdPopularPassword, falsePositiveRate * 100d,
                            falseNegativeRate * 100d, detectionRate * 100d, falseDetectionRate * 100d, stats.bootstrapall, stats.bootstrapsuccess, falsePositiveRate * 10000d);

                    }


                }
                else if (ParameterSweep == "PenaltyForInvalidAccount")
                {
                    string csvname = "Log_PenaltyForInvalidAccount.csv";
                    using (StreamWriter CSV = File.AppendText(@csvname))
                    {
                        CSV.WriteLine("{0},{1},{2},{3},{4},{5},{6},{7}", options.PenaltyForInvalidAccount, falsePositiveRate * 100d,
                            falseNegativeRate * 100d, detectionRate * 100d, falseDetectionRate * 100d, stats.bootstrapall, stats.bootstrapsuccess, falsePositiveRate * 10000d);

                    }
                }
                else if (ParameterSweep == "RewardForCorrectPasswordPerAccount")
                {
                    string csvname = "RewardForCorrectPasswordPerAccount.csv";
                    using (StreamWriter CSV = File.AppendText(@csvname))
                    {
                        CSV.WriteLine("{0},{1},{2},{3},{4},{5},{6},{7}", options.RewardForCorrectPasswordPerAccount, falsePositiveRate * 100d,
                            falseNegativeRate * 100d, detectionRate * 100d, falseDetectionRate * 100d, stats.bootstrapall, stats.bootstrapsuccess, falsePositiveRate * 10000d);

                    }
                }
                else if (ParameterSweep == "PenaltyForReachingEachPopularityThreshold")
                {
                    string csvname = "PenaltyForReachingEachPopularityThreshold.csv";
                    using (StreamWriter CSV = File.AppendText(@csvname))
                    {
                        CSV.WriteLine("{0},{1},{2},{3},{4},{5},{6},{7}", 1, falsePositiveRate * 100d,
                            falseNegativeRate * 100d, detectionRate * 100d, falseDetectionRate * 100d, stats.bootstrapall, stats.bootstrapsuccess, falsePositiveRate * 10000d);

                    }
                }


            }
        }