VulnWorker.cs
7.59 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
using LibGit2Sharp;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace VulnCrawler
{
public static class VulnWorker
{
// 템플릿 메서드 패턴
public static void Run<T>(string dirPath) where T : VulnAbstractCrawler, new() {
var crawler = new T();
crawler.Init(dirPath);
var commits = crawler.Commits;
Console.WriteLine(commits.Count());
foreach (var commit in commits) {
// 커밋 메시지
string message = commit.Message;
string cve = crawler.GetCVE(message);
if (string.IsNullOrEmpty(cve)) {
continue;
}
foreach (var parent in commit.Parents) {
// 부모 커밋과 현재 커밋을 Compare 하여 패치 내역을 가져옴
var patch = crawler.Repository.Diff.Compare<Patch>(parent.Tree, commit.Tree);
// 패치 엔트리 파일 배열 중에 파일 확장자가 .py인 것만 가져옴
// (실질적인 코드 변경 커밋만 보기 위해서)
var entrys = crawler.GetPatchEntryChanges(patch);
// 현재 커밋에 대한 패치 엔트리 배열을 출력함
PrintPatchEntrys(entrys, crawler, message, cve);
}
}
}
private static void PrintPatchEntrys(IEnumerable<PatchEntryChanges> entrys, VulnAbstractCrawler self, string commitMsg, string cve) {
foreach (var entry in entrys) {
// 기존 소스코드
var oldOid = entry.OldOid;
try
{
Blob oldBlob = self.Repository.Lookup<Blob>(oldOid);
string oldContent = oldBlob.GetContentText();
// 변경된 소스코드
var newOid = entry.Oid;
Blob newBlob = self.Repository.Lookup<Blob>(newOid);
string newContent = newBlob.GetContentText();
var regs = self.GetMatches(entry.Patch);
#region 패치 전 후 코드 출력
// 패치 전 코드 (oldContent)
// 패치 후 코드 (newContent)
// 패치 코드 (entry.Patch)
// 출력
if (regs.Count > 0)
{
Console.BackgroundColor = ConsoleColor.DarkBlue;
Console.WriteLine($"Old Content: \n{oldContent}");
Console.ResetColor();
//Console.BackgroundColor = ConsoleColor.DarkMagenta;
//Console.WriteLine($"New Content: \n{newContent}");
//Console.ResetColor();
Console.ForegroundColor = ConsoleColor.Blue;
Console.WriteLine($"status: {entry.Status.ToString()}");
Console.WriteLine($"added: {entry.LinesAdded.ToString()}, deleted: {entry.LinesDeleted.ToString()}");
Console.WriteLine($"old path: {entry.OldPath.ToString()}, new path: {entry.Path.ToString()}");
Console.ResetColor();
Console.Write($"CVE: ");
Console.ForegroundColor = ConsoleColor.Red;
Console.Write($"{cve}");
Console.WriteLine("");
Console.ResetColor();
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine($"Commit Message: {commitMsg}");
Console.ResetColor();
Console.BackgroundColor = ConsoleColor.DarkRed;
Console.WriteLine($"Patched: \n{entry.Patch}");
Console.ResetColor();
var table = self.ExtractGitCriticalMethodTable(entry.Patch);
foreach (var tuple in self.Process(oldBlob, table))
{
(var methodName, var blocks) = tuple;
Console.WriteLine($"메서드 이름 : {methodName}");
foreach (var block in blocks)
{
if (block.HasCritical)
{
Console.BackgroundColor = ConsoleColor.DarkMagenta;
}
else
{
Console.BackgroundColor = ConsoleColor.DarkGreen;
}
Console.WriteLine($"=====block({block.Num}, {block.HasCritical.ToString()})");
Console.WriteLine(block.Code);
Console.ResetColor();
Console.WriteLine($"MD5 = {block.Hash}");
}
}
//foreach (var item in table)
//{
// Console.WriteLine($"Method : {item.Key}");
// //foreach (var b in item.Value)
// //{
// // Console.WriteLine($"--{b}");
// //}
//}
Console.ReadLine();
}
else
{
continue;
}
// 패치 코드에서 매칭된 파이썬 함수들로부터
// 패치 전 코드 파일(oldBlob)을 탐색하여 원본 파이썬 함수 가져오고(originalFunc)
//
#endregion
//foreach (var reg in regs)
//{
// var match = reg as Match;
// string methodName = match.Groups[VulnAbstractCrawler.MethodName].Value.Trim();
// string originalFunc, md5;
// (originalFunc, md5) = self.Process(oldBlob.GetContentStream(),
// methodName);
// #region 현재 패치 엔트리 정보 출력(추가된 줄 수, 삭제된 줄 수, 패치 이전 경로, 패치 후 경로)
// // 패치 전 원본 함수
// Console.WriteLine($"Original Func: {originalFunc}");
// // 해쉬 후
// Console.WriteLine($"Original Func MD5: {md5}");
// //Console.BackgroundColor = ConsoleColor.DarkRed;
// //Console.WriteLine($"Patched: \n{entry.Patch}");
// Console.ResetColor();
// Console.ForegroundColor = ConsoleColor.Red;
// Console.WriteLine("==============================");
// Console.ResetColor();
// #endregion
//}
//Console.ReadLine();
}
catch (Exception e)
{
Console.WriteLine(entry.Patch);
Console.WriteLine(e.ToString());
Console.ReadLine();
continue;
}
}
}
}
}