Example #1
0
        public static void Main(string[] args)
        {
            //Application.Run(new CveSummaryGeneratorForm());

            // まとめ作成対象CVE一覧を取得
            var targetCVEs = GetTargetCVEs();

            // まとめ対象CVEを分割してリスト化
            string[] targetCVElist = targetCVEs.Split(' ');

            // 対象製品リストを取得
            var targetProducts = GetTargetProducts();

            // メモリ上のデータベースを作成
            DataSet dataSet = new DataSet();

            // まとめデータを扱うテーブルを作成
            DataTable summaryTable = new DataTable("SummaryTable");

            // まとめテーブルにカラム名の追加
            SetColumnsToSummaryTable(targetProducts, summaryTable);

            // DBにまとめテーブルを追加
            dataSet.Tables.Add(summaryTable);

            // 影響対象製品のデータを扱うテーブルを作成
            DataTable affectedTargetProductsTable = new DataTable("AffectedTargetProducts");

            // 影響対象製品のデータを扱うテーブルにカラム名を設定
            SetColumnsToAffectedTargetProductsTable(affectedTargetProductsTable);

            foreach (var cve in targetCVElist)
            {
                // サーバアクセスの間隔を1秒以上空けるようにする
                Thread.Sleep(1000);

                // CVEに対応する行を作成
                DataRow workRow = summaryTable.NewRow();

                // CVENumberを格納
                workRow[Constants.SummaryTableColumn.CveNumber] = cve;
                Console.WriteLine(cve);

                // 正規表現とマッチするかチェックする
                if (!Regex.IsMatch(cve, @"^(CVE-20[0-9][0-9]-\d{4}$|^ADV\d{6}$)"))
                {
                    workRow[Constants.SummaryTableColumn.Remarks] = "CVEの正規表現と一致しません";
                    summaryTable.Rows.Add(workRow);
                    continue;
                }

                //json形式CVE情報を取得する
                var JsonCveInfo = GetJsonCveInfo(cve);
                if (String.IsNullOrEmpty(JsonCveInfo))
                {
                    // TODO:エラーをそのまま出力できるようにメソッドを変更する
                    workRow[Constants.SummaryTableColumn.Remarks] = "404 Not Found";
                    summaryTable.Rows.Add(workRow);
                    continue;
                }

                // supply settings to JsonConvert.DeserializeObject to handle null values
                var settings = new JsonSerializerSettings
                {
                    NullValueHandling     = NullValueHandling.Ignore,
                    MissingMemberHandling = MissingMemberHandling.Ignore
                };
                // JSONを.NETのクラスにデシリアライズ
                SecurityGuidance sg = JsonConvert.DeserializeObject <SecurityGuidance>(JsonCveInfo, settings);

                // 共通項目のデータを格納する
                SetCommonCveValueToWorkRow(workRow, sg);

                // 対象とする製品のデータを抽出する
                var affectedTargetProducts = sg.AffectedProducts.Where(n =>
                                                                       n.Name == Constants.ProductName.Win_2012_R2_SeverCore ||
                                                                       n.Name == Constants.ProductName.Win_2012_R2 ||
                                                                       n.Name == Constants.ProductName.Win_2016_ServerCore ||
                                                                       n.Name == Constants.ProductName.Win_2016 ||
                                                                       n.Name.Contains(Constants.ProductName.MS_NET_Framework_4_x) ||
                                                                       n.Name.Contains(Constants.ProductName.MS_SQL_Server_2014_x) ||
                                                                       n.Name == Constants.ProductName.IE_11
                                                                       );

                // targetProductsの有無を判別し、なければ処理終了
                if (!affectedTargetProducts.Any())
                {
                    workRow[Constants.SummaryTableColumn.Remarks] = "CVEの対象製品の中に目的の製品が含まれていません";
                    summaryTable.Rows.Add(workRow);
                    continue;
                }

                // まとめデータ格納用クラスの初期化
                AffectedProduct summaryOfTargetProducts = new AffectedProduct();

                // ループに用いる変数を初期化
                bool isFirst = true;

                // 対象製品を有無を表すハッシュテーブルを作成する
                Hashtable TableRepresentingPresenceOfTargetProduct = CreateTableRepresentingPresenceOfTargetProduct(targetProducts);

                // 対象製品データのうち値が同じ項目は一つにまとめる
                foreach (var affectedTargetProduct in affectedTargetProducts)
                {
                    // Tableに新しい行を作成してaffectedTargetProduct情報をセット
                    SetAffectedTargetProductsRow(affectedTargetProductsTable, affectedTargetProduct, cve);

                    // CVEの影響対象製品と一致する目的製品を確認する
                    CheckIfContainToProductName(affectedTargetProduct.Name, TableRepresentingPresenceOfTargetProduct);

                    if (isFirst)
                    {
                        // 1番目のデータは丸ごと代入する
                        summaryOfTargetProducts = affectedTargetProduct;
                        isFirst = false;
                        continue;
                    }
                    else
                    {
                        // 2番目以降のデータは1番目と一致するか確認する
                        CheckIfEqualToAssignedData(summaryOfTargetProducts, affectedTargetProduct);
                    }
                }

                // ループで作成した対象製品データのまとめを格納する
                SetSummaryOfTargetProductsToWorkRow(workRow, summaryOfTargetProducts, TableRepresentingPresenceOfTargetProduct);

                // CVSSからCVEの攻撃のしやすさを判別する
                CheckEaseOfAttack(workRow);

                // Rows.Addメソッドを使ってデータを追加
                summaryTable.Rows.Add(workRow);
            }

            // TODO:CVEの脅威レベル(自作)で優先度順に並べられるようにする

            // CSVファイル保存先の完全パスを取得
            string csvPath = GetFullPathWithCurrentDirectoryAndCurrentTimeAsCSVFileName();

            Console.WriteLine(csvPath);

            // CSVコンバーターを呼び出す
            DatatableToCSVConverter csv = new DatatableToCSVConverter();

            // DistinctなダウンロードURLを取得する
            // TODO:ADV系の記事を集計から除去する or ADV系であることがわかるようにする
            DataTable distinctUrlForEachName = affectedTargetProductsTable.DefaultView.ToTable(true, "Name", "ArticleUrl1", "DownloadTitle1", "DownloadUrl1", "ArticleUrl2", "DownloadTitle2", "DownloadUrl2", "ArticleUrl3", "DownloadTitle3", "DownloadUrl3", "ArticleUrl4", "DownloadTitle4", "DownloadUrl4");

            // DataTableをCSVで保存する
            csv.ConvertDataTableToCsv(summaryTable, csvPath, true);
            csv.ConvertDataTableToCsv(affectedTargetProductsTable, csvPath + "_affectedTargetProducts.csv", true);
            csv.ConvertDataTableToCsv(distinctUrlForEachName, csvPath + "_distinctUrlForEachName.csv", true);

            Console.ReadLine();
        }
Example #2
0
        static void Main(string[] args)
        {
            string WIN2008 = "Windows Server 2008 for 32-bit Systems Service Pack 2";
            string WIN2012 = "Windows Server 2012 R2 (Server Core installation)";
            string WIN2016 = "Windows Server 2016  (Server Core installation)";
            var    wc      = new WebClient();

            wc.Encoding = Encoding.UTF8;

            // TODO:取得するCVE一覧を取得

            // TODO:CVE一覧から取得するCVEを一つずつ取得
            var cve = "CVE-2018-8308";

            // TODO:正規表現で正しいCVEかチェックする
            // (CVE - 20[0 - 9][0 - 9] -\d{ 4}|ADV\d{ 6})

            if (Regex.IsMatch(cve, @"(CVE-20[0-9][0-9]-\d{4}|ADV\d{6})"))
            {
                Console.WriteLine("正規表現と一致します");
            }
            else
            {
                Console.WriteLine("一致しません");
            }

            // APIからjson形式の文字列を取得
            var jsonString = wc.DownloadString(@"https://portal.msrc.microsoft.com/api/security-guidance/ja-JP/CVE/" + cve);

            // ダウンロードしたjson文字列を出力
            Console.WriteLine(jsonString);

            // JSONを.NETのクラスにデシリアライズ
            SecurityGuidance sg = JsonConvert.DeserializeObject <SecurityGuidance>(jsonString);

            // まとめデータを格納するテーブルを作成
            DataSet   dataSet = new DataSet();                 // 表形式のデータをメモリ領域へ格納するクラス
            DataTable table   = new DataTable("SummaryTable"); // 表形式のデータを扱う

            // カラム名の追加
            table.Columns.Add("CVE");
            table.Columns.Add("概要");
            table.Columns.Add("詳細");
            table.Columns.Add("一般に公開");
            table.Columns.Add("悪用");
            table.Columns.Add("最新のソフトウェア リリース");
            table.Columns.Add("過去のソフトウェア リリース");
            table.Columns.Add("VectorString");
            table.Columns.Add("BaseScore", Type.GetType("System.Double"));
            table.Columns.Add("TemporalScore", Type.GetType("System.Double"));
            table.Columns.Add("Severity");
            table.Columns.Add(WIN2008);
            table.Columns.Add(WIN2012);
            table.Columns.Add(WIN2016);

            // DataSetにDataTableを追加
            dataSet.Tables.Add(table);

            // TODO:「サービス拒否」の項目はjsonにないのか確認

            // 対象とする製品のデータを抽出する
            var targetProducts = sg.AffectedProducts.Where(n => n.Name == WIN2008 || n.Name == WIN2012 || n.Name == WIN2016);

            // まとめデータ格納用クラスの初期化
            AffectedProduct summaryOfTargetProducts = new AffectedProduct();

            // ループに用いる変数を初期化
            bool   isFirst         = true;
            string containsWIN2008 = "☓";
            string containsWIN2012 = "☓";
            string containsWIN2016 = "☓";

            // 対象製品データのうち値が同じ項目は一つにまとめる
            foreach (var product in targetProducts)
            {
                // CVEの対象製品が以下の製品のどれに該当するかチェックする
                if (product.Name == WIN2008)
                {
                    containsWIN2008 = "○";
                }
                if (product.Name == WIN2012)
                {
                    containsWIN2012 = "○";
                }
                if (product.Name == WIN2016)
                {
                    containsWIN2016 = "○";
                }

                if (isFirst)
                {
                    summaryOfTargetProducts = product;
                    isFirst = false;
                    continue;
                }

                if (!summaryOfTargetProducts.VectorString.Equals(product.VectorString))
                {
                    summaryOfTargetProducts.VectorString = "vectorStringの中に一致しないものがあります";
                    Console.WriteLine(summaryOfTargetProducts.VectorString);
                }

                if (!summaryOfTargetProducts.BaseScore.Equals(product.BaseScore))
                {
                    summaryOfTargetProducts.BaseScore = 0;
                    Console.WriteLine("baseScoreの中に一致しないものがあります");
                }

                if (!summaryOfTargetProducts.TemporalScore.Equals(product.TemporalScore))
                {
                    summaryOfTargetProducts.TemporalScore = 0;
                    Console.WriteLine("temporalScoreの中に一致しないものがあります");
                }

                if (!summaryOfTargetProducts.Severity.Equals(product.Severity))
                {
                    summaryOfTargetProducts.Severity = "severityの中に一致しないものがあります";
                    Console.WriteLine("severityの中に一致しないものがあります");
                }
            }

            // tableへのデータ追加用文字列を作成
            var LatestReleaseExploitability = sg.ExploitabilityAssessment.LatestReleaseExploitability.Id.ToString() + "-" + sg.ExploitabilityAssessment.LatestReleaseExploitability.Name; // 最新のソフトウェア リリース
            var OlderReleaseExploitability  = sg.ExploitabilityAssessment.OlderReleaseExploitability.Id.ToString() + "-" + sg.ExploitabilityAssessment.OlderReleaseExploitability.Name;   // 過去のソフトウェア リリース

            // Rows.Addメソッドを使ってデータを追加
            table.Rows.Add(cve
                           , sg.CveTitle
                           , sg.Description.Replace("\n", "")
                           , sg.PubliclyDisclosed
                           , sg.Exploited
                           , LatestReleaseExploitability
                           , OlderReleaseExploitability
                           , summaryOfTargetProducts.VectorString
                           , summaryOfTargetProducts.BaseScore
                           , summaryOfTargetProducts.TemporalScore
                           , summaryOfTargetProducts.Severity
                           , containsWIN2008
                           , containsWIN2012
                           , containsWIN2016);

            Console.WriteLine("tableの中身を表示");
            foreach (DataRow Row in table.Rows)
            {
                for (int i = 0; i < Row.ItemArray.Length; i++)
                {
                    Console.WriteLine(Row[i].ToString() + "|");
                }
            }

            // CSVコンバーターを呼び出す
            DatatableToCSVConverter csv = new DatatableToCSVConverter();

            // カレントディレクトリのパスを取得する
            string CurrentDir = Directory.GetCurrentDirectory();

            // ファイル名を現在時刻を「西暦月日時分秒」形式で取得する
            string now = DateTime.Now.ToString("yyyyMMddHHmmss");

            // 保存先のCSVファイルのパス
            string csvPath = CurrentDir + "/" + now + ".csv";

            // DataTableをCSVで保存する
            csv.ConvertDataTableToCsv(table, csvPath, true);

            Console.ReadLine();
        }