Showing
9 changed files
with
287 additions
and
196 deletions
... | @@ -32,9 +32,10 @@ class HomeView(View): | ... | @@ -32,9 +32,10 @@ class HomeView(View): |
32 | # context['form'] = ServerList_form | 32 | # context['form'] = ServerList_form |
33 | # context['object_list'] = object_list | 33 | # context['object_list'] = object_list |
34 | 34 | ||
35 | + context = {} | ||
36 | + context['user_name'] = str(request.user) | ||
35 | 37 | ||
36 | - | 38 | + return render(self.request, self.template_name, context) |
37 | - return render(self.request, self.template_name) | ||
38 | 39 | ||
39 | def post(self, request, *args, **kwargs): | 40 | def post(self, request, *args, **kwargs): |
40 | 41 | ... | ... |
... | @@ -97,7 +97,9 @@ | ... | @@ -97,7 +97,9 @@ |
97 | <td>{{ object.update_date }}</td> | 97 | <td>{{ object.update_date }}</td> |
98 | <td>{{ object.fileName }}</td> | 98 | <td>{{ object.fileName }}</td> |
99 | <td>{{ object.funcName }}</td> | 99 | <td>{{ object.funcName }}</td> |
100 | - <td>{{ object.url }}</td> | 100 | + <td> |
101 | + <a href="{{ object.url }}">{{ object.url }}</a> | ||
102 | + </td> | ||
101 | <td>{{ object.cveDetail }}</td> | 103 | <td>{{ object.cveDetail }}</td> |
102 | </tr> | 104 | </tr> |
103 | {% endfor %} | 105 | {% endfor %} |
... | @@ -107,7 +109,7 @@ | ... | @@ -107,7 +109,7 @@ |
107 | <button id="prev" class="btn btn-primary" style="background-color: #FF0066; border: #FF0066;"><< Prev</button> | 109 | <button id="prev" class="btn btn-primary" style="background-color: #FF0066; border: #FF0066;"><< Prev</button> |
108 | <button id="next" class="btn btn-primary" style="margin-left: 200px; background-color: #FF0066; border: #FF0066;">Next >></button> | 110 | <button id="next" class="btn btn-primary" style="margin-left: 200px; background-color: #FF0066; border: #FF0066;">Next >></button> |
109 | </div> --> | 111 | </div> --> |
110 | - | 112 | + |
111 | 113 | ||
112 | <!-- {% for object in object_list %} | 114 | <!-- {% for object in object_list %} |
113 | <div class="portfolio-modal mfp-hide" id="portfolio-modal-{{ forloop.counter }}"> | 115 | <div class="portfolio-modal mfp-hide" id="portfolio-modal-{{ forloop.counter }}"> | ... | ... |
... | @@ -534,5 +534,7 @@ class StaticView(TemplateView): | ... | @@ -534,5 +534,7 @@ class StaticView(TemplateView): |
534 | context['level8'] = level8 | 534 | context['level8'] = level8 |
535 | context['level9'] = level9 | 535 | context['level9'] = level9 |
536 | 536 | ||
537 | + context['logined_user'] = str(request.user) | ||
538 | + | ||
537 | 539 | ||
538 | return render(self.request, self.template_name, context) | 540 | return render(self.request, self.template_name, context) | ... | ... |
... | @@ -47,6 +47,10 @@ | ... | @@ -47,6 +47,10 @@ |
47 | <li class="nav-item mx-0 mx-lg-1"> | 47 | <li class="nav-item mx-0 mx-lg-1"> |
48 | <a class="nav-link py-3 px-0 px-lg-3 rounded js-scroll-trigger" href="{% url 'edit' %}">Mypage</a> | 48 | <a class="nav-link py-3 px-0 px-lg-3 rounded js-scroll-trigger" href="{% url 'edit' %}">Mypage</a> |
49 | </li> | 49 | </li> |
50 | + <li class="nav-item mx-0 mx-lg-1"> | ||
51 | + <a class="nav-link py-3 px-0 px-lg-3 rounded js-scroll-trigger" style="color: yellow;" href="#">Welcome! {{ user_name }}</a> | ||
52 | + </li> | ||
53 | + | ||
50 | {% else %} | 54 | {% else %} |
51 | <li class="nav-item mx-0 mx-lg-1"> | 55 | <li class="nav-item mx-0 mx-lg-1"> |
52 | <a class="nav-link py-3 px-0 px-lg-3 rounded js-scroll-trigger" href="/accounts/login">Login</a> | 56 | <a class="nav-link py-3 px-0 px-lg-3 rounded js-scroll-trigger" href="/accounts/login">Login</a> | ... | ... |
... | @@ -35,7 +35,7 @@ namespace VulnCrawler | ... | @@ -35,7 +35,7 @@ namespace VulnCrawler |
35 | AWS.Account account = AWS.account; | 35 | AWS.Account account = AWS.account; |
36 | 36 | ||
37 | /* AWS 정보 출력 */ | 37 | /* AWS 정보 출력 */ |
38 | - Console.WriteLine($"Endpoint: {account.Endpoint}, ID: {account.Id}, PW: {account.Pw}"); | 38 | + Console.WriteLine($"Endpoint: {account.Endpoint}, ID: {account.Id}"); |
39 | try | 39 | try |
40 | { | 40 | { |
41 | /* DB 접속 시도 */ | 41 | /* DB 접속 시도 */ | ... | ... |
... | @@ -41,14 +41,11 @@ namespace VulnCrawler | ... | @@ -41,14 +41,11 @@ namespace VulnCrawler |
41 | if (string.IsNullOrEmpty(cve)) { | 41 | if (string.IsNullOrEmpty(cve)) { |
42 | continue; | 42 | continue; |
43 | } | 43 | } |
44 | - | ||
45 | string commitUrl = $"{crawler.PushUrl}/commit/{commit.Sha}"; | 44 | string commitUrl = $"{crawler.PushUrl}/commit/{commit.Sha}"; |
46 | 45 | ||
47 | foreach (var parent in commit.Parents) { | 46 | foreach (var parent in commit.Parents) { |
48 | try | 47 | try |
49 | { | 48 | { |
50 | - | ||
51 | - | ||
52 | // 부모 커밋과 현재 커밋을 Compare 하여 패치 내역을 가져옴 | 49 | // 부모 커밋과 현재 커밋을 Compare 하여 패치 내역을 가져옴 |
53 | var patch = crawler.Repository.Diff.Compare<Patch>(parent.Tree, commit.Tree); | 50 | var patch = crawler.Repository.Diff.Compare<Patch>(parent.Tree, commit.Tree); |
54 | 51 | ||
... | @@ -132,7 +129,7 @@ namespace VulnCrawler | ... | @@ -132,7 +129,7 @@ namespace VulnCrawler |
132 | }; | 129 | }; |
133 | 130 | ||
134 | /* VulnDB에 추가 */ | 131 | /* VulnDB에 추가 */ |
135 | - VulnRDS._InsertVulnData(vuln); | 132 | + //VulnRDS._InsertVulnData(vuln); |
136 | 133 | ||
137 | } | 134 | } |
138 | } | 135 | } | ... | ... |
... | @@ -11,7 +11,7 @@ using System.Threading.Tasks; | ... | @@ -11,7 +11,7 @@ using System.Threading.Tasks; |
11 | using VulnCrawler; | 11 | using VulnCrawler; |
12 | using Newtonsoft.Json; | 12 | using Newtonsoft.Json; |
13 | using Newtonsoft.Json.Linq; | 13 | using Newtonsoft.Json.Linq; |
14 | - | 14 | +using LibGit2Sharp; |
15 | 15 | ||
16 | namespace VulnUserCodeAnalyzer | 16 | namespace VulnUserCodeAnalyzer |
17 | { | 17 | { |
... | @@ -42,7 +42,12 @@ namespace VulnUserCodeAnalyzer | ... | @@ -42,7 +42,12 @@ namespace VulnUserCodeAnalyzer |
42 | public static void AutoLoad() | 42 | public static void AutoLoad() |
43 | { | 43 | { |
44 | var dir = new DirectoryInfo(@"c:\CVE"); | 44 | var dir = new DirectoryInfo(@"c:\CVE"); |
45 | - | 45 | + if (!dir.Exists) |
46 | + { | ||
47 | + Console.WriteLine("found not CVE Directory"); | ||
48 | + return; | ||
49 | + } | ||
50 | + Console.WriteLine("Loading CVE List..."); | ||
46 | foreach (var json in dir.EnumerateFiles("*.json")) | 51 | foreach (var json in dir.EnumerateFiles("*.json")) |
47 | { | 52 | { |
48 | var match = Regex.Match(json.Name, @"(20\d\d)"); | 53 | var match = Regex.Match(json.Name, @"(20\d\d)"); |
... | @@ -59,7 +64,7 @@ namespace VulnUserCodeAnalyzer | ... | @@ -59,7 +64,7 @@ namespace VulnUserCodeAnalyzer |
59 | var dict = LoadCveJson(int.Parse(match.Value)); | 64 | var dict = LoadCveJson(int.Parse(match.Value)); |
60 | CveDict.Add(year, dict); | 65 | CveDict.Add(year, dict); |
61 | 66 | ||
62 | - Console.WriteLine($"cve 로드 완료 {year}, 개수 : {CveDict[year].Count}"); | 67 | + Console.WriteLine($"Finished loading CVE List Year: {year}, Count: {CveDict[year].Count}"); |
63 | 68 | ||
64 | } | 69 | } |
65 | } | 70 | } |
... | @@ -109,12 +114,38 @@ namespace VulnUserCodeAnalyzer | ... | @@ -109,12 +114,38 @@ namespace VulnUserCodeAnalyzer |
109 | } | 114 | } |
110 | class Program | 115 | class Program |
111 | { | 116 | { |
112 | - static void Main(string[] args) | 117 | + /// <summary> |
118 | + /// Clone 콜백 함수 | ||
119 | + /// </summary> | ||
120 | + /// <param name="progress"></param> | ||
121 | + /// <returns></returns> | ||
122 | + public static bool TransferProgress(TransferProgress progress) | ||
123 | + { | ||
124 | + int totalBytes = progress.TotalObjects; | ||
125 | + int receivedBytes = progress.ReceivedObjects; | ||
126 | + long receivedTotal = progress.ReceivedBytes; | ||
127 | + double received = progress.ReceivedBytes / 1000000; | ||
128 | + double percent = ((double)receivedBytes / (double)totalBytes); | ||
129 | + Console.WriteLine($"Progress: {percent.ToString("P2")}, Remain: {receivedBytes} of {totalBytes}"); //, 받은 용량: {received.ToString()}MB"); | ||
130 | + Console.ForegroundColor = ConsoleColor.DarkGreen; | ||
131 | + return true; | ||
132 | + } | ||
133 | + public static void CheckoutProcess(string path, int completedSteps, int totalSteps) | ||
113 | { | 134 | { |
135 | + Console.WriteLine($"{completedSteps}, {totalSteps}, {path}"); | ||
136 | + } | ||
114 | 137 | ||
138 | + public static void Clone(string path, string url) | ||
139 | + { | ||
140 | + Console.WriteLine($"Start Cloning Path : {path}"); | ||
141 | + string clone = Repository.Clone(url, $@"{path}", new CloneOptions { OnTransferProgress = TransferProgress, OnCheckoutProgress = CheckoutProcess }); | ||
142 | + Console.ResetColor(); | ||
143 | + Console.WriteLine($"Finished Clone Repository: {clone}"); | ||
144 | + } | ||
145 | + static void Main(string[] args) | ||
146 | + { | ||
115 | /* 연도별 CVE JSON 파일 로드 */ | 147 | /* 연도별 CVE JSON 파일 로드 */ |
116 | - //CVE_JSON.AutoLoad(); | 148 | + CVE_JSON.AutoLoad(); |
117 | - | ||
118 | /* 크롤러 타입 */ | 149 | /* 크롤러 타입 */ |
119 | var crawler = new VulnC(); | 150 | var crawler = new VulnC(); |
120 | 151 | ||
... | @@ -129,7 +160,7 @@ namespace VulnUserCodeAnalyzer | ... | @@ -129,7 +160,7 @@ namespace VulnUserCodeAnalyzer |
129 | AWS.LoadAccount(xml); | 160 | AWS.LoadAccount(xml); |
130 | AWS.Account account = AWS.account; | 161 | AWS.Account account = AWS.account; |
131 | /* AWS 정보 출력 */ | 162 | /* AWS 정보 출력 */ |
132 | - Console.WriteLine($"Endpoint: {account.Endpoint}, ID: {account.Id}, PW: {account.Pw}"); | 163 | + Console.WriteLine($"Endpoint: {account.Endpoint}, ID: {account.Id}"); |
133 | try | 164 | try |
134 | { | 165 | { |
135 | /* DB 접속 시도 */ | 166 | /* DB 접속 시도 */ |
... | @@ -137,227 +168,267 @@ namespace VulnUserCodeAnalyzer | ... | @@ -137,227 +168,267 @@ namespace VulnUserCodeAnalyzer |
137 | } | 168 | } |
138 | catch (Exception e) | 169 | catch (Exception e) |
139 | { | 170 | { |
140 | - Console.WriteLine($"접속 에러 :: {e.ToString()}"); | 171 | + Console.WriteLine($"Connection Error :: {e.ToString()}"); |
141 | return; | 172 | return; |
142 | } | 173 | } |
143 | /* AWS 연결 여부 확인 */ | 174 | /* AWS 연결 여부 확인 */ |
144 | if (VulnRDS.Conn.State == System.Data.ConnectionState.Open) | 175 | if (VulnRDS.Conn.State == System.Data.ConnectionState.Open) |
145 | { | 176 | { |
146 | - Console.WriteLine("접속 성공"); | 177 | + Console.WriteLine("Connection Success"); |
147 | } | 178 | } |
148 | else | 179 | else |
149 | { | 180 | { |
150 | - Console.WriteLine("연결 실패"); | 181 | + Console.WriteLine("Fail Connection"); |
151 | return; | 182 | return; |
152 | } | 183 | } |
153 | - | 184 | + while (true) |
154 | - var reposits = VulnRDS.SelectAllReposit(); | ||
155 | - | ||
156 | - foreach (var (userName, repository) in reposits) | ||
157 | - { | ||
158 | - Console.WriteLine($"{userName}, {repository}"); | ||
159 | - } | ||
160 | - | ||
161 | - Console.ReadLine(); | ||
162 | - | ||
163 | - /* hashDict = 사용된 사용자 함수 정보 */ | ||
164 | - var hashDict = new Dictionary<int, HashSet<VulnAbstractCrawler.UserBlock>>(); | ||
165 | - /* 경과 시간 체크 */ | ||
166 | - Stopwatch stopwatch = new Stopwatch(); | ||
167 | - stopwatch.Start(); | ||
168 | - DirectoryInfo dirInfo = new DirectoryInfo(@"C:\code"); | ||
169 | - | ||
170 | - /* 모든 .c 파일 탐색 */ | ||
171 | - var codeFiles = dirInfo.EnumerateFiles("*.c", SearchOption.AllDirectories); | ||
172 | - int totalFileCount = codeFiles.Count(); | ||
173 | - int count = 0; | ||
174 | - foreach (var codeFile in codeFiles) | ||
175 | { | 185 | { |
176 | - Console.WriteLine(codeFile.FullName); | 186 | + string userId = string.Empty; |
177 | - using (var reader = codeFile.OpenText()) | 187 | + string repoPath = string.Empty; |
188 | + Stopwatch repoWatch = new Stopwatch(); | ||
189 | + repoWatch.Start(); | ||
190 | + while (true) | ||
178 | { | 191 | { |
179 | - /* 사용자 코드를 함수별로 나눔 */ | 192 | + var elapsedSeconds = repoWatch.Elapsed.TotalSeconds; |
180 | - var dict = crawler.CrawlUserCode(reader); | 193 | + if (elapsedSeconds < 10) |
181 | - foreach (var item in dict) | ||
182 | { | 194 | { |
183 | - /* hashDict의 키와 item.key는 함수 블록의 코드 길이 */ | 195 | + continue; |
184 | - if (!hashDict.ContainsKey(item.Key)) | 196 | + } |
197 | + Console.WriteLine("Checking User DB..."); | ||
198 | + var reposits = VulnRDS.SelectAllReposit(); | ||
199 | + foreach (var (userName, repository) in reposits) | ||
200 | + { | ||
201 | + if (string.IsNullOrWhiteSpace(repository)) | ||
185 | { | 202 | { |
186 | - hashDict[item.Key] = new HashSet<VulnAbstractCrawler.UserBlock>(); | 203 | + continue; |
187 | } | 204 | } |
188 | - /* item.Value는 각 코드 길이 마다의 블록 정보 | 205 | + var repoBytes = Encoding.Unicode.GetBytes(repository); |
189 | - * Bloom Filter에 코드 블록 해쉬값 기록 | 206 | + var repoBase64 = Convert.ToBase64String(repoBytes); |
190 | - */ | 207 | + var repoDir = new DirectoryInfo($@"C:\Repo\{repoBase64}"); |
191 | - foreach (var hash in item.Value) | 208 | + if (repoDir.Exists) |
192 | { | 209 | { |
193 | - hash.Path = codeFile.FullName; | 210 | + continue; |
194 | - hashDict[item.Key].Add(hash); | ||
195 | - filter.Add(hash.Hash); | ||
196 | } | 211 | } |
212 | + repoDir.Create(); | ||
213 | + Console.WriteLine($"Clone... Path : {repoDir.FullName}, Url : {repository}"); | ||
214 | + Clone(repoDir.FullName, repository); | ||
215 | + repoPath = repoDir.FullName; | ||
216 | + userId = userName; | ||
217 | + } | ||
218 | + if (!string.IsNullOrWhiteSpace(repoPath) && !string.IsNullOrWhiteSpace(userId)) | ||
219 | + { | ||
220 | + break; | ||
197 | } | 221 | } |
198 | - count++; | 222 | + repoWatch.Restart(); |
199 | - double per = ((double)count / (double)totalFileCount) * 100; | ||
200 | - Console.WriteLine($"{count} / {totalFileCount} :: {per.ToString("#0.0")}%, 개체 수 : {hashDict.Count}"); | ||
201 | } | 223 | } |
202 | - } | 224 | + //Console.WriteLine("엔터를 누르세요"); |
203 | - var findBlocks = new Queue<VulnAbstractCrawler.UserBlock>(); | 225 | + //Console.ReadLine(); |
204 | - var vulnDict = new Dictionary<string, IEnumerable<VulnRDS._Vuln>>(); | 226 | + |
205 | - foreach (var set in hashDict) | 227 | + /* hashDict = 사용된 사용자 함수 정보 */ |
206 | - { | 228 | + var hashDict = new Dictionary<int, HashSet<VulnAbstractCrawler.UserBlock>>(); |
207 | - /* 사용자 코드의 길이 마다 DB로 부터 같은 길이의 CVE 레코드 목록 가져옴 */ | 229 | + /* 경과 시간 체크 */ |
208 | - var cveList = VulnRDS.SelectVulnbyLen(set.Key).Select(v => v.Cve).Distinct(); | 230 | + Stopwatch stopwatch = new Stopwatch(); |
209 | - foreach (var cve in cveList) | 231 | + stopwatch.Start(); |
232 | + DirectoryInfo dirInfo = new DirectoryInfo(repoPath); | ||
233 | + | ||
234 | + /* 모든 .c 파일 탐색 */ | ||
235 | + var codeFiles = dirInfo.EnumerateFiles("*.c", SearchOption.AllDirectories); | ||
236 | + int totalFileCount = codeFiles.Count(); | ||
237 | + int count = 0; | ||
238 | + foreach (var codeFile in codeFiles) | ||
210 | { | 239 | { |
211 | - if (!vulnDict.ContainsKey(cve)) | 240 | + Console.WriteLine(codeFile.FullName); |
241 | + using (var reader = codeFile.OpenText()) | ||
212 | { | 242 | { |
213 | - vulnDict[cve] = new HashSet<VulnRDS._Vuln>(); | 243 | + /* 사용자 코드를 함수별로 나눔 */ |
214 | - var vulnHashSet = vulnDict[cve] as HashSet<VulnRDS._Vuln>; | 244 | + var dict = crawler.CrawlUserCode(reader); |
215 | - /* 같은 길이의 CVE에서 또 같은 종류의 CVE 레코드 목록 가져옴 | 245 | + foreach (var item in dict) |
216 | - * 같은 종류의 CVE 레코드들이 사용자 코드에서 모두 포함되어야 | ||
217 | - * CVE를 가지고 있다고 인정하는 프로그램 정책 때문 | ||
218 | - */ | ||
219 | - var searchedCveHashList = VulnRDS.SelectVulnbyCve(cve); | ||
220 | - Console.WriteLine($"cve:{cve}, {searchedCveHashList.Count()}개 가져옴"); | ||
221 | - foreach (var s in searchedCveHashList) | ||
222 | { | 246 | { |
223 | - vulnHashSet.Add(s); | 247 | + /* hashDict의 키와 item.key는 함수 블록의 코드 길이 */ |
248 | + if (!hashDict.ContainsKey(item.Key)) | ||
249 | + { | ||
250 | + hashDict[item.Key] = new HashSet<VulnAbstractCrawler.UserBlock>(); | ||
251 | + } | ||
252 | + /* item.Value는 각 코드 길이 마다의 블록 정보 | ||
253 | + * Bloom Filter에 코드 블록 해쉬값 기록 | ||
254 | + */ | ||
255 | + foreach (var hash in item.Value) | ||
256 | + { | ||
257 | + hash.Path = codeFile.FullName; | ||
258 | + hashDict[item.Key].Add(hash); | ||
259 | + filter.Add(hash.Hash); | ||
260 | + } | ||
224 | } | 261 | } |
225 | - | 262 | + count++; |
263 | + double per = ((double)count / (double)totalFileCount) * 100; | ||
264 | + Console.WriteLine($"{count} / {totalFileCount} :: {per.ToString("#0.0")}%, 개체 수 : {hashDict.Count}"); | ||
226 | } | 265 | } |
227 | } | 266 | } |
228 | - } | 267 | + var findBlocks = new Queue<VulnAbstractCrawler.UserBlock>(); |
229 | - var findCveDict = new Dictionary<string, List<VulnAbstractCrawler.UserBlock>>(); | 268 | + var vulnDict = new Dictionary<string, IEnumerable<VulnRDS._Vuln>>(); |
230 | - var findCveList = new HashSet<string>(); | 269 | + foreach (var set in hashDict) |
231 | - /* 본격적인 취약점 매칭 부분 */ | ||
232 | - foreach (var vulnSet in vulnDict) | ||
233 | - { | ||
234 | - //Console.WriteLine($"-----cve:{vulnSet.Key}"); | ||
235 | - bool match = false; | ||
236 | - foreach (var vuln in vulnSet.Value) | ||
237 | { | 270 | { |
238 | - /* 사용자 코드 해쉬 저장해논 bloom filter에 취약점 레코드 해쉬값들이 포함되는지 확인 | 271 | + /* 사용자 코드의 길이 마다 DB로 부터 같은 길이의 CVE 레코드 목록 가져옴 */ |
239 | - * 포함이 된다는 건 해당 취약점 레코드가 사용자 코드에도 있다는 뜻(취약점) | 272 | + var cveList = VulnRDS.SelectVulnbyLen(set.Key).Select(v => v.Cve).Distinct(); |
240 | - * 같은 종류의 CVE 레코드가 전부 필터에 포함된다면 취약점으로 판단한다. | 273 | + foreach (var cve in cveList) |
241 | - */ | ||
242 | - if (filter.Contains(vuln.BlockHash)) | ||
243 | { | 274 | { |
244 | - if (hashDict.ContainsKey(vuln.LenFunc)) | 275 | + if (!vulnDict.ContainsKey(cve)) |
245 | { | 276 | { |
246 | - /* Bloom Filter는 아쉽게도 포함 여부만 알 수 있기에 | 277 | + vulnDict[cve] = new HashSet<VulnRDS._Vuln>(); |
247 | - * 포함되었음을 알았다면 검색해서 정보를 구한다. */ | 278 | + var vulnHashSet = vulnDict[cve] as HashSet<VulnRDS._Vuln>; |
248 | - var userBlock = hashDict[vuln.LenFunc].FirstOrDefault(b => b.Hash == vuln.BlockHash); | 279 | + /* 같은 길이의 CVE에서 또 같은 종류의 CVE 레코드 목록 가져옴 |
249 | - if (userBlock == null) | 280 | + * 같은 종류의 CVE 레코드들이 사용자 코드에서 모두 포함되어야 |
281 | + * CVE를 가지고 있다고 인정하는 프로그램 정책 때문 | ||
282 | + */ | ||
283 | + var searchedCveHashList = VulnRDS.SelectVulnbyCve(cve); | ||
284 | + | ||
285 | + Console.WriteLine($"CVE:{cve}, Received Count : {searchedCveHashList.Count()}"); | ||
286 | + foreach (var s in searchedCveHashList) | ||
250 | { | 287 | { |
251 | - continue; | 288 | + vulnHashSet.Add(s); |
252 | } | 289 | } |
253 | - /* 해당 유저 블록을 임시 저장한다. | 290 | + |
254 | - * 밑에서 블록 정보를 DB로 전송하기 위해서다. | 291 | + } |
255 | - */ | 292 | + } |
256 | - if (!findCveDict.ContainsKey(vuln.Cve)) | 293 | + } |
294 | + var findCveDict = new Dictionary<string, List<VulnAbstractCrawler.UserBlock>>(); | ||
295 | + var findCveList = new HashSet<string>(); | ||
296 | + /* 본격적인 취약점 매칭 부분 */ | ||
297 | + foreach (var vulnSet in vulnDict) | ||
298 | + { | ||
299 | + Console.WriteLine($"-----cve:{vulnSet.Key}"); | ||
300 | + bool match = false; | ||
301 | + foreach (var vuln in vulnSet.Value) | ||
302 | + { | ||
303 | + /* 사용자 코드 해쉬 저장해논 bloom filter에 취약점 레코드 해쉬값들이 포함되는지 확인 | ||
304 | + * 포함이 된다는 건 해당 취약점 레코드가 사용자 코드에도 있다는 뜻(취약점) | ||
305 | + * 같은 종류의 CVE 레코드가 전부 필터에 포함된다면 취약점으로 판단한다. | ||
306 | + */ | ||
307 | + if (filter.Contains(vuln.BlockHash)) | ||
308 | + { | ||
309 | + if (hashDict.ContainsKey(vuln.LenFunc)) | ||
257 | { | 310 | { |
258 | - findCveDict[vuln.Cve] = new List<VulnAbstractCrawler.UserBlock>(); | 311 | + /* Bloom Filter는 아쉽게도 포함 여부만 알 수 있기에 |
312 | + * 포함되었음을 알았다면 검색해서 정보를 구한다. */ | ||
313 | + var userBlock = hashDict[vuln.LenFunc].FirstOrDefault(b => b.Hash == vuln.BlockHash); | ||
314 | + if (userBlock == null) | ||
315 | + { | ||
316 | + continue; | ||
317 | + } | ||
318 | + /* 해당 유저 블록을 임시 저장한다. | ||
319 | + * 밑에서 블록 정보를 DB로 전송하기 위해서다. | ||
320 | + */ | ||
321 | + if (!findCveDict.ContainsKey(vuln.Cve)) | ||
322 | + { | ||
323 | + findCveDict[vuln.Cve] = new List<VulnAbstractCrawler.UserBlock>(); | ||
324 | + } | ||
325 | + userBlock.Url = vuln.Url; | ||
326 | + findCveDict[vuln.Cve].Add(userBlock); | ||
327 | + match = true; | ||
259 | } | 328 | } |
260 | - userBlock.Url = vuln.Url; | 329 | + } |
261 | - findCveDict[vuln.Cve].Add(userBlock); | 330 | + else |
262 | - match = true; | 331 | + { |
332 | + match = false; | ||
333 | + break; | ||
263 | } | 334 | } |
264 | } | 335 | } |
336 | + /* 취약점 레코드가 전부 있어야 CVE 찾음 인정 */ | ||
337 | + if (match) | ||
338 | + { | ||
339 | + Console.WriteLine($"Matched CVE : {vulnSet.Key}"); | ||
340 | + /* 찾았으면 cve값을 기록함 밑에서 찾은 cve 정보 전송하기 위해 */ | ||
341 | + findCveList.Add(vulnSet.Key); | ||
342 | + } | ||
265 | else | 343 | else |
266 | { | 344 | { |
267 | - match = false; | 345 | + Console.WriteLine("Not"); |
268 | - break; | ||
269 | } | 346 | } |
270 | } | 347 | } |
271 | - /* 취약점 레코드가 전부 있어야 CVE 찾음 인정 */ | 348 | + stopwatch.Stop(); |
272 | - if (match) | 349 | + /* 매칭 끝 후처리 (출력, DB 전송 등) */ |
273 | - { | 350 | + var hours = stopwatch.Elapsed.Hours; |
274 | - Console.WriteLine($"CVE 찾음 {vulnSet.Key}"); | 351 | + var minutes = stopwatch.Elapsed.Minutes; |
275 | - /* 찾았으면 cve값을 기록함 밑에서 찾은 cve 정보 전송하기 위해 */ | 352 | + var seconds = stopwatch.Elapsed.Seconds; |
276 | - findCveList.Add(vulnSet.Key); | 353 | + Console.WriteLine($"Elapsed Time : {hours.ToString("00")}:{minutes.ToString("00")}:{seconds.ToString("00")}"); |
277 | - } | 354 | + Console.WriteLine($"Matched CVE Count : {findCveList.Count}"); |
278 | - else | ||
279 | - { | ||
280 | - Console.WriteLine("없음"); | ||
281 | - } | ||
282 | - } | ||
283 | - stopwatch.Stop(); | ||
284 | - /* 매칭 끝 후처리 (출력, DB 전송 등) */ | ||
285 | - var hours = stopwatch.Elapsed.Hours; | ||
286 | - var minutes = stopwatch.Elapsed.Minutes; | ||
287 | - var seconds = stopwatch.Elapsed.Seconds; | ||
288 | - Console.WriteLine($"경과 시간 {hours.ToString("00")}:{minutes.ToString("00")}:{seconds.ToString("00")}"); | ||
289 | - Console.WriteLine($"찾은 CVE 개수 : {findCveList.Count}"); | ||
290 | - var yearMatch = new Regex(@"CVE-(\d{4})-(\d+)"); | ||
291 | - foreach (var cve in findCveList) | ||
292 | - { | ||
293 | - Console.WriteLine(cve); | ||
294 | - var c = yearMatch.Match(cve); | ||
295 | - int year = int.Parse(c.Groups[1].Value); | ||
296 | - if (!CVE_JSON.CveDict.ContainsKey(year)) | ||
297 | - { | ||
298 | - continue; | ||
299 | - } | ||
300 | - if (!CVE_JSON.CveDict[year].ContainsKey(cve)) | ||
301 | - { | ||
302 | - continue; | ||
303 | - } | ||
304 | - var data = CVE_JSON.CveDict[year][cve]; | ||
305 | 355 | ||
306 | - /* 취약점 타입 분류 */ | 356 | + var yearMatch = new Regex(@"CVE-(\d{4})-(\d+)"); |
307 | - string type = "NORMAL"; | 357 | + foreach (var cve in findCveList) |
308 | - if (data.Detail.IndexOf("overflow", StringComparison.CurrentCultureIgnoreCase) > 0) | ||
309 | - { | ||
310 | - type = "OVERFLOW"; | ||
311 | - } | ||
312 | - else if (data.Detail.IndexOf("xss", StringComparison.CurrentCultureIgnoreCase) > 0) | ||
313 | - { | ||
314 | - type = "XSS"; | ||
315 | - } | ||
316 | - else if (data.Detail.IndexOf("injection", StringComparison.CurrentCultureIgnoreCase) > 0) | ||
317 | - { | ||
318 | - type = "SQLINJECTION"; | ||
319 | - } | ||
320 | - else if (data.Detail.IndexOf("dos", StringComparison.CurrentCultureIgnoreCase) > 0) | ||
321 | - { | ||
322 | - type = "DOS"; | ||
323 | - } | ||
324 | - else if (data.Detail.IndexOf("Memory", StringComparison.CurrentCultureIgnoreCase) > 0) | ||
325 | - { | ||
326 | - type = "MEMORY"; | ||
327 | - } | ||
328 | - else if (data.Detail.IndexOf("CSRF", StringComparison.CurrentCultureIgnoreCase) > 0) | ||
329 | - { | ||
330 | - type = "CSRF"; | ||
331 | - } | ||
332 | - else if (data.Detail.IndexOf("inclusion", StringComparison.CurrentCultureIgnoreCase) > 0) | ||
333 | - { | ||
334 | - type = "FILEINCLUSION"; | ||
335 | - } | ||
336 | - else if (data.Detail.IndexOf("EXCUTE", StringComparison.CurrentCultureIgnoreCase) > 0) | ||
337 | { | 358 | { |
338 | - type = "EXCUTE"; | 359 | + Console.WriteLine(cve); |
339 | - } | 360 | + var c = yearMatch.Match(cve); |
340 | - | 361 | + int year = int.Parse(c.Groups[1].Value); |
341 | - var urlBytes = Convert.FromBase64String(findCveDict[cve].FirstOrDefault().Url); | 362 | + if (!CVE_JSON.CveDict.ContainsKey(year)) |
342 | - string url = Encoding.Unicode.GetString(urlBytes); | 363 | + { |
364 | + continue; | ||
365 | + } | ||
366 | + if (!CVE_JSON.CveDict[year].ContainsKey(cve)) | ||
367 | + { | ||
368 | + continue; | ||
369 | + } | ||
370 | + var data = CVE_JSON.CveDict[year][cve]; | ||
343 | 371 | ||
344 | - /* DB 전송 */ | 372 | + /* 취약점 타입 분류 */ |
345 | - VulnRDS.InsertVulnDetail(new VulnRDS.Vuln_detail | 373 | + string type = "NORMAL"; |
346 | - { | 374 | + if (data.Detail.IndexOf("overflow", StringComparison.CurrentCultureIgnoreCase) > 0) |
347 | - CveName = data.Code, | 375 | + { |
348 | - Type = type, | 376 | + type = "OVERFLOW"; |
349 | - Level = data.Level.ToString(), | 377 | + } |
350 | - Year = data.Year.ToString(), | 378 | + else if (data.Detail.IndexOf("xss", StringComparison.CurrentCultureIgnoreCase) > 0) |
351 | - CveDetail = data.Detail, | 379 | + { |
352 | - Publish_date = data.Publish_Date.ToString("yyyy-MM-dd"), | 380 | + type = "XSS"; |
353 | - Update_date = data.Update_Date.ToString("yyyy-MM-dd"), | 381 | + } |
354 | - UserName = "samsung", | 382 | + else if (data.Detail.IndexOf("injection", StringComparison.CurrentCultureIgnoreCase) > 0) |
355 | - Url = url, | 383 | + { |
356 | - FileName = findCveDict[cve].FirstOrDefault().Path.Replace(@"C:\code", ""), | 384 | + type = "SQLINJECTION"; |
357 | - FuncName = findCveDict[cve].FirstOrDefault().FuncName, | 385 | + } |
358 | - Product = data.Type, | 386 | + else if (data.Detail.IndexOf("dos", StringComparison.CurrentCultureIgnoreCase) > 0) |
359 | - }); | 387 | + { |
360 | - Console.WriteLine("추가 완료"); | 388 | + type = "DOS"; |
389 | + } | ||
390 | + else if (data.Detail.IndexOf("Memory", StringComparison.CurrentCultureIgnoreCase) > 0) | ||
391 | + { | ||
392 | + type = "MEMORY"; | ||
393 | + } | ||
394 | + else if (data.Detail.IndexOf("CSRF", StringComparison.CurrentCultureIgnoreCase) > 0) | ||
395 | + { | ||
396 | + type = "CSRF"; | ||
397 | + } | ||
398 | + else if (data.Detail.IndexOf("inclusion", StringComparison.CurrentCultureIgnoreCase) > 0) | ||
399 | + { | ||
400 | + type = "FILEINCLUSION"; | ||
401 | + } | ||
402 | + else if (data.Detail.IndexOf("EXCUTE", StringComparison.CurrentCultureIgnoreCase) > 0) | ||
403 | + { | ||
404 | + type = "EXCUTE"; | ||
405 | + } | ||
406 | + | ||
407 | + var urlBytes = Convert.FromBase64String(findCveDict[cve].FirstOrDefault().Url); | ||
408 | + string url = Encoding.Unicode.GetString(urlBytes); | ||
409 | + var vulnDetail = new VulnRDS.Vuln_detail | ||
410 | + { | ||
411 | + CveName = data.Code, | ||
412 | + Type = type, | ||
413 | + Level = data.Level.ToString(), | ||
414 | + Year = data.Year.ToString(), | ||
415 | + CveDetail = data.Detail, | ||
416 | + Publish_date = data.Publish_Date.ToString("yyyy-MM-dd"), | ||
417 | + Update_date = data.Update_Date.ToString("yyyy-MM-dd"), | ||
418 | + UserName = userId, | ||
419 | + Url = url, | ||
420 | + FileName = findCveDict[cve].FirstOrDefault().Path.Replace(repoPath, ""), | ||
421 | + FuncName = findCveDict[cve].FirstOrDefault().FuncName, | ||
422 | + Product = data.Type, | ||
423 | + }; | ||
424 | + Console.WriteLine("추가 완료"); | ||
425 | + | ||
426 | + | ||
427 | + /* DB 전송 */ | ||
428 | + VulnRDS.InsertVulnDetail(vulnDetail); | ||
429 | + | ||
430 | + Console.WriteLine($"Added CVE: {vulnDetail.CveName}, Type: {vulnDetail.Type}, CVSS: {vulnDetail.Level}"); | ||
431 | + } | ||
361 | } | 432 | } |
362 | } | 433 | } |
363 | } | 434 | } | ... | ... |
1 | <?xml version="1.0" encoding="utf-8"?> | 1 | <?xml version="1.0" encoding="utf-8"?> |
2 | <Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | 2 | <Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
3 | + <Import Project="..\packages\LibGit2Sharp.NativeBinaries.1.0.217\build\net461\LibGit2Sharp.NativeBinaries.props" Condition="Exists('..\packages\LibGit2Sharp.NativeBinaries.1.0.217\build\net461\LibGit2Sharp.NativeBinaries.props')" /> | ||
3 | <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> | 4 | <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> |
4 | <PropertyGroup> | 5 | <PropertyGroup> |
5 | <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> | 6 | <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> |
... | @@ -11,6 +12,8 @@ | ... | @@ -11,6 +12,8 @@ |
11 | <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion> | 12 | <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion> |
12 | <FileAlignment>512</FileAlignment> | 13 | <FileAlignment>512</FileAlignment> |
13 | <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects> | 14 | <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects> |
15 | + <NuGetPackageImportStamp> | ||
16 | + </NuGetPackageImportStamp> | ||
14 | </PropertyGroup> | 17 | </PropertyGroup> |
15 | <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> | 18 | <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> |
16 | <PlatformTarget>AnyCPU</PlatformTarget> | 19 | <PlatformTarget>AnyCPU</PlatformTarget> |
... | @@ -32,6 +35,9 @@ | ... | @@ -32,6 +35,9 @@ |
32 | <WarningLevel>4</WarningLevel> | 35 | <WarningLevel>4</WarningLevel> |
33 | </PropertyGroup> | 36 | </PropertyGroup> |
34 | <ItemGroup> | 37 | <ItemGroup> |
38 | + <Reference Include="LibGit2Sharp, Version=0.25.0.0, Culture=neutral, PublicKeyToken=7cbde695407f0333, processorArchitecture=MSIL"> | ||
39 | + <HintPath>..\packages\LibGit2Sharp.0.25.2\lib\netstandard2.0\LibGit2Sharp.dll</HintPath> | ||
40 | + </Reference> | ||
35 | <Reference Include="MySql.Data, Version=8.0.10.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d, processorArchitecture=MSIL" /> | 41 | <Reference Include="MySql.Data, Version=8.0.10.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d, processorArchitecture=MSIL" /> |
36 | <Reference Include="Newtonsoft.Json, Version=11.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL"> | 42 | <Reference Include="Newtonsoft.Json, Version=11.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL"> |
37 | <HintPath>..\packages\Newtonsoft.Json.11.0.2\lib\net45\Newtonsoft.Json.dll</HintPath> | 43 | <HintPath>..\packages\Newtonsoft.Json.11.0.2\lib\net45\Newtonsoft.Json.dll</HintPath> |
... | @@ -64,4 +70,10 @@ | ... | @@ -64,4 +70,10 @@ |
64 | </ProjectReference> | 70 | </ProjectReference> |
65 | </ItemGroup> | 71 | </ItemGroup> |
66 | <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> | 72 | <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> |
73 | + <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild"> | ||
74 | + <PropertyGroup> | ||
75 | + <ErrorText>이 프로젝트는 이 컴퓨터에 없는 NuGet 패키지를 참조합니다. 해당 패키지를 다운로드하려면 NuGet 패키지 복원을 사용하십시오. 자세한 내용은 http://go.microsoft.com/fwlink/?LinkID=322105를 참조하십시오. 누락된 파일은 {0}입니다.</ErrorText> | ||
76 | + </PropertyGroup> | ||
77 | + <Error Condition="!Exists('..\packages\LibGit2Sharp.NativeBinaries.1.0.217\build\net461\LibGit2Sharp.NativeBinaries.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\LibGit2Sharp.NativeBinaries.1.0.217\build\net461\LibGit2Sharp.NativeBinaries.props'))" /> | ||
78 | + </Target> | ||
67 | </Project> | 79 | </Project> |
... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
1 | <?xml version="1.0" encoding="utf-8"?> | 1 | <?xml version="1.0" encoding="utf-8"?> |
2 | <packages> | 2 | <packages> |
3 | + <package id="LibGit2Sharp" version="0.25.2" targetFramework="net461" /> | ||
4 | + <package id="LibGit2Sharp.NativeBinaries" version="1.0.217" targetFramework="net461" /> | ||
3 | <package id="Newtonsoft.Json" version="11.0.2" targetFramework="net461" /> | 5 | <package id="Newtonsoft.Json" version="11.0.2" targetFramework="net461" /> |
4 | <package id="System.ValueTuple" version="4.5.0" targetFramework="net461" /> | 6 | <package id="System.ValueTuple" version="4.5.0" targetFramework="net461" /> |
5 | </packages> | 7 | </packages> |
... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
-
Please register or login to post a comment