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); }
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); }
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); }
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)); } }
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); }
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)); } }
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); } }
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); }