노현종

VulnRDS VulnDB 자동 Insert

......@@ -25,7 +25,7 @@ namespace VulnCrawler
public static Account account { get; private set; }
static AWS() {
// account = LoadAccount();
account = new Account();
}
private static Account LoadAccount() {
if (!File.Exists(Account.FilePath)) {
......
......@@ -22,17 +22,37 @@ namespace VulnCrawler
//SecureString s_key = GetConsoleSecurePassword();
//Console.Clear();
//string key = SecureStringToString(s_key);
////AWS.SaveAccount();
//AWS.account.Id = "yhackerbv";
//AWS.account.Pw = "guswhd12";
//AWS.account.Endpoint = "vulndb.cby38wfppa7l.us-east-2.rds.amazonaws.com";
//AWS.SaveAccount();
//AES aes = new AES();
//string txt = File.ReadAllText(@"Account.xml");
//string xml = aes.AESDecrypt128(txt, key);
string txt = File.ReadAllText(@"Account.xml");
// string xml = aes.AESDecrypt128(txt, key);
string xml = txt;
//AWS.LoadAccount(xml);
AWS.LoadAccount(xml);
AWS.Account account = AWS.account;
//AWS.Account account = AWS.account;
//Console.WriteLine($"Endpoint: {account.Endpoint}, ID: {account.Id}, PW: {account.Pw}");
Console.WriteLine($"Endpoint: {account.Endpoint}, ID: {account.Id}, PW: {account.Pw}");
try
{
VulnRDS.Connect(account, "vuln");
}
catch(Exception e)
{
Console.WriteLine($"접속 에러 :: {e.ToString()}");
}
if (VulnRDS.Conn.State == System.Data.ConnectionState.Open)
{
Console.WriteLine("접속 성공");
}
else
{
Console.WriteLine("연결 실패");
return;
}
//MySqlConnectionStringBuilder builder = new MySqlConnectionStringBuilder {
// Server = "",
// UserID = id,
......@@ -69,12 +89,7 @@ namespace VulnCrawler
Regex.CacheSize = 50;
// var fields = VulnWorker.GetCriticalVariant(@"return _is_safe_url(url, host) and _is_safe_url(url.replace('\\', '/'), host)");
var c = new VulnC();
var fields = c.ExtractCriticalVariant(@"if (s->session->peer != s->session->sess_cert->peer_key->x509)");
foreach (var item in fields)
{
Console.WriteLine(item);
}
// return;
var directorys = Directory.GetDirectories(@"c:\VulnC");
if (directorys.Length == 0) {
......@@ -84,10 +99,11 @@ namespace VulnCrawler
// Repository 목록 만큼 반복함.
foreach (var directory in directorys) {
// 템플릿 패턴화 T : VulnAbstractCrawler
if (directory.Contains("linux"))
if (directory.Contains("open"))
{
continue;
}
Console.WriteLine(directory);
VulnWorker.Run<VulnC>(directory);
}
}
......
......@@ -77,9 +77,12 @@ namespace VulnCrawler
public void Init(string path) {
Console.WriteLine("로딩중");
Console.WriteLine(path);
Repository = new Repository(path);
Console.WriteLine("로딩 완료");
Commits = SearchCommits();
Console.WriteLine($"Commits Count: {Commits.Count()}");
}
/// <summary>
/// 레파지토리
......@@ -227,7 +230,7 @@ namespace VulnCrawler
/// <param name="oldBlob">패치 전 파일 Blob</param>
/// <param name="table">크리티컬 메서드 테이블(Key: 메서드 이름, Value: 변수 리스트)</param>
/// <returns></returns>
public virtual IEnumerable<(string methodName, IList<Block> blocks)> Process(Blob oldBlob, IDictionary<string, IEnumerable<string>> table) {
public virtual IEnumerable<(string methodName, string oriFunc, IList<Block> blocks)> Process(Blob oldBlob, IDictionary<string, IEnumerable<string>> table) {
foreach (var item in table)
{
var methodTable = new Dictionary<string, string>();
......@@ -238,7 +241,7 @@ namespace VulnCrawler
Stream oldStream = oldBlob.GetContentStream();
// 패치 전 원본 함수 구하고
string func = GetOriginalFunc(oldStream, methodName);
Console.WriteLine(func);
string bs = string.Empty;
string md5 = string.Empty;
if (item.Value.Count() != 0)
......@@ -261,24 +264,17 @@ namespace VulnCrawler
{
block.CriticalList = item.Value;
/* 추상화 및 정규화 */
block.AbsCode = Abstract(block.Code, varTable, methodTable);
block.Hash = MD5HashFunc(block.AbsCode);
}
/* 추상화 및 정규화 */
foreach (var block in blocks)
{
string code = block.Code;
}
/* 추상화 변환 테이블 출력 */
foreach (var var in varTable)
{
Console.WriteLine($"{var.Key}, {var.Value}");
}
yield return (methodName, blocks);
yield return (methodName, func, blocks);
}
}
......
......@@ -60,6 +60,7 @@
<Compile Include="VulnAbstractCrawler.cs" />
<Compile Include="VulnC.cs" />
<Compile Include="VulnPython.cs" />
<Compile Include="VulnRDS.cs" />
<Compile Include="VulnWorker.cs" />
</ItemGroup>
<ItemGroup>
......
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MySql.Data.MySqlClient;
namespace VulnCrawler
{
public static class VulnRDS
{
public static MySqlConnection Conn { get; set; }
public class Vuln
{
public int VulnId { get; set; } = -1; /* 취약점 ID */
public int LenBlock { get; set; } = -1; /* 취약점 BLOCK 길이 */
public string RepositName { get; set; } = "NULL"; /* 취약점 레파지토리 이름 */
public string Cve { get; set; } = "NULL"; /* 취약점 CVE */
public string FuncName { get; set; } = "NULL"; /* 취약점 함수 이름 */
public string Language { get; set; } = "NULL"; /* 취약점 언어 종류 */
public string CodeOriBefore { get; set; } = "NULL"; /* 취약점 패치 전 원본 코드 */
public string CodeOriAfter { get; set; } = "NULL"; /* 취약점 패치 후 원본 코드 */
public string CodeAbsBefore { get; set; } = "NULL"; /* 취약점 패치 전 추상화 코드 */
public string CodeAbsAfter { get; set; } = "NULL"; /* 취약점 패치 후 추상화 코드 */
public string BlockHash { get; set; } = "NULL";/* 취약점 블록 해시 값 */
public int BlockNum { get; set; } = -1; /* 블록 번호 */
// 생성자
public Vuln()
{
}
public Vuln(int _lenBlock, string _repositName, string _cve, string _funcName, string _language, string _codeOriBefore, string _codeOriAfter, string _codeAbsBefore, string _codeAbsAfter, string _blockHash)
{
//임의의 VulnId
VulnId = -1;
LenBlock = _lenBlock;
RepositName = _repositName;
Cve = _cve;
FuncName = _funcName;
Language = _language;
CodeOriBefore = _codeOriBefore;
CodeOriAfter = _codeOriAfter;
CodeAbsBefore = _codeAbsBefore;
CodeAbsAfter = _codeAbsAfter;
BlockHash = _blockHash;
}
public Vuln(int _vulnId, int _lenBlock, string _repositName, string _cve, string _funcName, string _language, string _codeOriBefore, string _codeOriAfter, string _codeAbsBefore, string _codeAbsAfter, string _blockHash)
{
VulnId = _vulnId;
LenBlock = _lenBlock;
RepositName = _repositName;
Cve = _cve;
FuncName = _funcName;
Language = _language;
CodeOriBefore = _codeOriBefore;
CodeOriAfter = _codeOriAfter;
CodeAbsBefore = _codeAbsBefore;
CodeAbsAfter = _codeAbsAfter;
BlockHash = _blockHash;
}
}
public class User
{
public int UserId { get; set; } /* 유저 ID */
public string RepositName { get; set; } /* 유저 레파지토리 이름 */
public string Cve { get; set; } /* 취약점 CVE */
public string CodeOriBefore { get; set; } /* 취약점 패치 전 원본 코드 */
public string CodeOriAfter { get; set; } /* 취약점 패치 후 원본 코드 */
public string FuncName { get; set; } /* 취약점 함수 이름 */
public string DetectDate { get; set; } /* 검사 날짜 */
// 생성자
public User()
{
}
public User(int _UserId, string _RepositName, string _Cve, string _CodeOriBefore, string _CodeOriAfter, string _FuncName, string _DetectDate)
{
UserId = _UserId;
RepositName = _RepositName;
Cve = _Cve;
CodeOriBefore = _CodeOriBefore;
CodeOriAfter = _CodeOriAfter;
FuncName = _FuncName;
DetectDate = _DetectDate;
}
}
//connect
public static void Connect(AWS.Account account, string dbName)
{
MySqlConnectionStringBuilder builder = new MySqlConnectionStringBuilder()
{
Server = account.Endpoint,
UserID = account.Id,
Password = account.Pw,
Database = dbName,
Port = 3306,
};
string strConn = builder.ToString();
builder = null;
Conn = new MySqlConnection(strConn);
Conn.Open();
}
public static void InsertVulnData(Vuln vuln)
{
// Conn.Open();
//DB에 취약점 데이터가 이미 있는지 검사
String sql = string.Empty;
//String sql = "select count(*) from vulnInfo where cve like '" + vuln.Cve + "'";
//MySqlCommand cmd = new MySqlCommand(sql, Conn);
//int RecordCount = Convert.ToInt32(cmd.ExecuteScalar());
////CVE 중복인 경우
//if (RecordCount > 0)
//{
// Console.WriteLine("이미 cve가 존재함");
//}
//CVE 중복이 아닌 경우
//else
//{
// vulnId setting (마지막 vulnId +1)
MySqlCommand cmd = null;
int last_vulnId = 1;
try
{
sql = "select max(vulnId) from vulnInfo";
cmd = new MySqlCommand(sql, Conn);
last_vulnId = (Convert.ToInt32(cmd.ExecuteScalar())) + 1;
}
catch(Exception)
{
last_vulnId = 1;
}
//DB insert
try
{
sql = "INSERT INTO vulnInfo(vulnId, lenBlock, repositName, cve, funcName, numBlock, codeOriBefore, codeOriAfter, codeAbsBefore, codeAbsAfter, blockHash) " +
$"VALUES({last_vulnId}, {vuln.LenBlock}, '{vuln.RepositName}', '{vuln.Cve}', '{vuln.FuncName}', {vuln.BlockNum}, '{vuln.CodeOriBefore}', '{vuln.CodeOriAfter}', '{vuln.CodeAbsBefore}', '{vuln.CodeAbsAfter}', '{vuln.BlockHash}')";
//sql = "INSERT INTO vulnInfo (vulnId, lenBlock, repositName, cve, funcName, codeOriBefore, codeOriAfter, codeAbsBefore, codeAbsAfter, blockHash) " +
// "VALUES(" + last_vulnId + ", " + vuln.LenBlock + ", " + vuln.RepositName + ", " + vuln.Cve + ", " + vuln.FuncName + ", " + vuln.CodeOriBefore + ", " + vuln.CodeOriAfter + ", " + vuln.CodeAbsBefore + ", " + vuln.CodeAbsAfter + ", '" + vuln.BlockHash + "')";
Console.WriteLine(sql);
cmd = new MySqlCommand(sql, Conn);
cmd.ExecuteNonQuery();
//Conn.Close();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
Console.ReadLine();
}
// }
}
public static void InsertUserData(User user)
{
Conn.Open();
//DB에 취약점 데이터가 이미 있는지 검사
String sql = "select count(*) from vulnInfo where cve like '" + user.Cve + "'";
MySqlCommand cmd = new MySqlCommand(sql, Conn);
int RecordCount = Convert.ToInt32(cmd.ExecuteScalar());
//CVE 중복인 경우
if (RecordCount > 0)
{
Console.WriteLine("이미 cve가 존재함");
}
//CVE 중복이 아닌 경우
else
{
//DB insert
try
{
sql = "INSERT INTO userInfo (userId, repositName, cve,codeOriBefore,codeOriAfter,funcName,detectDate) " +
"VALUES(" + user.UserId + "," + user.RepositName + "," + user.Cve + "," + user.CodeOriBefore + "," + user.CodeOriAfter + "," + user.FuncName + "," + user.DetectDate + ")";
cmd = new MySqlCommand(sql, Conn);
cmd.ExecuteNonQuery();
Conn.Close();
}
catch (Exception e)
{
Console.WriteLine(e.StackTrace);
}
}
}
public static Vuln SearchVulnCve(string _cve)
{
Vuln vuln = new Vuln();
Conn.Open();
//특정 cve 가 있는지 검사
String sql = "select * from vulnInfo where cve like '" + _cve + "'";
MySqlCommand cmd = new MySqlCommand(sql, Conn);
MySqlDataReader rdr = cmd.ExecuteReader();
while (rdr.Read())
{
vuln.VulnId = Convert.ToInt32(rdr["vulnId"]);
vuln.LenBlock = Convert.ToInt32(rdr["lenBlock"]);
vuln.RepositName = Convert.ToString(rdr["repositName"]);
vuln.Cve = Convert.ToString(rdr["cve"]);
vuln.FuncName = Convert.ToString(rdr["funcName"]);
vuln.Language = Convert.ToString(rdr["language"]);
vuln.CodeOriBefore = Convert.ToString(rdr["codeOriBefore"]);
vuln.CodeOriAfter = Convert.ToString(rdr["codeOriAfter"]);
vuln.CodeAbsBefore = Convert.ToString(rdr["codeAbsBefore"]); ;
vuln.CodeAbsAfter = Convert.ToString(rdr["codeAbsAfter"]);
vuln.BlockHash = Convert.ToString(rdr["blockHash"]);
}
Conn.Close();
return vuln;
}
public static int ReturnUserLastId()
{
Conn.Open();
String sql = "select max(userId) from userInfo";
MySqlCommand cmd = new MySqlCommand(sql, Conn);
int last_userId = (Convert.ToInt32(cmd.ExecuteScalar())) + 1;
Conn.Close();
return last_userId;
}
//public static IEnumerable<string> SearchVulnData(int _len)
//{
//
//}
}
}
\ No newline at end of file
......@@ -2,6 +2,7 @@
using LibGit2Sharp;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
......@@ -17,7 +18,6 @@ namespace VulnCrawler
var crawler = new T();
crawler.Init(dirPath);
var commits = crawler.Commits;
Console.WriteLine(commits.Count());
foreach (var commit in commits) {
// 커밋 메시지
string message = commit.Message;
......@@ -31,16 +31,19 @@ namespace VulnCrawler
// 패치 엔트리 파일 배열 중에 파일 확장자가 .py인 것만 가져옴
// (실질적인 코드 변경 커밋만 보기 위해서)
var entrys = crawler.GetPatchEntryChanges(patch);
var dsp = dirPath.Split(Path.DirectorySeparatorChar);
string repoName = dsp[dsp.Length - 1];
// 현재 커밋에 대한 패치 엔트리 배열을 출력함
PrintPatchEntrys(entrys, crawler, message, cve);
PrintPatchEntrys(entrys, crawler, message, cve, repoName);
}
Console.ReadLine();
// Console.ReadLine();
}
}
private static void PrintPatchEntrys(IEnumerable<PatchEntryChanges> entrys, VulnAbstractCrawler self, string commitMsg, string cve) {
private static void PrintPatchEntrys(IEnumerable<PatchEntryChanges> entrys, VulnAbstractCrawler self, string commitMsg, string cve, string repoName) {
foreach (var entry in entrys) {
// 기존 소스코드
var oldOid = entry.OldOid;
......@@ -60,6 +63,11 @@ namespace VulnCrawler
// 출력
if (regs.Count > 0)
{
int deleted = entry.LinesDeleted;
if (deleted == 0)
{
continue;
}
Console.BackgroundColor = ConsoleColor.DarkBlue;
Console.WriteLine($"Old Content: \n{oldContent}");
Console.ResetColor();
......@@ -89,19 +97,12 @@ namespace VulnCrawler
var table = self.ExtractGitCriticalMethodTable(entry.Patch);
foreach (var tuple in self.Process(oldBlob, table))
{
(var methodName, var blocks) = tuple;
(var methodName, var oriFunc, var blocks) = tuple;
Console.BackgroundColor = ConsoleColor.DarkRed;
Console.WriteLine($"메서드 이름 : {methodName}");
Console.ResetColor();
//Console.ForegroundColor = ConsoleColor.Blue;
//foreach (var c in )
//{
// Console.WriteLine(c);
//}
//Console.ResetColor();
foreach (var block in blocks)
{
if (block.HasCritical)
{
Console.BackgroundColor = ConsoleColor.DarkMagenta;
......@@ -115,6 +116,37 @@ namespace VulnCrawler
Console.ResetColor();
Console.WriteLine($"AbsCode = \n{block.AbsCode}");
Console.WriteLine($"MD5 = {block.Hash}");
if (!block.HasCritical)
{
// Console.WriteLine("크리티컬 아님");
continue;
}
byte[] funcNameBytes = Encoding.Unicode.GetBytes(methodName);
byte[] codeOriBeforeBytes = Encoding.Unicode.GetBytes(oriFunc);
byte[] codeAbsBeforeBytes = Encoding.Unicode.GetBytes(block.AbsCode);
VulnRDS.Vuln vuln = new VulnRDS.Vuln()
{
Cve = cve,
Language = "C",
BlockHash = block.Hash,
LenBlock = block.Code.Length,
FuncName = Convert.ToBase64String(funcNameBytes),
RepositName = repoName,
CodeOriBefore = Convert.ToBase64String(codeOriBeforeBytes),
CodeAbsBefore = Convert.ToBase64String(codeAbsBeforeBytes),
BlockNum = block.Num,
};
// Console.WriteLine("추가중...");
VulnRDS.InsertVulnData(vuln);
// Console.WriteLine($"추가: {vuln.Cve}, {vuln.FuncName}, {vuln.RepositName}");
// Console.ReadLine();
}
}
......