示例#1
0
        public static int ProcessGet(string host, string id, string flag)
        {
            log.Info("Processing Vuln2.Get");

            var state = JsonHelper.ParseJson <Vuln2State>(Convert.FromBase64String(id));

            log.InfoFormat("Looking for Election {0}", state.ElectionId);
            var election = ElectroClient.FindElection(host, Program.PORT, state.Voter.Cookies, state.ElectionId);

            if (election == null)
            {
                throw new ServiceException(ExitCode.CORRUPT, string.Format("Can't find election '{0}'", id));
            }
            log.InfoFormat("Election {0} found", state.ElectionId);

            var gotFlag = ExtractFlag(election, state.PrivateKey, flag.Length);

            if (flag != gotFlag)
            {
                throw new ServiceException(ExitCode.CORRUPT, string.Format("Invalid flag! Got '{0}' instead of expected '{1}'", gotFlag, flag));
            }

            log.Info("Flag found! OK");
            return((int)ExitCode.OK);
        }
示例#2
0
        public static KeyValuePair <User, int[]>[] RegisterVoters(string host, int[][] votes, User[] candidateUsers)
        {
            var fakeTasks      = votes.Take(candidateUsers.Length).Zip(candidateUsers, (vote, voter) => new { vote, voter, task = Task.FromResult(voter.Cookies) });
            var newVotersTasks = votes.Skip(candidateUsers.Length).Select(vote =>
            {
                var voter = UsersManager.GenRandomUser();
                return(new  { vote, voter, task = ElectroClient.RegUserAsync(host, Program.PORT, voter.Login, voter.Pass, voter.PublicMessage, voter.PrivateMessage) });
            }).ToArray();

            log.InfoFormat("Registering {0} new voters", newVotersTasks.Length);

            var voterTasks = fakeTasks.Concat(newVotersTasks).ToArray();

            KeyValuePair <User, int[]>[] voters;
            try
            {
                voters = voterTasks.Select(arg => { arg.voter.Cookies = arg.task.Result; return(new KeyValuePair <User, int[]>(arg.voter, arg.vote)); }).ToArray();
            }
            catch (AggregateException e)
            {
                throw new ServiceException(ExitCode.DOWN, string.Format("Failed to reg {0} voters in parallel: {1}", newVotersTasks.Length, e.Flatten()));
            }

            log.Info("Voters registered");
            return(voters);
        }
示例#3
0
        public static Election StartElection(string host, User candidate, bool isPublic, int nominateTimeInSec, int voteTimeInSec)
        {
            log.Info("Starting election...");
            var election = ElectroClient.StartElection(host, Program.PORT, candidate.Cookies, Utils.GenRandomElectionName(), isPublic, nominateTimeInSec, voteTimeInSec);

            if (election == null)
            {
                throw new ServiceException(ExitCode.MUMBLE, "Can't start election - result is NULL");
            }
            log.InfoFormat("Election {0} sarted", election.Id);
            return(election);
        }
示例#4
0
        private static void Vote(string host, KeyValuePair <User, int[]>[] voters, Guid id, PublicKey publicKey)
        {
            log.Info("Voting in parallel...");
            var candidateTasks = voters.Select(kvp => ElectroClient.VoteAsync(host, Program.PORT, kvp.Key.Cookies, id, HomoCrypto.EncryptVector(kvp.Value, publicKey))).ToArray();

            try
            {
                Task.WaitAll();
                log.InfoFormat("Voted by {0} users", voters.Length);
            }
            catch (Exception e)
            {
                throw new ServiceException(ExitCode.DOWN, string.Format("Failed to vote by {0} users in parallel: {1}", candidateTasks.Length, e));
            }
        }
示例#5
0
        public static int ProcessPut(string host, string id, string flag)
        {
            log.Info("Processing Vuln2.Put");

            var candidateUsers = RegisterCandidates(host, flag.Distinct().Select(c => UsersManager.GenUser(null, c.ToString())).OrderBy(user => user.Login).ToArray());

            var election   = StartElection(host, candidateUsers[0], false, nominateTimeInSec, voteTimeInSec);
            var privateKey = election.PrivateKeyForCandidates;

            var sw = Stopwatch.StartNew();

            election = NominateUsers(host, election, candidateUsers.Skip(1).ToArray());
            sw.Stop();

            var tts = nominateTimeInSec * 1000 - sw.ElapsedMilliseconds;

            if (tts > 0)
            {
                log.InfoFormat("Sleeping for {0}ms before voting (nomination duration is {1}s)", tts, nominateTimeInSec);
                Thread.Sleep((int)tts);
            }

            var votes = GenVotes(flag, election);

            var voters = RegisterVoters(host, votes, candidateUsers);

            log.InfoFormat("Voting by {0} voters", voters.Length);
            foreach (var voter in voters)
            {
                ElectroClient.Vote(host, Program.PORT, voter.Key.Cookies, election.Id, HomoCrypto.EncryptVector(voter.Value, election.PublicKey));
            }
            log.Info("Voted");

            var state = new Vuln2State
            {
                ElectionId = election.Id.ToString(),
                Voter      = voters[0].Key,
                PrivateKey = privateKey
            };

            log.Info("Flag put");
            Console.Out.WriteLine(Convert.ToBase64String(Encoding.UTF8.GetBytes(state.ToJsonString())));
            return((int)ExitCode.OK);
        }
示例#6
0
        public static User[] RegisterCandidates(string host, User[] users)
        {
            log.Info("Registering candidates...");
            var candidateTasks = users.Select(candidate => new { candidate, task = ElectroClient.RegUserAsync(host, Program.PORT, candidate.Login, candidate.Pass, candidate.PublicMessage, candidate.PrivateMessage) }).ToArray();

            try
            {
                var result = candidateTasks.Select(arg =>
                {
                    arg.candidate.Cookies = arg.task.Result;
                    return(arg.candidate);
                }).ToArray();
                log.InfoFormat("Registered {0} candidates", result.Length);
                return(result);
            }
            catch (Exception e)
            {
                throw new ServiceException(ExitCode.DOWN, string.Format("Failed to reg {0} candidates in parallel: {1}", candidateTasks.Length, e));
            }
        }
示例#7
0
        public static int ProcessGet(string host, string id, string flag)
        {
            log.Info("Processing Vuln1.Get");

            var state = JsonHelper.ParseJson <Vuln1State>(Convert.FromBase64String(id));

            var now            = DateTime.UtcNow;
            var elapsedSeconds = now.Subtract(state.ElectionStartDate).TotalMilliseconds;

            if (elapsedSeconds < 0)
            {
                throw new ServiceException(ExitCode.CHECKER_ERROR, string.Format("Possible time desynchronization on checksystem hosts! Election started in future: '{0}' and now is only '{1}'", state.ElectionStartDate.ToSortable(), now.ToSortable()));
            }

            var nominateEndTime = state.ElectionStartDate.AddSeconds(nominateTimeInSec);
            var voteEndTime     = state.ElectionStartDate.AddSeconds(nominateTimeInSec + voteTimeInSec);

            log.InfoFormat("Looking for Election {0}", state.ElectionId);
            var election = ElectroClient.FindElection(host, Program.PORT, state.Candidates[0].Cookies, state.ElectionId);

            if (election == null || election.Candidates == null || election.Candidates.Count < 2)
            {
                throw new ServiceException(ExitCode.CORRUPT, string.Format("Can't find election '{0}' or it has less than 2 candidates", state.ElectionId));
            }
            log.InfoFormat("Election {0} found", state.ElectionId);

            log.InfoFormat("Election startDt {0}", state.ElectionStartDate.ToSortable());
            log.InfoFormat("Nominate end Dt  {0}", nominateEndTime.ToSortable());
            log.InfoFormat("Vote end Dt      {0}", voteEndTime.ToSortable());
            log.InfoFormat("Now              {0}", now.ToSortable());

            if (now < nominateEndTime)
            {
                log.InfoFormat("Nomination is still going, got election, considering everything OK");
                return((int)ExitCode.OK);
            }
            else if (now < voteEndTime)
            {
                log.InfoFormat("Nomination finished, but voting is still going. Trying to win!");
                int notFlagNum = 0;
                for (; notFlagNum < election.Candidates.Count; notFlagNum++)
                {
                    if (election.Candidates[notFlagNum] != null && !election.Candidates[notFlagNum].IsMe)
                    {
                        break;
                    }
                }
                if (notFlagNum == election.Candidates.Count)
                {
                    throw new ServiceException(ExitCode.CORRUPT, string.Format("Can't find candidate with no flag in election '{0}'", state.ElectionId));
                }

                var random      = new Random();
                var votersCount = random.Next(votesMinCount, votesMaxCount + 1);

                var votesForWinner =
                    Enumerable.Repeat(Utils.GenVoteVector(election.Candidates.Count, notFlagNum), (votersCount / 2) + 1).ToArray();
                var restVotes = Utils.GenRandomVoteVectors(election.Candidates.Count, votersCount - votesForWinner.Length).ToArray();
                var votes     = votesForWinner.Concat(restVotes).ToArray();

                var voters = Vuln2Methods.RegisterVoters(host, votes, state.Candidates);
                Vote(host, voters, election.Id, election.PublicKey);
                return((int)ExitCode.OK);
            }
            else
            {
                log.InfoFormat("Voting has already finished. Considering everything OK");
                var realWinner = election.FindWinner();
                if (realWinner == null)
                {
                    throw new ServiceException(ExitCode.MUMBLE, string.Format("Can't find winner in election '{0}'", election.Id));
                }

                var winner = state.Candidates.FirstOrDefault(info => info.Login == realWinner.Name);
                if (winner == null)
                {
                    throw new ServiceException(ExitCode.CORRUPT, string.Format("We have no credentials for winner in election '{0}'. Possibly hacker won, so we lost a flag", election.Id));
                }

                log.InfoFormat("Reloading election, now as winner '{0}'", winner.Login);
                election = ElectroClient.FindElection(host, Program.PORT, winner.Cookies, election.Id.ToString());
                if (election == null)
                {
                    throw new ServiceException(ExitCode.CORRUPT, string.Format("Can't find election '{0}'", state.ElectionId));
                }

                if (election.Candidates.All(info => info.PrivateNotesForWinner != flag))
                {
                    throw new ServiceException(ExitCode.CORRUPT, "Can't find flag", null);
                }

                log.Info("Flag found! Ok");
                return((int)ExitCode.OK);
            }
        }
示例#8
0
        public static Election NominateUsers(string host, Election election, User[] candidates)
        {
            log.InfoFormat("Nominating rest {0} candidates for election...", candidates.Length);
            var nominateTasks = candidates.Select(candidate => new { candidate, task = ElectroClient.NominateAsync(host, Program.PORT, candidate.Cookies, election.Id) }).ToArray();

            Election[] elections;
            try
            {
                elections = nominateTasks.Select(arg => arg.task.Result).ToArray();
            }
            catch (Exception e)
            {
                throw new ServiceException(ExitCode.DOWN, string.Format("Failed to nominate {0} candidates in parallel: {1}", nominateTasks.Length, e));
            }

            var electionId = election.Id;

            election = elections.FirstOrDefault(election1 => election1 != null && election1.Candidates.Count >= candidates.Length + 1);
            if (election == null)
            {
                throw new ServiceException(ExitCode.MUMBLE, string.Format("Nominated '{0}' candidates for election '{1}', but got less in result", candidates.Length + 1, electionId));
            }

            log.Info("Candidates nomindated");
            return(election);
        }