예제 #1
0
        static void Main(string[] args)
        {
            bool   hubUpload = false;
            string username  = null;
            string password  = null;

            if (args.Length < 1 || string.IsNullOrWhiteSpace(args[0]))
            {
                Console.Error.WriteLine("Arguments required: Scanner.exe <Path to Assembly to Scan> [<Output File>]");
                return;
            }

            if (args.Length < 2)
            {
                //No output argument. Do we have a preconfigured hub instance?
                if (Settings.Instance.Url != null)
                {
                    username = Settings.Instance.Username;
                    while (string.IsNullOrEmpty(username))
                    {
                        username = Prompt.Read($"Please enter a username for the hub instance at {Settings.Instance.Url}");
                    }
                    password = Settings.Instance.Password;
                    while (string.IsNullOrEmpty(password))
                    {
                        password = Prompt.ReadPassword($"Please enter the password for user {Settings.Instance.Username} at the Hub instance at {Settings.Instance.Url}");
                    }
                    hubUpload = true;
                }
                else
                {
                    Console.Error.WriteLine("No URL specified in configuration file. Exiting.");
                    return;
                }
            }


            string target = Path.GetFullPath(args[0]);

            Console.WriteLine("Scanning " + target + "...");

            ScannerJsonBuilder builder = scanAssembly(target);

            if (hubUpload)
            {
                HubUpload.UploadScan(Settings.Instance.Url, username, password, builder);
            }
            else
            {
                using (var fileWriter = new StreamWriter(args[1], false))
                {
                    builder.Write(fileWriter);
                }
            }
        }
예제 #2
0
        public static void UploadScan(string baseUrl, string username, string password, ScannerJsonBuilder scanResult)
        {
            //Prepare the cookies
            CookieContainer authCookies = authenticate(baseUrl, username, password);

            string requestUrl = $"{(baseUrl.EndsWith("/", StringComparison.Ordinal) ? baseUrl : baseUrl + "/")}{UPLOAD_URI}";

            var clientHandler = new HttpClientHandler()
            {
                CookieContainer = authCookies
            };
            var httpClient = new HttpClient(clientHandler);

            var content = new MultipartFormDataContent();


            using (var ms = new MemoryStream())
                using (var writer = new StreamWriter(ms))
                {
                    scanResult.Write(writer);
                    var streamContent = new ByteArrayContent(ms.ToArray());
                    streamContent.Headers.ContentType = System.Net.Http.Headers.MediaTypeHeaderValue.Parse("application/json");
                    content.Add(streamContent, "file", "scan.json");

                    var response = httpClient.PostAsync(requestUrl, content);
                    Task.WaitAll(response);

                    if (response.Result.StatusCode != HttpStatusCode.OK && response.Result.StatusCode != HttpStatusCode.Created)
                    {
                        throw new Exception($"Unable to upload to hub. Status code: {response.Result.StatusCode}. {response.Result.ReasonPhrase}");
                    }
                }
        }
예제 #3
0
        private static ScannerJsonBuilder scanAssembly(string target)
        {
            ScannerJsonBuilder builder = ScannerJsonBuilder.NewInstance();


            Assembly targetAssembly = Assembly.LoadFile(target);

            Console.WriteLine(targetAssembly.GetName().Name + " " + targetAssembly.GetName().GetPublicKey());

            //Prime the output model
            builder.ProjectName = targetAssembly.GetName().Name;
            builder.Release     = targetAssembly.GetName().Version.ToString();
            builder.AddDirectory(targetAssembly.GetName().Name, new FileInfo(target).FullName);

            //The files already scanned
            ISet <string> scannedPaths = new HashSet <String>();

            //The assembly references found that need scanning
            //For each reference, get the assembly that contains that reference, so we can look for DLLs at the parent's location.
            var assembliesToScan = new Queue <Tuple <AssemblyName, Assembly> >();

            assembliesToScan.Enqueue(Tuple.Create(targetAssembly.GetName(), targetAssembly));
            assembliesToScan.EnqueueAll(targetAssembly.GetReferencedAssemblies().Select(assemblyName => Tuple.Create(assemblyName, targetAssembly)));

            while (assembliesToScan.Count > 0)
            {
                try
                {
                    var          assemblyQueueEntry = assembliesToScan.Dequeue();
                    AssemblyName refAssemblyName    = assemblyQueueEntry.Item1;
                    Assembly     parentAssembly     = assemblyQueueEntry.Item2;


                    string parentAssemblyDirectory = Path.GetDirectoryName(parentAssembly.Location);
                    string targetLocation          = Path.Combine(parentAssemblyDirectory, refAssemblyName.Name + ".dll");
                    var    refAssembly             = File.Exists(targetLocation) ? Assembly.LoadFrom(targetLocation) : Assembly.Load(refAssemblyName);

                    String path = Path.GetFullPath(refAssembly.Location);
                    if (scannedPaths.Contains(path))
                    {
                        continue;
                    }

                    scannedPaths.Add(path);
                    //Note the file informatoin
                    FileVersionInfo fvi      = FileVersionInfo.GetVersionInfo(path);
                    string          name     = string.IsNullOrWhiteSpace(fvi.ProductName) ? refAssembly.GetName().Name : fvi.ProductName;
                    string          fileName = Path.GetFileName(path);
                    //We'll make our file names more descriptive than just the actual file name.
                    string fileEntry = ($"{fileName} - {name}[{fvi.ProductVersion}]");
                    Console.WriteLine("Found " + fileEntry);

                    bool blacklisted = false;
                    if (!string.IsNullOrWhiteSpace(path))
                    {
                        string sha1 = computeSha1(path);
                        if (fileName != Blacklist.Instance.Contains(sha1))
                        {
                            builder.AddFile(fileEntry, path, new FileInfo(path).Length, sha1);
                        }
                        else
                        {
                            blacklisted = true;
                        }
                    }
                    if (!blacklisted)
                    {
                        assembliesToScan.EnqueueAll(refAssembly.GetReferencedAssemblies().Select(parentAssemblyName => Tuple.Create(parentAssemblyName, refAssembly)));
                    }


                    //Find and document native code invocations.
                    var pInvokePaths = PInvokeSearcher.findPInvokePaths(refAssembly);
                    foreach (string nativeDllPath in pInvokePaths.FoundPaths.Where(fp => !scannedPaths.Contains(fp)))
                    {
                        FileVersionInfo dllVersionInfo = FileVersionInfo.GetVersionInfo(nativeDllPath);
                        String          dllFileName    = ($"{Path.GetFileName(nativeDllPath)} - {dllVersionInfo.ProductName}[{dllVersionInfo.ProductVersion}]");
                        string          sha1           = computeSha1(nativeDllPath);
                        if (!string.Equals(Blacklist.Instance.Contains(sha1), dllFileName))
                        {
                            Console.WriteLine("Found native: " + dllFileName);
                            builder.AddFile(dllFileName, nativeDllPath, new FileInfo(nativeDllPath).Length, sha1);
                        }
                        scannedPaths.Add(nativeDllPath);
                    }
                }
                catch (FileNotFoundException e)
                {
                    builder.AddScanProblem(e);
                    Console.Error.WriteLine(e.Message);
                }
            }
            return(builder);
        }
        static void Main(string[] args)
        {
            bool   hubUpload          = false;
            string username           = null;
            string password           = null;
            bool   ignoreSsl          = false;
            string targetAssemblyPath = null;
            string outputFile         = null;


            ParserResult <Options> parseResult = CommandLine.Parser.Default.ParseArguments <Options>(args).WithNotParsed(result =>
            {
                Console.Error.WriteLine("Invalid usage");
                Environment.Exit(1);
            }).WithParsed(options =>
            {
                ignoreSsl          = options.IgnoreSslErrors;
                outputFile         = options.OutputFile.FirstOrDefault();
                targetAssemblyPath = Path.GetFullPath(options.AssemblyToScan);
            });

            if (string.IsNullOrWhiteSpace(outputFile))
            {
                //No output argument. Do we have a preconfigured hub instance?
                if (Settings.Instance.Url != null)
                {
                    username = Settings.Instance.Username;
                    while (string.IsNullOrEmpty(username))
                    {
                        username = Prompt.Read($"Please enter a username for the hub instance at {Settings.Instance.Url}");
                    }
                    password = Settings.Instance.Password;
                    while (string.IsNullOrEmpty(password))
                    {
                        password = Prompt.ReadPassword($"Please enter the password for user {Settings.Instance.Username} at the Hub instance at {Settings.Instance.Url}");
                    }
                    hubUpload = true;
                }
                else
                {
                    Console.Error.WriteLine("No URL specified in configuration file and no output file specified. Exiting.");
                    Environment.Exit(1);
                }
            }

            if (ignoreSsl)
            {
                Console.WriteLine("SSL errors will be ignored.");
                ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, sslPolicyErrors) => true;
            }

            Console.WriteLine("Scanning " + targetAssemblyPath + "...");


            ScannerJsonBuilder builder = scanAssembly(targetAssemblyPath);

            if (hubUpload)
            {
                HubUpload.UploadScan(Settings.Instance.Url, username, password, builder);
            }
            else
            {
                using (var fileWriter = new StreamWriter(outputFile, false))
                {
                    builder.Write(fileWriter);
                }
            }
        }