Пример #1
0
        public async Task Check(string host)
        {
            var client = new AsyncHttpClient(GetBaseUri(host), true);

            var result = await client.DoRequestAsync(HttpMethod.Get, "/", null, NetworkOpTimeout, MaxHttpBodySize).ConfigureAwait(false);

            if (result.StatusCode != HttpStatusCode.OK)
            {
                throw new CheckerException(result.StatusCode.ToExitCode(), "get / failed");
            }

            await RndUtil.RndDelay(MaxDelay).ConfigureAwait(false);

            var query = "?query=" + WebUtility.UrlEncode(RndText.RandomWord(RndUtil.GetInt(2, 10)));

            result = await client.DoRequestAsync(HttpMethod.Get, ApiNotesSearch + query, null, NetworkOpTimeout, MaxHttpBodySize).ConfigureAwait(false);

            if (result.StatusCode != HttpStatusCode.OK)
            {
                throw new CheckerException(result.StatusCode.ToExitCode(), $"get {ApiNotesSearch} failed");
            }

            var notes = DoIt.TryOrDefault(() => JsonSerializer.Deserialize <List <Note> >(result.BodyAsString));

            if (notes == default)
            {
                throw new CheckerException(ExitCode.MUMBLE, $"invalid {ApiNotesSearch} response");
            }

            await Console.Error.WriteLineAsync($"found '{notes.Count}' notes by query '{query}'").ConfigureAwait(false);
        }
Пример #2
0
        public async Task Get(string host, string id, string flag, int vuln)
        {
            var parts = id.Split(':');

            if (parts.Length != 3)
            {
                throw new Exception($"Invalid flag id '{id}'");
            }

            var login  = parts[0];
            var pass   = parts[1];
            var cookie = Encoding.UTF8.GetString(Convert.FromBase64String(parts[2]));

            var client = new AsyncHttpClient(GetBaseUri(host), true);

            var result = await client.DoRequestAsync(HttpMethod.Get, ApiScoreboard, null, NetworkOpTimeout, MaxHttpBodySize).ConfigureAwait(false);

            if (result.StatusCode != HttpStatusCode.OK)
            {
                throw new CheckerException(result.StatusCode.ToExitCode(), $"get {ApiScoreboard} failed");
            }

            var solutions = DoIt.TryOrDefault(() => JsonSerializer.Deserialize <List <Solution> >(result.BodyAsString));

            if (solutions == default || solutions.Count == 0 || solutions.All(sln => sln.Login != login))
            {
                throw new CheckerException(ExitCode.MUMBLE, $"invalid {ApiScoreboard} response");
            }

            await RndUtil.RndDelay(MaxDelay).ConfigureAwait(false);

            client = new AsyncHttpClient(GetBaseUri(host), true);
            client.Cookies.SetCookies(GetBaseUri(host), cookie);

            result = await client.DoRequestAsync(HttpMethod.Get, ApiAuth, null, NetworkOpTimeout, MaxHttpBodySize).ConfigureAwait(false);

            if (result.StatusCode != HttpStatusCode.OK)
            {
                throw new CheckerException(result.StatusCode.ToExitCode(), $"get {ApiAuth} failed");
            }

            var user = DoIt.TryOrDefault(() => JsonSerializer.Deserialize <User>(result.BodyAsString));

            if (user == default || user.Login != login || user.Bio != flag)
            {
                throw new CheckerException(ExitCode.CORRUPT, "flag not found");
            }
        }
Пример #3
0
        public async Task <string> Put(string host, string id, string flag, int vuln)
        {
            var client = new AsyncHttpClient(GetBaseUri(host), true);

            var result = await client.DoRequestAsync(HttpMethod.Get, ApiGenerate, null, NetworkOpTimeout, MaxHttpBodySize).ConfigureAwait(false);

            if (result.StatusCode != HttpStatusCode.OK)
            {
                throw new CheckerException(result.StatusCode.ToExitCode(), $"get {ApiGenerate} failed");
            }

            var rubik = DoIt.TryOrDefault(() => JsonSerializer.Deserialize <GeneratedRubik>(result.BodyAsString));

            if (rubik == default)
            {
                throw new CheckerException(ExitCode.MUMBLE, $"invalid {ApiGenerate} response");
            }

            await Console.Error.WriteLineAsync($"rubik '{rubik.Rubik}', signed '{rubik.Value}'").ConfigureAwait(false);

            string solution;

            try
            {
                solution = DoIt.TryOrDefault(() => SolveHelper.ConvertOutputSolution(RubikSolver.FindSolution(SolveHelper.ConvertInputCube(rubik.Rubik), 32, 10000)));
            }
            catch (RubikSolveException e)
            {
                await Console.Error.WriteLineAsync(e.Message).ConfigureAwait(false);

                throw new CheckerException(ExitCode.MUMBLE, $"invalid {ApiGenerate} response: unsolvable puzzle");
            }

            await Console.Error.WriteLineAsync($"solution '{solution}'").ConfigureAwait(false);

            await RndUtil.RndDelay(MaxDelay).ConfigureAwait(false);

            var login = RndText.RandomWord(RndUtil.GetInt(MinRandomFieldLength, MaxRandomFieldLength)).RandomLeet().RandomUpperCase();
            var pass  = RndText.RandomWord(RndUtil.GetInt(MinRandomFieldLength, MaxRandomFieldLength)).RandomLeet().RandomUpperCase();

            await Console.Error.WriteLineAsync($"name '{login}', pass '{pass}', bio '{flag}'").ConfigureAwait(false);

            var query = $"?login={WebUtility.UrlEncode(login)}&pass={WebUtility.UrlEncode(pass)}&bio={WebUtility.UrlEncode(flag)}&puzzle={WebUtility.UrlEncode(rubik.Value)}&solution={WebUtility.UrlEncode(solution)}";

            result = await client.DoRequestAsync(HttpMethod.Post, ApiSolve + query, null, NetworkOpTimeout, MaxHttpBodySize).ConfigureAwait(false);

            if (result.StatusCode != HttpStatusCode.OK)
            {
                throw new CheckerException(result.StatusCode.ToExitCode(), $"post {ApiSolve} failed");
            }

            var sln = DoIt.TryOrDefault(() => JsonSerializer.Deserialize <Solution>(result.BodyAsString));

            if (sln == default || sln.Login != login || sln.MovesCount != solution.Length)
            {
                throw new CheckerException(ExitCode.MUMBLE, $"invalid {ApiSolve} response");
            }

            await Console.Error.WriteLineAsync($"solution '{solution}'").ConfigureAwait(false);

            var cookie = client.Cookies.GetCookieHeader(GetBaseUri(host));
            await Console.Error.WriteLineAsync($"cookie '{cookie}'").ConfigureAwait(false);

            if (string.IsNullOrEmpty(cookie) || cookie.Length > 512)
            {
                throw new CheckerException(result.StatusCode.ToExitCode(), $"invalid {ApiSolve} response: cookies");
            }

            return($"{login}:{pass}:{Convert.ToBase64String(Encoding.UTF8.GetBytes(cookie))}");
        }
Пример #4
0
        public async Task Check(string host)
        {
            var client = new AsyncHttpClient(GetBaseUri(host), true);

            var result = await client.DoRequestAsync(HttpMethod.Get, "/", null, NetworkOpTimeout, MaxHttpBodySize).ConfigureAwait(false);

            if (result.StatusCode != HttpStatusCode.OK)
            {
                throw new CheckerException(result.StatusCode.ToExitCode(), "get / failed");
            }

            await RndUtil.RndDelay(MaxDelay).ConfigureAwait(false);

            result = await client.DoRequestAsync(HttpMethod.Get, ApiGenerate, null, NetworkOpTimeout, MaxHttpBodySize).ConfigureAwait(false);

            if (result.StatusCode != HttpStatusCode.OK)
            {
                throw new CheckerException(result.StatusCode.ToExitCode(), $"get {ApiGenerate} failed");
            }

            var rubik = DoIt.TryOrDefault(() => JsonSerializer.Deserialize <GeneratedRubik>(result.BodyAsString));

            if (rubik == default)
            {
                throw new CheckerException(ExitCode.MUMBLE, $"invalid {ApiGenerate} response");
            }

            await Console.Error.WriteLineAsync($"rubik '{rubik.Rubik}', signed '{rubik.Value}'").ConfigureAwait(false);

            await RndUtil.RndDelay(MaxDelay).ConfigureAwait(false);

            var login = RndText.RandomWord(RndUtil.GetInt(MinRandomFieldLength, MaxRandomFieldLength)).RandomLeet().RandomUpperCase();
            var pass  = RndText.RandomWord(RndUtil.GetInt(MinRandomFieldLength, MaxRandomFieldLength)).RandomLeet().RandomUpperCase();
            var flag  = RndText.RandomWord(RndUtil.GetInt(MinRandomFieldLength, MaxRandomFieldLength)).RandomLeet().RandomUpperCase();

            await Console.Error.WriteLineAsync($"name '{login}', pass '{pass}', bio '{flag}'").ConfigureAwait(false);

            var solution = RndRubik.RandomSolution(MinRandomSolutionLength, MaxRandomSolutionLength);
            var query    = $"?login={WebUtility.UrlEncode(login)}&pass={WebUtility.UrlEncode(pass)}&bio={WebUtility.UrlEncode(flag)}&puzzle={WebUtility.UrlEncode(rubik.Value)}&solution={WebUtility.UrlEncode(solution)}";

            result = await client.DoRequestAsync(HttpMethod.Post, ApiSolve + query, null, NetworkOpTimeout, MaxHttpBodySize).ConfigureAwait(false);

            if (result.StatusCode != (HttpStatusCode)418)
            {
                throw new CheckerException(result.StatusCode == HttpStatusCode.OK ? ExitCode.MUMBLE : result.StatusCode.ToExitCode(), $"invalid {ApiSolve} response");
            }

            await RndUtil.RndDelay(MaxDelay).ConfigureAwait(false);

            result = await client.DoRequestAsync(HttpMethod.Get, ApiAuth, null, NetworkOpTimeout, MaxHttpBodySize).ConfigureAwait(false);

            if (result.StatusCode != HttpStatusCode.OK)
            {
                throw new CheckerException(result.StatusCode.ToExitCode(), $"get {ApiAuth} failed");
            }

            var user = DoIt.TryOrDefault(() => JsonSerializer.Deserialize <User>(result.BodyAsString));

            if (user == default || user.Login != login || user.Bio != flag)
            {
                throw new CheckerException(ExitCode.MUMBLE, $"invalid {ApiAuth} response");
            }
        }
Пример #5
0
        public async Task <string> Put(string host, string id, string flag, int vuln)
        {
            var client = new AsyncHttpClient(GetBaseUri(host), true);

            var login = RndText.RandomWord(RndUtil.GetInt(MinRandomFieldLength, MaxRandomFieldLength)).RandomLeet().RandomUpperCase();
            var name  = RndText.RandomWord(RndUtil.GetInt(MinRandomFieldLength, MaxRandomFieldLength)).RandomLeet().RandomUpperCase();
            var pass  = RndText.RandomWord(RndUtil.GetInt(MinRandomFieldLength, MaxRandomFieldLength)).RandomLeet().RandomUpperCase();

            await Console.Error.WriteLineAsync($"login '{login}', name '{name}', pass '{pass}'").ConfigureAwait(false);

            var signUpQuery = $"?login={WebUtility.UrlEncode(login)}&name={WebUtility.UrlEncode(name)}&password={WebUtility.UrlEncode(pass)}";
            var result      = await client.DoRequestAsync(HttpMethod.Post, ApiAuthSignUp + signUpQuery, null, NetworkOpTimeout, MaxHttpBodySize).ConfigureAwait(false);

            if (result.StatusCode != HttpStatusCode.OK)
            {
                throw new CheckerException(result.StatusCode.ToExitCode(), $"get {ApiAuthSignUp} failed");
            }

            await RndUtil.RndDelay(MaxDelay).ConfigureAwait(false);

            var items = Enumerable.Range(0, RndUtil.GetInt(1, 3)).Select(i => new Note {
                Title = RndText.RandomText(RndUtil.GetInt(MinRandomTitleLength, MaxRandomTitleLength)).RandomUmlauts(),
                Text  = RndText.RandomText(RndUtil.GetInt(MinRandomTextLength, MaxRandomTextLength)).RandomUmlauts()
            }).ToArray();

            var itemWithFlag = RndUtil.Choice(items);

            if (RndUtil.GetInt(0, 2) == 0)
            {
                itemWithFlag.Text = flag;
            }
            else
            {
                itemWithFlag.Title = flag;
            }
            itemWithFlag.IsPrivate = true;

            foreach (var item in items)
            {
                await Console.Error.WriteLineAsync($"title '{item.Title}', text '{item.Text}', isPrivate '{item.IsPrivate}'").ConfigureAwait(false);

                var q = $"?title={WebUtility.UrlEncode(item.Title)}&text={WebUtility.UrlEncode(item.Text)}" + (item.IsPrivate ? "&isPrivate=on" : null);
                result = await client.DoRequestAsync(HttpMethod.Post, ApiNotesAdd + q, null, NetworkOpTimeout).ConfigureAwait(false);

                if (result.StatusCode != HttpStatusCode.OK)
                {
                    throw new CheckerException(result.StatusCode.ToExitCode(), $"post {ApiNotesAdd} failed");
                }

                await RndUtil.RndDelay(MaxDelay).ConfigureAwait(false);
            }

            var query = GetRandomQuery(itemWithFlag);

            if (query.Trim('\"', ' ').Length <= 4)            //NOTE: too low entropy
            {
                query = flag;
            }

            await Console.Error.WriteLineAsync($"random query '{query}'").ConfigureAwait(false);

            var cookie = client.Cookies.GetCookieHeader(GetBaseUri(host));
            await Console.Error.WriteLineAsync($"cookie '{cookie}'").ConfigureAwait(false);

            var bytes = DoIt.TryOrDefault(() => Encoding.UTF8.GetBytes(cookie));

            if (bytes == null || bytes.Length > 1024)
            {
                throw new CheckerException(result.StatusCode.ToExitCode(), "too large or invalid cookies");
            }

            return($"{login}:{pass}:{Convert.ToBase64String(bytes)}:{WebUtility.UrlEncode(query)}");
        }
Пример #6
0
        public async Task Get(string host, string id, string flag, int vuln)
        {
            var parts = id.Split(':', 4);

            if (parts.Length != 4)
            {
                throw new Exception($"Invalid flag id '{id}'");
            }

            var login        = parts[0];
            var pass         = parts[1];
            var cookie       = Encoding.UTF8.GetString(Convert.FromBase64String(parts[2]));
            var encodedQuery = parts[3];

            var client = new AsyncHttpClient(GetBaseUri(host), true);

            if (RndUtil.GetInt(0, 2) == 0)
            {
                await Console.Error.WriteLineAsync($"login by cookie '{cookie}'").ConfigureAwait(false);

                client.Cookies.SetCookies(GetBaseUri(host), cookie);
            }
            else
            {
                await Console.Error.WriteLineAsync($"login with login '{login}' and pass '{pass}'").ConfigureAwait(false);

                var loginQuery   = $"?login={WebUtility.UrlEncode(login)}&password={WebUtility.UrlEncode(pass)}";
                var signInResult = await client.DoRequestAsync(HttpMethod.Post, ApiAuthSignIn + loginQuery).ConfigureAwait(false);

                if (signInResult.StatusCode != HttpStatusCode.OK)
                {
                    throw new CheckerException(signInResult.StatusCode.ToExitCode(), $"get {ApiAuthSignIn} failed");
                }

                await Console.Error.WriteLineAsync($"cookie '{client.Cookies.GetCookieHeader(GetBaseUri(host))}'").ConfigureAwait(false);

                await RndUtil.RndDelay(MaxDelay).ConfigureAwait(false);
            }

            var query = RndUtil.Choice("?query=&myOnly=on", "?query=" + encodedQuery);

            var result = await client.DoRequestAsync(HttpMethod.Get, ApiNotesSearch + query, null, NetworkOpTimeout, MaxHttpBodySize).ConfigureAwait(false);

            if (result.StatusCode != HttpStatusCode.OK)
            {
                throw new CheckerException(result.StatusCode.ToExitCode(), $"get {ApiNotesSearch} failed");
            }

            var notes = DoIt.TryOrDefault(() => JsonSerializer.Deserialize <List <Note> >(result.BodyAsString));

            if (notes == default)
            {
                throw new CheckerException(ExitCode.MUMBLE, $"invalid {ApiNotesSearch} response");
            }

            await Console.Error.WriteLineAsync($"found '{notes.Count}' notes by query '{query}'").ConfigureAwait(false);

            var note = notes.FirstOrDefault(note => note.Author.Contains(flag) || note.Title.Contains(flag) || note.Text.Contains(flag));

            if (note == null)
            {
                throw new CheckerException(ExitCode.CORRUPT, "flag not found");
            }

            //NOTE: Also check phrase query

            if (!query.StartsWith("?query=%22") || !query.EndsWith("%22"))
            {
                return;
            }

            var words = WebUtility.UrlDecode(encodedQuery).Trim('"', ' ').Split().Where(word => !string.IsNullOrWhiteSpace(word)).Distinct().ToArray();

            if (words.Length < 2)
            {
                return;
            }

            query = string.Join(' ', words.Reverse());
            if (note.Author.Contains(query, StringComparison.InvariantCultureIgnoreCase) || note.Title.Contains(query, StringComparison.InvariantCultureIgnoreCase) || note.Text.Contains(query, StringComparison.InvariantCultureIgnoreCase))
            {
                return;
            }

            query = "?query=" + WebUtility.UrlEncode('"' + query + '"');
            await Console.Error.WriteLineAsync($"check phrase query reversed '{query}'").ConfigureAwait(false);

            result = await client.DoRequestAsync(HttpMethod.Get, ApiNotesSearch + query, null, NetworkOpTimeout, MaxHttpBodySize).ConfigureAwait(false);

            if (result.StatusCode != HttpStatusCode.OK)
            {
                throw new CheckerException(result.StatusCode.ToExitCode(), $"get {ApiNotesSearch} failed");
            }

            notes = DoIt.TryOrDefault(() => JsonSerializer.Deserialize <List <Note> >(result.BodyAsString));
            if (notes == default)
            {
                throw new CheckerException(ExitCode.MUMBLE, $"invalid {ApiNotesSearch} response");
            }

            await Console.Error.WriteLineAsync($"found '{notes.Count}' notes by query '{query}'").ConfigureAwait(false);

            if (notes.Any(note => note.Author.Contains(flag) || note.Title.Contains(flag) || note.Text.Contains(flag)))
            {
                throw new CheckerException(ExitCode.MUMBLE, $"invalid {ApiNotesSearch} response: phrase query");
            }
        }