ENOWARS Blog

11 July 2019

Unhappy Flagsubmission, Part 1

by Trolldemorted

Immediately after we opened the network, multiple teams exploited Voting, and complained that our flag submission endpoint was always responding INTERNAL_ERROR.

As you have noticed, the issue was fixed during the CTF, and I mentioned on IRC that this error would not have happened in Rust. Since you might be interested in details, here we go:

for (int i = 0; i < acceptedSubmissions.Count; i++)
{
    if (inserts[i].SubmissionsCount == 1)
    {
        var t = Task.Run(() => acceptedSubmissions[i].TrySetResult(FlagSubmissionResult.Ok));
        okFlags += 1;
    }
    else
    {
        var t = Task.Run(() => acceptedSubmissions[i].TrySetResult(FlagSubmissionResult.Duplicate));
        duplicateFlags += 1;
    }
}

This is the loop which processes the results of a batched insert... on conflict do update statement, and sets the result of the TaskCompletionSources which the tcp connection handlers await. Setting a TaskCompletionSource’s result is the way to go, as the continuation of whatever awaits it is executed synchronously.

The problem here is that, under the hood, i is one variable. The spawned tasks which set the result are executed on the thread pool, so they might or might not start immediately - but the variable i will increase in the next loop, regardless of the spawned task has already captured i or not!

So some TaskCompletionSources were not covered by that loop, and were set to INTERNAL_ERROR by a “set everything else to error” block. The flags were inserted fine, though!

tags: ENOWARS3 - C# - EnoEngine