private static void CheckIfEqualToAssignedData(AffectedProduct summaryOfTargetProducts, AffectedProduct affectedTargetProduct) { if (affectedTargetProduct.VectorString != null && summaryOfTargetProducts.VectorString != null && !summaryOfTargetProducts.VectorString.Equals(affectedTargetProduct.VectorString)) { summaryOfTargetProducts.VectorString = default(string); Console.WriteLine("対象製品のVectorStringに一致しない値があります"); } if (!summaryOfTargetProducts.BaseScore.Equals(affectedTargetProduct.BaseScore)) { summaryOfTargetProducts.BaseScore = default(double); Console.WriteLine("対象製品のBaseScoreに一致しない値があります"); } if (!summaryOfTargetProducts.TemporalScore.Equals(affectedTargetProduct.TemporalScore)) { summaryOfTargetProducts.TemporalScore = default(double); Console.WriteLine("対象製品のTemporalScoreに一致しない値があります"); } if (!String.IsNullOrEmpty(summaryOfTargetProducts.Severity) && !summaryOfTargetProducts.Severity.Equals(affectedTargetProduct.Severity)) { summaryOfTargetProducts.Severity = default(string); Console.WriteLine("対象製品のSeverityの中に一致しないものがあります"); } }
private static void SetSummaryOfTargetProductsToWorkRow(DataRow workRow, AffectedProduct summaryOfTargetProducts, Hashtable tableRepresentingPresenceOfTargetProduct) { workRow[Constants.SummaryTableColumn.VectorString] = summaryOfTargetProducts.VectorString; workRow[Constants.SummaryTableColumn.BaseScore] = summaryOfTargetProducts.BaseScore; workRow[Constants.SummaryTableColumn.TemporalScore] = summaryOfTargetProducts.TemporalScore; // 深刻度が「緊急」の場合は攻撃しやすさ列に(+)として設定 workRow[Constants.SummaryTableColumn.Severity] = summaryOfTargetProducts.Severity; if (summaryOfTargetProducts.Severity == "緊急") { workRow[Constants.SummaryTableColumn.EaseOfAttack] += "(+)深刻度が緊急"; } foreach (string targetProductName in tableRepresentingPresenceOfTargetProduct.Keys) { workRow[targetProductName] = tableRepresentingPresenceOfTargetProduct[targetProductName]; } }
private static void SetAffectedTargetProductValuesToRow(AffectedProduct affectedTargetProduct, DataRow affectedTargetProductRow) { affectedTargetProductRow["Name"] = affectedTargetProduct.Name; affectedTargetProductRow["Platform"] = affectedTargetProduct.Platform; affectedTargetProductRow["ImpactId"] = affectedTargetProduct.ImpactId; affectedTargetProductRow["Impact"] = affectedTargetProduct.Impact; affectedTargetProductRow["SeverityId"] = affectedTargetProduct.SeverityId; affectedTargetProductRow["Severity"] = affectedTargetProduct.Severity; affectedTargetProductRow["BaseScore"] = affectedTargetProduct.BaseScore; affectedTargetProductRow["TemporalScore"] = affectedTargetProduct.TemporalScore; affectedTargetProductRow["EnvironmentScore"] = affectedTargetProduct.EnvironmentScore; affectedTargetProductRow["VectorString"] = affectedTargetProduct.VectorString; affectedTargetProductRow["Supersedence"] = affectedTargetProduct.Supersedence; affectedTargetProductRow["KnowledgeBaseId"] = affectedTargetProduct.KnowledgeBaseId; affectedTargetProductRow["KnowledgeBaseUrl"] = affectedTargetProduct.KnowledgeBaseUrl; affectedTargetProductRow["MonthlyKnowledgeBaseId"] = affectedTargetProduct.MonthlyKnowledgeBaseId; affectedTargetProductRow["MonthlyKnowledgeBaseUrl"] = affectedTargetProduct.MonthlyKnowledgeBaseUrl; affectedTargetProductRow["DownloadUrl"] = affectedTargetProduct.DownloadUrl; affectedTargetProductRow["DownloadTitle"] = affectedTargetProduct.DownloadTitle; affectedTargetProductRow["MonthlyDownloadUrl"] = affectedTargetProduct.MonthlyDownloadUrl; affectedTargetProductRow["MonthlyDownloadTitle"] = affectedTargetProduct.MonthlyDownloadTitle; affectedTargetProductRow["ArticleTitle1"] = affectedTargetProduct.ArticleTitle1; affectedTargetProductRow["ArticleUrl1"] = affectedTargetProduct.ArticleUrl1; affectedTargetProductRow["DownloadTitle1"] = affectedTargetProduct.DownloadTitle1; affectedTargetProductRow["DownloadUrl1"] = affectedTargetProduct.DownloadUrl1; affectedTargetProductRow["DoesRowOneHaveAtLeastOneArticleOrUrl"] = affectedTargetProduct.DoesRowOneHaveAtLeastOneArticleOrUrl; affectedTargetProductRow["ArticleTitle2"] = affectedTargetProduct.ArticleTitle2; affectedTargetProductRow["ArticleUrl2"] = affectedTargetProduct.ArticleUrl2; affectedTargetProductRow["DownloadTitle2"] = affectedTargetProduct.DownloadTitle2; affectedTargetProductRow["DownloadUrl2"] = affectedTargetProduct.DownloadUrl2; affectedTargetProductRow["DoesRowTwoHaveAtLeastOneArticleOrUrl"] = affectedTargetProduct.DoesRowTwoHaveAtLeastOneArticleOrUrl; affectedTargetProductRow["ArticleTitle3"] = affectedTargetProduct.ArticleTitle3; affectedTargetProductRow["ArticleUrl3"] = affectedTargetProduct.ArticleUrl3; affectedTargetProductRow["DownloadTitle3"] = affectedTargetProduct.DownloadTitle3; affectedTargetProductRow["DownloadUrl3"] = affectedTargetProduct.DownloadUrl3; affectedTargetProductRow["DoesRowThreeHaveAtLeastOneArticleOrUrl"] = affectedTargetProduct.DoesRowThreeHaveAtLeastOneArticleOrUrl; affectedTargetProductRow["ArticleTitle4"] = affectedTargetProduct.ArticleTitle4; affectedTargetProductRow["ArticleUrl4"] = affectedTargetProduct.ArticleUrl4; affectedTargetProductRow["DownloadTitle4"] = affectedTargetProduct.DownloadTitle4; affectedTargetProductRow["DownloadUrl4"] = affectedTargetProduct.DownloadUrl4; affectedTargetProductRow["DoesRowFourHaveAtLeastOneArticleOrUrl"] = affectedTargetProduct.DoesRowFourHaveAtLeastOneArticleOrUrl; affectedTargetProductRow["CountOfRowsWithAtLeastOneArticleOrUrl"] = affectedTargetProduct.CountOfRowsWithAtLeastOneArticleOrUrl; }
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(); }
private static void SetAffectedTargetProductsRow(DataTable affectedTargetProductsTable, AffectedProduct affectedTargetProduct, string cve) { // affectedTargetProductに対応する行を作成 DataRow affectedTargetProductRow = affectedTargetProductsTable.NewRow(); // CVENumberを格納 affectedTargetProductRow["CveNumber"] = cve; // affectedTargetProductの値を行へセット SetAffectedTargetProductValuesToRow(affectedTargetProduct, affectedTargetProductRow); // Rows.Addメソッドを使ってデータを追加 affectedTargetProductsTable.Rows.Add(affectedTargetProductRow); }
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(); }