발자취

악성코드 탐지 시스템 04 - 암호화와 복호화 본문

3-2/악성코드

악성코드 탐지 시스템 04 - 암호화와 복호화

해린 2024. 1. 18. 07:43

 

악성코드 탐지시스템의 구조를 알아보는 실습, 그 마지막 시간이다.

본 실습은 '파이썬으로 배우는 Anti-Virus 구조와 원리' 교재의 4~7, 12장에 해당하는 실습이며, 본 게시물에서는 12장의 내용을 다룬다.

앞선 실습의 탐지 시스템의 문제점을 개선한 구조의 탐지 시스템을 확인할 수 있다.

 

이전 실습 게시글:

https://haelyn.tistory.com/127

https://haelyn.tistory.com/128

https://haelyn.tistory.com/129

 

 


4. 네번째 실습

실습에 필요한 코드는 다음과 같다.

 

# -*- coding:utf-8 -*-
# Author: Kei Choi(hanul93@gmail.com)



import sys
import k2rsa

if __name__ == '__main__':
    pu_fname = 'key.pkr'
    pr_fname = 'key.skr'

    if len(sys.argv) == 3:
        pu_fname = sys.argv[1]
        pr_fname = sys.argv[2]

    elif len(sys.argv) != 1:
        print 'Usage: mkkey.py [[PU filename] [PR filename]]'
        exit(0)

    k2rsa.create_key(pu_fname, pr_fname, True)

mkkey.py

 

# -*- coding:utf-8 -*-
# Author: Kei Choi(hanul93@gmail.com)

# 침임탑지와차단시스템 과목 교재의 eicar.py 프로그램을 수정하여 
# fakeVirus_md5.py를 제작함
# FakeVirus_MD5에 대한 플러그인 엔진

import os
import hashlib

class KavMain:


    def init(self, plugins_path):
        return 0


    def uninit(self):
        return 0

    
    def scan(self, filehandle, filename):
        try:
            
            mm = filehandle

            size = os.path.getsize(filename)
            if size == 17:
                m = hashlib.md5()
                m.update(mm[:17])
                fmd5 = m.hexdigest()
                
                # 탐지되면 True 결과와 
                # 바이러스 이름(FakeVirus_MD5)
                # 바이러스 치료를 위한 악성코드 ID 반환
                # 악성코드 ID가 0이면 파일 삭제하여 악성코드 치료
                if fmd5 == 'a56ca3d75f1bb7179292c2c8ebd2ca94':
                    return True, 'FakeVirus_MD5', 0

        except IOError:
            pass

        # 악성코드 탐지 안되면 False 결과와
        # 악성코드 ID -1 반환
        return False, '', -1


    def disinfect(self, filename, malware_id):
        try:
            if malware_id == 0:
                os.remove(filename)
                return True

        except IOError:
            pass

       
        return False


    def listvirus(self):
        vlist = list()

        vlist.append('FakeVirus_MD5')

        return vlist


    def getinfo(self):
        info = dict()

        info['author'] = 'anonymous'
        info['version'] = '1'
        info['title'] = 'FakeVirus_MD5'
        info['kmd_name'] = 'fakeVirus_md5'

        return info

fakeVirus_md5.py

 

# -*- coding:utf-8 -*-
# Author: Kei Choi(hanul93@gmail.com)

# 침임탑지와차단시스템 과목 교재의 dummy.py 프로그램을 수정하여 
# fakeVirus_str.py를 제작함
# FakeVirus_Str에 대한 플러그인 엔진

import os

class KavMain:


    def init(self, plugins_path):
        self.virus_name = 'FakeVirus_Str'
        self.virus_pattern = 'signature FV9321568'

        return 0


    def uninit(self):
        del self.virus_name
        del self.virus_pattern

        return 0

    
    def scan(self, filehandle, filename):
        try:
            fp = open(filename)
            buf = fp.read(len(self.virus_pattern))
            fp.close()

            if buf == self.virus_pattern:
                return True, self.virus_name, 0

        except IOError:
            pass

      
        return False, '', -1


    def disinfect(self, filename, malware_id):
        try:
            if malware_id == 0:
                os.remove(filename)
                return True

        except IOError:
            pass

    
        return False


    def listvirus(self):
        vlist = list()

        vlist.append(self.virus_name)

        return vlist


    def getinfo(self):
        info = dict()

        info['author'] = 'anonymous'
        info['version'] = '1'
        info['title'] = 'FakeVirus_Str'
        info['kmd_name'] = 'fakeVirus_str'

        return info

fakeVirus_str.py

 

fakeVirus_str.kmd
fakeVirus_md5.kmd

kicom.lst

 

# -*- coding:utf-8 -*-
# Author: Kei Choi(hanul93@gmail.com)

# 침임탑지와차단시스템 과목을 위해서 
# 교재의 engine_test.py 프로그램을 수정함 


import k2engine

# listvirus의 콜백 함수
def listvirus_callback(plugin_name, vnames):
   for vname in vnames:
     print '%-50s [%s.kmd]' % (vname, plugin_name)

k2 = k2engine.Engine(debug=True)
if k2.set_plugins('.'): #플러그인 엔진 경로: 현재 디렉토리
   kav = k2.create_instance()
   if kav:
       print '[*] Success : create_instance'

       ret = kav.init()
       info = kav.getinfo()

       vlist = kav.listvirus(listvirus_callback)

       print '[*] Used Callback    : %d' % len(vlist)

       vlist = kav.listvirus()
       print '[*] Not Used Callback    : %d' % len(vlist)

       ret, vname, mid, eid = kav.scan('fakeVirus_str.txt')
       if ret:
           kav.disinfect('fakeVirus_str.txt', mid, eid) 

       ret, vname, mid, eid = kav.scan('fakeVirus_md5.txt')
       if ret:
           kav.disinfect('fakeVirus_md5.txt', mid, eid)

       kav.uninit()

engine_test.py

 

그리고 앞 실습에서 사용했던 kmake.py가 필요하다

 

1. 실습 절차

1. ~/Desktop/AVCodes/Ch12 폴더로 이동한 후, 다음의 명령어를 수행해 암호화, 복호화에 사용하는 키 파일들을 생성한다.

python .\mkkey.py

→ 키 파일 key.pkr, key.skr이 생성되었다.

 

 

2. ~/Desktop/AVCodes/Ch12 폴더로 이동한 후, 다음의 명령어를 수행해 fakeVirus_md5.py을 암호화한다.

python .\kmake.py fakeVirus_md5.py

→ fakeVirus_md5.kmd 모듈이 생성되었다.

 

 

3. ~/Desktop/AVCodes/Ch12 폴더로 이동한 후, 다음의 명령어를 수행해 fakeVirus_str.py을 암호화한다.

python .\kmake.py fakeVirus_str.py

→ fakeVirus_str.kmd 모듈이 생성되었다.

 

 

4. ~/Desktop/AVCodes/Ch12 폴더로 이동한 후, 다음의 명령어를 수행해 kicom.lst 파일을 암호화한다.

python .\kmake.py kicom.lst

→ kicom.kmd 모듈이 생성되었다.

 

 

5. ~/Desktop/AVCodes/Ch12 폴더로 이동한 후, 다음의 명령어를 수행해 백신 커널인 k2engine.py를 테스트한다.

python .\engine_test.py

 

 

2. 파일 설명

코드의 구체적인 설명은 하지 않을 것이고, 파일의 역할만 설명할 것이다.

 

- mkkey.py

RSA 방식을 사용해서 키를 생성해줌

 

- kmake.py

스트링 관련 모듈들을 암호화해줌

 

- engine_test.py

해시값과 문자열로 된 해시값들을 탐지하는 기능. 문자열과 해시값 관련된 정보들이 들어가 있음.

 

- k2engine.py

엔진 클래스, 엔진 인스턴스 클래스 등이 있다. 개발적으로 하던걸 엔진 형태로 만들어서 일반화시키고 확장성있게 처리할 수 있게 해서 효율적이게 만들었다.

 

 

3. 생각해보기

1. callback 함수의 정의는 무엇인가?

동작하다가 특정 이벤트가 발생했을 때 그걸 처리해달라고 요청하는 함수이다.

 

 

2. 암호화를 하는 이유?

의로운 파일이 암호화 되어 있지 않고 노출되어 있으면 공격자가 어떻게 동작하는지를 파악할 수 있기 때문에 그걸 회피하여 악성코드를 제작할 수 있을 것이다. 그렇기 때문에 암호화는 기본이다.

사이즈도 줄이고, 내용도 드러나지 않게 해줘야 한다!

 

 


이렇게 네 번의 실습이 마무리되었다. 

네 번의 실습을 통해 악성코드 탐지 시스템은

1. DB가 별도의 파일로 분리되어 있고

2. 시그니처를 해시값과 문자열 두 형태로 가지도록 하며

3. 암호화를 해줘야 한다.

는 것을 알 수 있었다.

 

탐지 시스템의 동작 원리 및 구조에 대해 자세히 알 수 있었던 뜻깊은 시간이었다.

오늘 얻은 이 지식들이 앞으로 악성코드 분석을 하면서도 도움이 많이 될 것 같아 행복하다!