示例#1
0
        private static List <(byte[], byte[])> GeneratePlainEncryptedPairs(byte[] imageBytes)
        {
            var result = new List <(byte[], byte[])>();
            var prefixWithEncryptedPixels = imageBytes.Skip(SubstitutionPermutationNetwork.GenerateRandomIV().Length + 0x38 - SubstitutionPermutationNetwork.BlockSizeBytes).ToList();

            for (int i = SubstitutionPermutationNetwork.BlockSizeBytes; i < prefixWithEncryptedPixels.Count - SubstitutionPermutationNetwork.BlockSizeBytes; i += SubstitutionPermutationNetwork.BlockSizeBytes)
            {
                var prevC = prefixWithEncryptedPixels.Skip(i - SubstitutionPermutationNetwork.BlockSizeBytes).Take(SubstitutionPermutationNetwork.BlockSizeBytes).ToArray();
                var c     = prefixWithEncryptedPixels.Skip(i).Take(SubstitutionPermutationNetwork.BlockSizeBytes).ToArray();

                var expectedP = new byte[] { 0, 0xFF, 0, 0, 0, 0xFF, 0, 0 };

                var input = SubstitutionPermutationNetwork.XorBlock(prevC, expectedP);
                result.Add((input, c));
            }
            return(result);
        }
示例#2
0
        static void Main(string[] args)
        {
//			ProofOfConecpt.Do();
//			return;

            if (args.Length < 1)
            {
                Console.WriteLine("Usage: sploit.exe <fileToDecrypt> [expectedKey]");
                Environment.Exit(1);
            }

            var expectedKey = args.Length >= 2 ? File.ReadAllBytes(args[1]) : new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };

            byte[] imageBytes;
            try
            {
                imageBytes = File.ReadAllBytes(args[0]);
            }
            catch (Exception e)
            {
                Console.WriteLine($"Can't read data from file {args[0]}", e);
                Environment.Exit(1);
                return;
            }

            var spn = new SubstitutionPermutationNetwork(SubstitutionPermutationNetwork.GenerateRandomKey());

            var pairs  = GeneratePlainEncryptedPairs(imageBytes);
            var plains = pairs.Select(tuple => tuple.Item1).ToArray();
            var encs   = pairs.Select(tuple => tuple.Item2).ToArray();

            var linearCryptoanalysis    = new LinearCryptoanalysis(spn);
            var bestLayerApproximations = linearCryptoanalysis.ChooseBestPathsStartingFromSingleSBoxInRound0(Exploit.maxSBoxesInLastRound, Exploit.maxSBoxesInRound, Exploit.thresholdBias).ToList();

            Console.WriteLine($"Total approximations: {bestLayerApproximations.Count}");

            var solutions = new List <Solution>();

            foreach (var approximationsGroup in bestLayerApproximations
                     .Where(layer => layer.round0sboxNum % 8 == 3 || (layer.round0sboxNum % 8 == 4 && ((layer.round0x & 0x01) == 0)))
                     .GroupBy(layer => layer.ActivatedSboxesNums.Aggregate("", (s, num) => s + num))
                     .OrderBy(group => group.Key))
            {
                foreach (var approximation in approximationsGroup.Distinct().OrderByDescending(layer => layer.inputProbability.Bias()).Take(6))
                {
                    solutions.AddRange(Exploit.HackApproximation(plains, encs, approximation, expectedKey));
                }
            }

            var solutionsDict = Exploit.OrderSolutions(solutions, expectedKey);

            var imageLength = imageBytes.Length - SubstitutionPermutationNetwork.GenerateRandomIV().Length;

            if (imageLength >= 65536)
            {
                throw new Exception("Unexpected image ciphertext length");
            }

            Console.WriteLine("\nBruting left bits..");

            var plaintextPrefixFrom4 = new byte[] { 0, 0, 0, 0, 0, 0, 0x36, 0, 0, 0 };
            var hackedKey            = GetFinalSolution(solutionsDict, imageBytes.Take(24).ToArray(), plaintextPrefixFrom4);

            if (hackedKey != null)
            {
                Console.WriteLine($"\nHACKED KEY: {hackedKey.ToHexUpperCase()}");
            }
            else
            {
                Console.WriteLine("BAD LUCK. Key not hacked");
            }
        }
示例#3
0
        public static int ProcessPut(string host, string id, string flag)
        {
            try
            {
                var tcpClient = ConnectToService(host, PUT_PORT);

                using (var stream = tcpClient.GetStream())
                {
                    var xA = DH.GenerateRandomXA(DH_x_bitsCount);
                    var yA = DH.CalculateYA(xA);
                    stream.WriteBigEndian(yA);

                    var yB          = stream.ReadBigIntBigEndian(NetworkStreamExtensions.DH_y_bytesCount);
                    var keyMaterial = DH.DeriveKey(yB, xA).ToByteArray(isBigEndian: true, isUnsigned: true);
                    var masterKey   = SubstitutionPermutationNetwork.CalcMasterKey(keyMaterial);

                    var flagPicture = FlagsPainter.DrawFlag(flag);

                    var spn           = new SubstitutionPermutationNetwork(masterKey);
                    var encryptedData = spn.EncryptWithPadding(flagPicture, SubstitutionPermutationNetwork.GenerateRandomIV());

                    stream.WriteLengthFieldAware(encryptedData);

                    var imageId = stream.ReadIntBigEndian();

                    Console.Error.WriteLine($"Got image id {imageId}");

                    string imageHash;
                    try
                    {
                        imageHash = CalcImageBytesHash(flagPicture);
                    }
                    catch (Exception e)
                    {
                        throw new ServiceException(ExitCode.CHECKER_ERROR, "Failed to calc hash of generated image", innerException: e);
                    }

                    var state = new State
                    {
                        FileId          = imageId,
                        MasterKeyHex    = Convert.ToBase64String(masterKey),
                        SourceImageHash = imageHash
                    };

                    var lastImageId = FindLastId(host);
                    SaveLastFileId(host, imageId);
                    if (lastImageId != null)
                    {
                        if (Math.Abs(lastImageId.Value - imageId) > MaxConsecutiveFileIdsDiff)
                        {
                            throw new ServiceException(ExitCode.MUMBLE, $"LastImageId {lastImageId}, got new imageId {imageId}, difference is more than threshold {MaxConsecutiveFileIdsDiff}. Possibly service was 'patched' to make ids non-predictable. It's not fairplay, so punishing service's SLA", "Unexpected image id");
                        }
                    }

                    Console.WriteLine(state.ToJsonString().ToBase64String());
                    return((int)ExitCode.OK);
                }
            }
            catch (ServiceException)
            {
                throw;
            }
            catch (Exception e)
            {
                throw new ServiceException(ExitCode.DOWN, string.Format("General failure"), innerException: e);
            }
        }