Extracting EXE Drop Malware

평소 생각만 하고 언젠가 한번쯤 코딩해봐야지 했던 도구였는데 우연히 보게 되었다.

이 스크립트는 주로 타켓 공격에 많이 이용되는 PDF나 DOC 등 문서 파일의 취약점을 이용하여 악성코드를 감염시킬 때, 만약 문서파일 내부에 악성 PE파일이 있을 경우 뽑아주는 스크립트 이다.

물론 파일 내부에 삽입하지 않고 외부에서 다운로드 받아 실행하는 쉘코드가 들어가 있는 경우도 있지만 경험 상 PE파일이 삽입된 경우가 많았다.

이 스크립트에 사용된 라이브러리도 앞으로 꽤나 유용하게 쓰일거 같다 🙂

#!/usr/bin/python
# [ pyexedump.py ]
#
# By Neil Archibald
#

import sys
import yara     # http://code.google.com/p/yara-project/
import pefile   # http://code.google.com/p/pefile/
import md5
import mmap

class exedump:
    __srch = """
    rule exe_drop
    {
        strings:
            $a  = "This program cannot be run in DOS mode"
        condition:
            all of them
    }
    """

    MZSIZE = 78

    def __init__(self, search_file):
        self.__offset = None
        self.__pe = None
        self.__pe_size = None
        self.__map = None
        self.__rules = yara.compile(source=exedump.__srch)
        self.__search_file = search_file
        self.__matches = self.__rules.match(self.__search_file)
    # end __init__

    def __set_pe_size(self):
        largest = 0
        for section in self.__pe.sections:
            addr = section.PointerToRawData + section.SizeOfRawData
            if(addr > largest):
                largest = addr
            # end if
        # end for
        self.__pe_size = largest

    def has_pe(self):
        return (self.__matches and len(self.__matches) != 0)

    def find_pe(self):
        if not self.has_pe():
            return None

        self.__offset = self.__matches[0].strings[0][0] - exedump.MZSIZE # offset in file to start of MZ header
        return self.__offset

    def parse_pe(self):
        if self.__offset == None and self.find_pe() == None:
            return None

        fp = open(self.__search_file,'r+b')
        self.__map = mmap.mmap(fp.fileno(),0)
        fp.close()

        self.__pe = pefile.PE(data=self.__map[self.__offset:])
        self.__set_pe_size()
        self.__map = self.__map[self.__offset:self.__offset + self.__pe_size]    #truncate extra bits
        return self.__pe_size

    def write_pe(self, filename=None):
        if not self.__map:
            return None

        if not filename:
            filename = self.gen_filename()
        fp = open(filename, "wb+")
        fp.write(self.__map)
        fp.close()

        return filename

    def gen_filename(self):
        m = md5.new()
        m.update(self.__map)
        filename = m.hexdigest() + ".exe"
        return filename

    def get_filesize(self):
        if self.__pe_size == None:
            self.__pe_size = self.__set_pe_size()

        return self.__pe_size

# end exedump

def main(argv):

    if(len(argv) != 2):
        print "usage: %s \n" % argv[0]
        sys.exit(1)
    # end if

    ed = exedump(argv[1])
    if not ed.has_pe():
        print "[!] error: no embedded executable file detected"
        sys.exit(1)
    # end if

    print "[+] Searching for embedded EXE file in: %s" % argv[1]

    offset = ed.find_pe()
    print "[+] Found file embedded EXE at offset: 0x%x" % offset

    file_size = ed.parse_pe()
    print "[+] Size of PE file: 0x%x bytes." % file_size

    exefilename = ed.gen_filename()
    print "[+] Writing out exe file to: %s." % exefilename

    ed.write_pe(exefilename)

# end main

if __name__ == "__main__":
    main(sys.argv)
# end if

출처 : http://blogs.cisco.com/security/extracting-exe-drop-malware/

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다