본문 바로가기

프로젝트/악성코드 분석

AI기반의 머신러닝기법을 활용한 악성코드 탐지 방법 - 동적분석

728x90
AI 기반 정보보호 R&D 데이터 챌린지 2018 예선전을 참여하고 작성한 보고서 입니다. 
동적 분석은 실제 대회에서 사용하지 못하였으나, 대회에서 제공하는 테스트셋을 활용하여 연구하였습니다.
git: https://github.com/epicarts/AI_challenge2018

AI기반의 머신러닝기법을 활용한 악성코드 탐지 방법 - 동적분석

최영호

상명대학교(천안) 정보보안공학과

서론

악성파일 내의 API가 호출 순서가 악성코드를 판단하는 중요한 feature가 된다는 연구(참고 1,2)를 보고 분석을 시도하였다. 데이터 전처리 과정으로 Cuckoo SandBox를 사용하여 Dynamic API feature를 추출하였고, 추출한 동적 API 시퀀스를 하나의 문서로 간주하고 단어 임베딩 방법 중 하나인 Doc2Vec를 사용하여 벡터화 시켰다. 벡터화 시킨 모델을 t-sne을 이용해 2차원 나타낸 그림을 통해 연관성을 찾아내었다.

그 결과 API TrainData 파일 1만개 중, 동적 분석을 통해 나온 소프트웨어 2807, 악성코드 6056개로 총 8863개의 Dynamic API feature에 대하여 K-fold로 데이터를 나누고 xgboostbayesian-opimization를 통해 튜닝과 학습을 한 결과 정확도가 92%인 탐지율이 나왔다.

 

. 악성코드 분석 및 특성 추출

2.1. 데이터셋 분석

 

주어진 데이터셋이 32bit 윈도우 환경에서 실행이 가능하다고 하여, PE형태의 파일이라는 생각으로 가장 먼저 정적 분석을 하기 위하여 python 기반의 peframe분석도구를 이용하여 분석을 시도해 보았다. 여기서 PE 파일이란 Portable Executable File의 약자로 실행 가능한 파일을 의미한다.

 

[ 그림 1] peframe 으로 추출한 파일별 패커 종류

 

많은 파일들이 UPXMSLRH, ACProtect 등 다양한 종류의 패커로 패킹되어 있었고, 몇몇 파일들은 정적분석 데이터가 아주 희박하여 feature 추출에 어려움이 있었다. 또한 언패킹 툴 들을 이용하기에는 1만개의 데이터 전부를 적절하게 언패킹하기에는 힘들다고 판단하였다.

 

정적분석은 한계가 있다고 생각해 Cuckoo Sandox라는 플랫폼을 이용해 동적분석을 시도해본 결과 정적분석에 비해 상대적으로 feature로 활용할 데이터를 쉽게 추출할 수 있고, Cuckoo web을 통해 네트워크, 동적분석, 정적분석, 요약 등 분석 정보들을 쉽게 접근하고 확인 할 수 있다.

[ 그림 2] Cuckoo SandBox 로 분석된 데이터 (Cuckoo web  화면 )

 

2.2. 정상/악성코드 탐지(판단) 결과

 

Doc2vec를 활용하면 문서의 유사도를 벡터로 나타내는데 수 있다. 여기서는 Cuckoo SandBox에서 추출한 API 호출 순서를 하나의 문서로 생각하였고, 제공된 악성코드와 소프트웨어 전부를 학습시켰다.

 

t-sne를 통해 나타낸 악성코드와 소프트웨어 

doc2vec 옵션
vector_size=100, alpha=0.025, min_alpha=0.025, min_count=20, window = 15, dm =1

악성코드와 정상파일을 학습시킨 뒤 t-sne를 통해 2차원으로 차원 압축을 시켜 데이터를 시각화 해보았다. 소프트웨어 2807, 악성코드 6056개의 도트로 표현되어있다.

 

그림과 같이 일부 섞여 있긴 하지만 파랑색 도트(소프트웨어), 빨강색 도트(악성코드)가 소,대규모로 군집를 이루고 있음을 볼 수 있다. 이를 통해 동적 API 시퀀스를 악성행위와 일반 파일을 구분하는 feature로 충분히 사용 할 수 있을거라 판단하였다.

 

 

2.3. 특성 추출

 

Cuckoo Sandbox에서 분석되는 파일들은 storage라는 폴더에 저장이 되는데, 각파일 마다 report.json이라는 파일이 존재한다. 이 파일 내부에는 파일 이름부터 시작하여 md5, sha256, processtree, static 정보 등 정리된 데이터들이 json 형태로 저장되어 있다. 이 중 process 항목의 API Call 부분을 추출하여 API 호출 순서대로 하나의 문서(Doc)으로 보고 csv 파일형태로 저장하였다.

 

 

2.4. 특성 분류결과

 

모든 파일의 api 호출을 가져오고 싶었으나 동적 분석에 실패한 파일들은 동적 API 시퀀스를 추출하지 못하였다. 1만개의 파일 중에서 소프트웨어 2807, 악성코드 6056개의 API 시퀀스를 추출하였으며, 여기서 탐지된 API의 종류는 총 274개가 발견되었고, 그 중 공통적으로 많이 나타난 API는 다음 표[1]와같았다.

 

[표 1] API 상위 10

. 탐지 알고리즘 구성

3.1. SandBox 분석

가장 먼저 SandBox를 이용하여 파일들의 동적 API 시퀀스를 추출을 한다. 빠른 추출을 위해 cuckoo 옵션인 --timeout 30(최대 30)을 주고 분석을 하며, 여기서 추출된 report.json 파일에 MD5 값을 추출하여 MD5.json 형태로 저장한다.

 

3.2. Doc2vec 모델 생성

Doc2vec 모델은 문서를 벡터화 시킬 때 사용한다. 여기서는 동적 API 시퀀스를 일종의 문서로 생각하고 Doc2vec 모델의 파라미터 값을 다르게 시도하며 학습시켰다.

 

3.4. Xgboost 학습 전 학습데이터 전처리

생성한 Doc2vec 모델을 토대로 기존의 추출된 API 시퀀스를 벡터로 변경시켰다.

각각 벡터화한 데이터에 악성코드인지, 소프트웨어인지 0,1을 사용하여 라벨링하였다.

 

3.4. bayesian-opimization를 활용한 튜닝

BayesianOptimization을 활용하여 xgboost의 튜닝값을 조절 하였다.

 

Xgboost 를 튜닝 위한 파라미터

    params = {
        "objective": "reg:linear",
        "booster" : "gbtree",
        "eval_metric": "mae",
        "tree_method": 'auto',
        "silent": 1,
        "eta": eta,
        "max_depth": int(maxDepth),
        "min_child_weight" : minChildWeight,
        "subsample": subsample,
        "colsample_bytree": colSample,
        "gamma": gamma,
        "scale_pos_weight": 0.48#데이터 셋 비율  0/1 소프트웨어 / 악성코드
        }#적용할 파라미터들

 

BayesianOptimization를 위한 파라미터

ranges = {
    'numRounds': (1000, 2000),
    'eta': (0.03, 0.1),
    'gamma': (0, 10),
    'maxDepth': (4, 10),
    'minChildWeight': (0, 10),
    'subsample': (0, 1),
    'colSample': (0, 1),
}#학습에 따라 변경될 값들. 설정

 

[소스코드 출처]
http://codingwiththomas.blogspot.com/2016/10/xgboost-bayesian-hyperparameter-tuning.html

다음 소스를 일부 수정하여, 적용하였다. 

 

 

. 실험

 

4.4. 실험 환경

 

분석을 위해 사용한 가상머신은 ubuntu 16.04LTS 버전을 사용하였고, 정적 분석 ubuntu 16.04LTS 을 위해 PEframe 5.0.1python 2.7.3을 이용해 추출하였다.

동적 분석으로는 위와 같은 ubuntu 16.04LTS 사용 하였고, 201810월 기준 최신 버전인 Cuckoo Sandbox 2.0.6을 설치하였다. Cuckoo Sandbox에 분석을 위해 사용한 가상머신은 WindowsXP SP2을 사용 하였으며 방화벽 및 보안 옵션은 최하로 설정하였다. 빠른 분석을 위해 cuckoo 옵션인 --timeout 30(최대 30)을 주었고, 같은 환경의 가상머신 3대를 동시에 가동하였다.

Doc2vec분석은 윈도우10에서 진행하였으며, python3.6.5gensim 3.6.0 패키지를 사용하여 실험하였다.

학습을 위한 xgboost 0.80 를 사용하였고, xgboost를 사용하여 최적의 튜닝 값을 계산을 위해 bayesian-opimization 0.6 를 사용하였다.

 

 

. 평가

테스트를 위해 Doc2vectsene로 변경했을 때 어느정도 악성코드와 소프트웨어가 구분이된다고 생각하는 모델을 하나 선정하여 평가하였다.

평가에 사용한 Doc2vec를 T-SNE를 활용하여 시각화

mincount = 0, window = 10 ,vector_size = 50

평가에 사용된 모델을 T-SNE로 나타낸 것으로 학습시킨 파라미터 값은 다음과 같다.

 

 

92%의 정확도가 나온 Xgboost 파라미터

0.16985
numRounds: 1980
	{'eta': 0.04268380464143151, 
     'max_depth': 9, 
     'subsample': 0.27562492851302745, 
     'objective': 'reg:linear', 
     'silent': 1, 
     'min_child_weight': 7, 
     'gamma': 0.3429412218176964, 
     'booster': 'gbtree', 
     'eval_metric': 'mae', 
     'tree_method': 'auto', 
     'scale_pos_weight': 0.48
     }
dtrain = xgb.DMatrix(train_data, label=train_labels)#k-fold로 나눈 데이터
#max_params = 최적의 파라미터
booster = xgb.train(max_params, dtrain, num_boost_round=1980)

dtest = xgb.DMatrix(test_data)
y_pred = booster.predict(dtest)
y_pred  = y_pred > 0.5
y_pred = y_pred.astype(int)
accuracy = accuracy_score(y_pred, test_labels)
print("Accuracy: %.2f%%" % (accuracy * 100.0))#예측률

K-fold로 데이터를 약 8:2의 비율로 나눈 뒤 평가하였다. (학습데이터: 7091개, 테스트데이터: 1772개)

 

최적화된 학습 파라미터를 이용하여 xgboost를 학습 시킨 후 예측을 하였을 때 약 92%의 정확도가 나왔다.

 

. 결론

1만개의 악성코드 중에서 비록 8863개의 파일만 추출하여 사용하였지만, 위 실험에서 쿠쿠샌드박스에서 사용된 XP sp2 뿐만 아니라 다양한 분석 환경을 만들면 더 많은 파일들을 동적 분석 할 수 있지 않을까 생각한다.

또한 timeout을 옵션으로 30 주어 시간단축을 위해 노력하였으나 동적 분석이기 때문에 악성코드 분석에 오랜시간이 걸렸는데 별도 분산 컴퓨팅환경을 만들어 분석속도를 향상시켜야 한다고 생각한다.

[참고문헌]
[1] 임태원, "실행파일 이미지화와 Word2Vec 을 이용한 딥러닝 기반 악성코드 탐지방법에 대한 연구," (학위논문(석사), 성균관대학교 정보통신대학원 : 정보보호학과 2017. 8 , n.d.), 1-55.
[2] 한경수, 김인경, 임을규, "API 순차적 특징을 이용한 악성코드 변종 분류 기법," (석사, 한양대학교 전자컴퓨터통신공학과, 2011), 133-791.

 

728x90