Пример #1
0
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="endPoint">EndPoint</param>
 /// <param name="server">Server</param>
 /// <param name="httpsCertFile">HTTPS certificate file</param>
 /// <param name="httpsPassword">HTTPS certificate password</param>
 public RpcServer(IPEndPoint endPoint, FuzzerServer server, string httpsCertFile, string httpsPassword)
 {
     EndPoint                 = endPoint;
     Server                   = server;
     HTTPSCertFile            = httpsCertFile;
     HTTPSCertificatePassword = httpsPassword;
 }
Пример #2
0
        private static void PrintStats(FuzzerServer server)
        {
            if (Interlocked.Exchange(ref _refreshRequested, 0x01) == 0x01)
            {
                return;
            }

            new Task(() =>
            {
                AsyncPrintStats(server);
                Interlocked.Exchange(ref _refreshRequested, 0x00);
            })
            .Start();
        }
Пример #3
0
        private void Test(FuzzerConnectionBase serverConnection, FuzzerConnectionBase clientConnection)
        {
            Fuzzer.Client.ExecutionTimeOut = TimeSpan.FromMilliseconds(5_000);

            using (var server = new FuzzerServer())
                using (var client = new FuzzerClient())
                {
                    // Change name

                    client.PublicName = "TestClient_" + Guid.NewGuid().ToString();

                    // Ensure no error

                    client.SendLog(null);

                    // Dummy input

                    var entryIBuffer = new byte[100];
                    RandomHelper.FillWithRandomBytes(entryIBuffer);

                    var entryI = new FuzzerStat <FuzzingInputBase>(new ManualFuzzingInput(entryIBuffer)
                    {
                        Description = "1"
                    });
                    server.Inputs.Add(entryI.Source.Id, entryI);
                    entryI = new FuzzerStat <FuzzingInputBase>(new RandomFuzzingInput(new FromToValue <long>(100, 200))
                    {
                        Description = "2"
                    });
                    server.Inputs.Add(entryI.Source.Id, entryI);

                    // Dummy configurations

                    var entryC = new FuzzerStat <FuzzingConfigBase>(new PatchConfig("1", new PatchChange("1", 1, 1, new byte[0])));
                    server.Configurations.Add(entryC.Source.Id, entryC);
                    entryC = new FuzzerStat <FuzzingConfigBase>(new PatchConfig("2", new PatchChange("2", 2, 2, new byte[0])));
                    server.Configurations.Add(entryC.Source.Id, entryC);

                    // Check server

                    CheckConfig(() => ((IRandomValue <FuzzingConfigBase>)server).Get(), server.Configurations.Select(u => u.Value.Source).ToArray());
                    CheckConfig(() => ((IRandomValue <FuzzingInputBase>)server).Get(), server.Inputs.Select(u => u.Value.Source).ToArray());
                    CheckConfig(() => server.GetConfig(), server.Configurations.Select(u => u.Value.Source).ToArray());
                    CheckConfig(() => server.GetInput(), server.Inputs.Select(u => u.Value.Source).ToArray());

                    // Start

                    Assert.IsFalse(server.IsStarted);
                    Assert.IsFalse(client.IsStarted);

                    if (serverConnection == null && clientConnection == null)
                    {
                        Assert.Catch <NullReferenceException>(() => server.Start(serverConnection));
                        Assert.Catch <NullReferenceException>(() => client.Start(clientConnection));
                        return;
                    }
                    else
                    {
                        if (serverConnection is TestDummyConnection && clientConnection is TestDummyConnection)
                        {
                            Assert.Catch <ArgumentException>(() => server.Start(serverConnection));
                            Assert.Catch <ArgumentException>(() => client.Start(clientConnection));
                            return;
                        }
                    }

                    var waitInput    = new ManualResetEvent(false);
                    var waitConfigs  = new ManualResetEvent(false);
                    var waitLog      = new ManualResetEvent(false);
                    var waitLogError = new ManualResetEvent(false);

                    client.OnReceiveInputs         += (s, e) => waitInput.Set();
                    client.OnReceiveConfigurations += (s, e) => waitConfigs.Set();
                    server.OnReceiveLog            += (s, e) => (e.Any(u => u.Error != null) ? waitLogError : waitLog).Set();

                    server.Start(serverConnection);
                    Thread.Sleep(250);             // Wait for server
                    client.Start(clientConnection);

                    Assert.IsTrue(server.IsStarted);
                    Assert.IsTrue(client.IsStarted);

                    // Already started

                    Assert.Catch <Exception>(() => server.Start(serverConnection));
                    Assert.Catch <Exception>(() => client.Start(clientConnection));

                    // Check client

                    Assert.IsTrue(waitConfigs.WaitOne(TimeSpan.FromSeconds(10)), "Waiting for configs");
                    Assert.IsTrue(waitInput.WaitOne(TimeSpan.FromSeconds(10)), "Waiting for inputs");

                    Assert.AreEqual(1, server.Connections.Count);
                    Assert.IsTrue(server.Connections.Values.FirstOrDefault()?.Source.Description.Contains(client.PublicName));
                    Assert.AreNotEqual(Guid.Empty, server.Connections.Values.FirstOrDefault()?.Source.Id);
                    Assert.AreNotEqual(Guid.Empty, server.Connections.Values.FirstOrDefault()?.Id);

                    var speedInit = server.Connections.Values.FirstOrDefault().Source.Speed;

                    CheckConfig(() => ((IRandomValue <FuzzingConfigBase>)client).Get(), server.Configurations.Select(u => u.Value.Source).ToArray());
                    CheckConfig(() => ((IRandomValue <FuzzingInputBase>)client).Get(), server.Inputs.Select(u => u.Value.Source).ToArray());
                    CheckConfig(() => client.GetConfig(), server.Configurations.Select(u => u.Value.Source).ToArray());
                    CheckConfig(() => client.GetInput(), server.Inputs.Select(u => u.Value.Source).ToArray());

                    // Send log

                    var cfg   = client.GetConfig();
                    var input = client.GetInput();
                    var log   = new FuzzerLog()
                    {
                        ConfigId = cfg.Id,
                        InputId  = input.Id,
                        Coverage = 10,
                    };

                    var sIn  = server.Inputs.Select(u => u.Value).Where(u => u.Source.Id == log.InputId).FirstOrDefault();
                    var sCfg = server.Configurations.Select(u => u.Value).Where(u => u.Source.Id == log.ConfigId).FirstOrDefault();

                    Assert.AreEqual(0, server.Logs.Count);
                    Assert.AreEqual(0, server.UniqueErrors);
                    Assert.AreEqual(0, server.TotalErrors);

                    client.SendLog(log);

                    Assert.IsTrue(waitLog.WaitOne(TimeSpan.FromSeconds(10)), "Waiting for log");

                    Assert.AreEqual(0, server.Logs.Count);
                    Assert.AreEqual(0, server.UniqueErrors);
                    Assert.AreEqual(0, server.TotalErrors);

                    Thread.Sleep(250);

                    Assert.IsTrue(server.Connections.Values.FirstOrDefault().Source.Speed > speedInit);
                    Assert.AreEqual(log.Coverage, server.Connections.Values.FirstOrDefault().Source.Coverage);

                    // Check stats

                    Assert.AreEqual(1, sIn.Tests);
                    Assert.AreEqual(1, sCfg.Tests);
                    Assert.AreEqual(0, sIn.Crashes);
                    Assert.AreEqual(0, sCfg.Crashes);
                    Assert.AreEqual(0, sIn.Errors);
                    Assert.AreEqual(0, sCfg.Errors);

                    // Send error

                    log = new FuzzerLog()
                    {
                        ConfigId = cfg.Id,
                        InputId  = input.Id,
                        Error    = new FuzzerError()
                        {
                            ErrorId           = Guid.NewGuid(),
                            Error             = FuzzerError.EFuzzingErrorType.Crash,
                            ExplotationResult = FuzzerError.EExplotationResult.Exploitable,
                            ReplicationData   = new byte[0],
                        }
                    };

                    Assert.AreEqual(0, server.UniqueErrors);
                    Assert.AreEqual(0, server.TotalErrors);
                    client.SendLog(log);

                    waitLogError.Reset();
                    Assert.IsTrue(waitLogError.WaitOne(TimeSpan.FromSeconds(10)), "Waiting for error");

                    Assert.AreEqual(1, server.Logs.Count);
                    Assert.IsTrue(server.Logs.TryGetValue(log.Error.ErrorId, out var peekLog));
                    Assert.IsTrue(log.Equals(peekLog));
                    Assert.AreEqual(1, server.UniqueErrors);
                    Assert.AreEqual(1, server.TotalErrors);

                    // Check stats

                    Assert.AreEqual(2, sIn.Tests);
                    Assert.AreEqual(2, sCfg.Tests);
                    Assert.AreEqual(1, sIn.Crashes);
                    Assert.AreEqual(1, sCfg.Crashes);
                    Assert.AreEqual(0, sIn.Errors);
                    Assert.AreEqual(0, sCfg.Errors);

                    // Generic MultiClient

                    FuzzerLog gerr = null;
                    Fuzzer.Client.Stop();
                    if (serverConnection != clientConnection)
                    {
                        // Test default
                        Fuzzer.Client.Start(clientConnection);
                    }

                    waitLogError.Reset();

                    Fuzzer.Run(FuzWERSample, new FuzzerRunArgs()
                    {
                        OnLog = (l, c) =>
                        {
                            if (l.Error != null)
                            {
                                c.Cancel = true;
                                gerr     = l;
                            }
                        }
                    });

                    // Could spend more time because are more tests

                    Assert.IsTrue(waitLogError.WaitOne(TimeSpan.FromSeconds(30)), "Waiting for error");
                    Assert.AreEqual(2, server.Logs.Count);
                    Assert.IsTrue(server.Logs.TryGetValue(gerr.Error.ErrorId, out peekLog));
                    Assert.IsTrue(gerr.Equals(peekLog));
                    Assert.IsTrue(gerr.Error.ReplicationData.Length > 0);
                    Assert.AreEqual(FuzzerError.EExplotationResult.Exploitable, gerr.Error.ExplotationResult);
                    Assert.AreEqual(FuzzerError.EFuzzingErrorType.Crash, gerr.Error.Error);
                    Assert.AreEqual(2, server.UniqueErrors);
                    Assert.AreEqual(2, server.TotalErrors);

                    // Generic MultiThread Client

                    gerr = null;
                    Fuzzer.Client.Stop();
                    Thread.Sleep(250);             // Wait some time for pipes

                    if (serverConnection != clientConnection)
                    {
                        // Test default
                        Fuzzer.Client.Start(clientConnection);
                    }

                    waitLogError.Reset();

                    Fuzzer.Run(1, FuzMultiThreadSample, new FuzzerRunArgs()
                    {
                        OnLog = (l, c) =>
                        {
                            if (l.Error != null)
                            {
                                c.Cancel = true;
                                gerr     = l;
                            }
                        }
                    });

                    // Could spend more time because are more tests

                    Assert.IsTrue(waitLogError.WaitOne(TimeSpan.FromSeconds(30)), "Waiting for error");
                    Assert.AreEqual(3, server.Logs.Count);
                    Assert.IsTrue(server.Logs.TryGetValue(gerr.Error.ErrorId, out peekLog));
                    Assert.IsTrue(gerr.Equals(peekLog));
                    Assert.IsTrue(gerr.Error.ReplicationData.Length > 0);
                    Assert.AreEqual(3, server.UniqueErrors);
                    Assert.AreEqual(3, server.TotalErrors);

                    // Test timeout

                    gerr = null;
                    waitLogError.Reset();

                    Fuzzer.Client.ExecutionTimeOut = TimeSpan.FromMilliseconds(250);
                    Fuzzer.Run(FuzTimeoutSample, new FuzzerRunArgs()
                    {
                        OnLog = (l, c) =>
                        {
                            c.Cancel = true;

                            if (l.Error != null)
                            {
                                gerr = l;
                            }
                        }
                    });

                    Assert.IsTrue(waitLogError.WaitOne(TimeSpan.FromSeconds(5)), "Waiting for error");
                    Assert.AreEqual(4, server.Logs.Count);
                    Assert.IsTrue(server.Logs.TryGetValue(gerr.Error.ErrorId, out peekLog));
                    Assert.IsTrue(gerr.Equals(peekLog));
                    Assert.IsTrue(gerr.Error.ReplicationData.Length > 0);
                    Assert.AreEqual(4, server.UniqueErrors);
                    Assert.AreEqual(4, server.TotalErrors);

                    // Current stream

                    var           logReaded = new byte[255];
                    var           current   = new byte[logReaded.Length];
                    FuzzingStream fuzStream = null;

                    Fuzzer.Run((stream) =>
                    {
                        Array.Resize(ref current, stream.Read(current, 0, current.Length));
                        fuzStream = (FuzzingStream)stream;
                        Assert.IsNotNull(fuzStream.CurrentStream);
                    },
                               new FuzzerRunArgs()
                    {
                        StoreCurrent = true,
                        OnLog        = (l, c) =>
                        {
                            // Read current file

                            var fCurrent = ((FileStream)fuzStream.CurrentStream);
                            fCurrent.Seek(0, SeekOrigin.Begin);
                            Array.Resize(ref logReaded, fCurrent.Read(logReaded, 0, logReaded.Length));
                            c.Cancel = true;
                        },
                    });

                    Assert.IsNotNull(fuzStream);
                    Assert.IsNotNull(fuzStream.CurrentStream);
                    CollectionAssert.AreEqual(current, logReaded);

                    // Clean

                    Fuzzer.Client.Stop();

                    waitInput.Dispose();
                    waitConfigs.Dispose();
                    waitLog.Dispose();
                    waitLogError.Dispose();
                }
        }
Пример #4
0
        private static void Run(CmdOptions opts)
        {
            using (var server = new FuzzerServer())
            {
                RpcServer rpc = null;

                if (!string.IsNullOrEmpty(opts.RpcEndPoint))
                {
                    rpc = new RpcServer(opts.RpcEndPoint.ToIpEndPoint(), server, opts.RpcHttpsCertificate, opts.RpcHttpsCertificatePassword);
                    rpc.Start();
                }

                // Parse

                foreach (var file in CmdOptions.GetFiles(opts.Inputs))
                {
                    foreach (var i in SerializationHelper.DeserializeFromFile <FuzzingInputBase>(file))
                    {
                        server.Inputs.Add(i.Id, new FuzzerStat <FuzzingInputBase>(i));
                    }
                }

                foreach (var file in CmdOptions.GetFiles(opts.Configs))
                {
                    foreach (var i in SerializationHelper.DeserializeFromFile <FuzzingConfigBase>(file))
                    {
                        server.Configurations.Add(i.Id, new FuzzerStat <FuzzingConfigBase>(i));
                    }
                }

                // Checks

                if (server.Inputs.Count == 0 && rpc == null)
                {
                    Console.WriteLine("No inputs found");
                    return;
                }

                if (server.Configurations.Count == 0)
                {
                    // Create an empty mutation, only the original value

                    _showMutations = false;
                    var empty = new PatchConfig()
                    {
                        Changes     = new List <PatchChange>(),
                        Description = "Original input",
                        Id          = Guid.Empty
                    };
                    server.Configurations.Add(empty.Id, new FuzzerStat <FuzzingConfigBase>(empty));
                }

                server.Start(opts.GetConnection());

                // Listener

                server.OnNewConnection += (s, e) =>
                {
                    PrintStats(server);
                };

                server.OnReceiveLog += (s2, logs) =>
                {
                    foreach (var log in logs)
                    {
                        log.Error?.Save(opts.OnlyUniques);
                    }
                    PrintStats(server);
                };

                // UI

                do
                {
                    Console.Clear();
                    PrintStats(server);
                }while (Console.ReadKey().Key != ConsoleKey.Enter);

                rpc?.Dispose();
            }
        }
Пример #5
0
        private static void AsyncPrintStats(FuzzerServer server)
        {
            TitleColumnLength     = Math.Max(20, (Console.WindowWidth - 1) - StatColumnLength * 3);
            Console.CursorVisible = false;
            Console.SetCursorPosition(0, 0);

            // Write data

            var colorBottom = ConsoleColor.White;

            var cellTitle          = new ConsoleBox.Cell("Inputs", TitleColumnLength);
            var cellConfigurations = new ConsoleBox.Cell("Configurations", TitleColumnLength);
            var cellConnections    = new ConsoleBox.Cell("Connections", TitleColumnLength - (StatColumnLength * 2));

            var cellSpeed    = new ConsoleBox.Cell("Speed".PadLeft(StatColumnLength - 1, ' '), StatColumnLength);
            var cellCoverage = new ConsoleBox.Cell("Coverage".PadLeft(StatColumnLength - 1, ' '), StatColumnLength);
            var cellTest     = new ConsoleBox.Cell("Test".PadLeft(StatColumnLength - 1, ' '), StatColumnLength);
            var cellErrors   = new ConsoleBox.Cell("Errors".PadLeft(StatColumnLength - 1, ' '), StatColumnLength);
            var cellCrashes  = new ConsoleBox.Cell("Crashes".PadLeft(StatColumnLength - 1, ' '), StatColumnLength);

            WriteList(server.Inputs.Values, ConsoleColor.Yellow, colorBottom, cellTitle, cellTest, cellErrors, cellCrashes);
            if (_showMutations)
            {
                WriteList(server.Configurations.Values, ConsoleColor.Yellow, colorBottom, cellConfigurations, cellTest, cellErrors, cellCrashes);
            }
            WriteList(server.Connections.Values.ToArray(), ConsoleColor.Yellow, colorBottom, cellConnections, cellCoverage, cellSpeed, cellTest, cellErrors, cellCrashes);

            // Write summary

            var l  = (TitleColumnLength + (StatColumnLength * 3)) / 4;
            var lg = (TitleColumnLength + (StatColumnLength * 3)) - (l * 3);

            Console.ForegroundColor = colorBottom = ConsoleColor.Yellow;

            ConsoleBox.WriteCorner(CornerStyle.BoldTop, lg, l, l, l);

            if (server.UniqueErrors + server.TotalErrors > 0)
            {
                ConsoleBox.WriteContent(CornerStyle.BoldTop, "Unique", lg, BoxContentType.First);

                // Red color

                Console.ForegroundColor = server.UniqueErrors <= 0 ? colorBottom : ConsoleColor.Red;
                Console.Write(server.UniqueErrors.ToString().PadLeft(l - 1, ' '));

                Console.ForegroundColor = colorBottom;
                Console.Write(CornerStyle.BoldTop.BoxChar.ToString());
                ConsoleBox.WriteContent(CornerStyle.BoldTop, "Total", l, BoxContentType.Middle);

                Console.ForegroundColor = server.TotalErrors <= 0 ? colorBottom : ConsoleColor.Red;
                Console.Write(server.TotalErrors.ToString().PadLeft(l - 1, ' '));

                Console.ForegroundColor = colorBottom;
                Console.WriteLine(CornerStyle.BoldTop.BoxChar.ToString());
            }
            else
            {
                ConsoleBox.WriteContent(CornerStyle.BoldTop, "Unique", lg, BoxContentType.First);
                ConsoleBox.WriteContent(CornerStyle.BoldTop, server.UniqueErrors.ToString().PadLeft(l - 1, ' '), l, BoxContentType.Middle);
                ConsoleBox.WriteContent(CornerStyle.BoldTop, "Total", l, BoxContentType.Middle);
                ConsoleBox.WriteContent(CornerStyle.BoldTop, server.TotalErrors.ToString().PadLeft(l - 1, ' '), l, BoxContentType.Last);
            }

            ConsoleBox.WriteCorner(CornerStyle.BoldBot, lg, l, l, l);
        }