def format(self, filehandle, filename, filename_ex): ret = {} mm = filehandle if mm[:8] == '\xD0\xCF\x11\xE0\xA1\xB1\x1A\xE1': # OLE 헤더와 동일 o = None try: o = ole.OleFile(filename) if '\x01Ole10Native' in o.listdir(): pics = o.openstream('\x01Ole10Native') buf = pics.read() if self.verbose: print '-' * 79 kavutil.vprint('Engine') kavutil.vprint(None, 'Engine', 'olenative.kmd') kavutil.vprint(None, 'File name', os.path.split(filename)[-1]) fileformat = analysis_ole10native(buf, self.verbose) if fileformat: ret = {'ff_ole10native': fileformat} except ole.Error: pass if o: o.close() return ret
def format(self, filehandle, filename, filename_ex): fileformat = {} # 포맷 정보를 담을 공간 ret = {} mm = filehandle if mm[:8] == '\xD0\xCF\x11\xE0\xA1\xB1\x1A\xE1': # OLE 헤더와 동일 o = None try: o = ole.OleFile(filename) pics = o.openstream('FileHeader') data = pics.read() if data[:0x11] == 'HWP Document File': ret['ff_hwp'] = 'HWP' except ole.Error: pass if o: o.close() # HWP 파일 내부에 첨부된 OLE 파일인가? if self.hwp_ole.search(filename_ex): ret['ff_hwp_ole'] = 'HWP_OLE' return ret
def arclist(self, filename, fileformat): file_scan_list = [] # 검사 대상 정보를 모두 가짐 # 미리 분석된 파일 포맷중에 HWP 파일 포맷이 있는가? if 'ff_hwp' in fileformat: # OLE Stream 목록 추출하기 o = ole.OleFile(filename) for name in o.listdir(): file_scan_list.append(['arc_hwp', name]) o.close() elif 'ff_hwp_ole' in fileformat: # HWP 파일 내부에 포함된 OLE 파일? file_scan_list.append(['arc_hwp_ole', 'Embedded']) return file_scan_list
def unarc(self, arc_engine_id, arc_name, fname_in_arc): data = None if arc_engine_id == 'arc_hwp': o = ole.OleFile(arc_name) fp = o.openstream(fname_in_arc) data = fp.read() o.close() elif arc_engine_id == 'arc_hwp_ole': with open(arc_name, 'rb') as fp: buf = fp.read() try: buf = zlib.decompress(buf, -15) except zlib.error: pass if kavutil.get_uint32(buf, 0) == len(buf[4:]): data = buf[4:] return data
def cure_office_macro(filename, malware_id): cure_macro_ref = { MALWARE_ID_WORD95: (None, 'WordDocument', cure_word95_macro), MALWARE_ID_WORD97: ('Macros', 'WordDocument', cure_word97_macro), MALWARE_ID_EXCEL95: ('_VBA_PROJECT', 'Book', cure_excel95_macro), MALWARE_ID_EXCEL97: ('_VBA_PROJECT_CUR', 'Workbook', cure_excel97_macro), MALWARE_ID_EXCEL_FORMULA97: (None, 'Workbook', cure_excel97_formula), } ret = False try: o = ole.OleFile(filename, write_mode=True) ole_lists = o.listdir(streams=True, storages=True) for name in ole_lists: pps = name.split('/') if cure_macro_ref[malware_id][0] and pps[-1] == cure_macro_ref[ malware_id][0]: o.delete(name) elif pps[-1] == cure_macro_ref[malware_id][1]: pics = o.openstream(name) t_data = pics.read() t_ret, t_data = cure_macro_ref[malware_id][2](t_data, verbose=True) if t_ret: o.write_stream(name, t_data) ret = True else: ret = False o.close() except IOError: pass return ret
def unarc(self, arc_engine_id, arc_name, fname_in_arc): if arc_engine_id.find('arc_ole10native:') != -1: val = arc_engine_id.split(':') off = int(val[1]) size = int(val[2]) data = None o = None try: o = ole.OleFile(arc_name) if '\x01Ole10Native' in o.listdir(): pics = o.openstream('\x01Ole10Native') buf = pics.read() data = buf[off:] except ole.Error: pass if o: o.close() return data return None
def scan(self, filehandle, filename, fileformat, filename_ex): # 악성코드 검사 mm = filehandle o = None try: # 미리 분석된 파일 포맷중에 OLE 포맷이 있는가? if 'ff_ole' in fileformat: o = ole.OleFile(filename) # 취약점 공격인가? if len(o.exploit): if o: o.close() return True, o.exploit[0], MALWARE_ID_OLE, kernel.INFECTED ole_lists = o.listdir() for pps_name in ole_lists: if pps_name.lower().find( '/vba/dir') != -1: # 오피스 97 매크로 존재 여부 pics = o.openstream(pps_name) data = pics.read() ret, decom_data = decompress(data) # dir 스트림 압축 해제 if ret: vba_modules = analysis_dir_stream(decom_data) t = pps_name.split('/') for vba in vba_modules: t[-1] = vba[0] t_pps_name = '/'.join(t) t_pics = o.openstream( t_pps_name) # 매크로가 존재하는 스트림 열기 t_data = t_pics.read() if len(t_data) == 0: # 데이터가 없으면 다음 vba 체크 continue t_ret, buf = decompress( t_data[vba[1]:]) # 매크로 소스코드 획득 완료 buf = buf.replace('\r\n', '\n') if t_ret: if self.verbose: # 매크로 소스코드 출력 kavutil.vprint('Macro Source') kavutil.vprint(None, 'PPS', '%s' % t_pps_name) print buf buf = self.p_vba_cmt.sub('', buf) # 주석문 제거 buf = buf.lower() # 영어 소문자로 통일 key_words = self.p_vba_word.findall(buf) vba_keyword_crc32 = set() for i in range(len(key_words) - 1): word = key_words[i] + key_words[i + 1] c = zlib.crc32(word) & 0xffffffffL vba_keyword_crc32.add(c) # 테스트 if self.verbose: max_len = len(key_words[0]) t_word = [] for i in range(len(key_words) - 1): word = key_words[i] + key_words[i + 1] c = zlib.crc32(word) & 0xffffffffL t_word.append([ c, key_words[i], key_words[i + 1] ]) if len(key_words[i + 1]) > max_len: max_len = len(key_words[i + 1]) t_l = '+-' + ('-' * 8) + '-+-' + ( '-' * max_len) + '-+-' + ( '-' * max_len) + '-+' print t_l msg = '| %%-8s | %%-%ds | %%-%ds |' % ( max_len, max_len) print msg % ('CRC32', 'Keyword #1', 'Keyword #2') print t_l msg = '| %%08X | %%-%ds | %%-%ds |' % ( max_len, max_len) for n in t_word: print msg % (n[0], n[1], n[2]) print t_l # Heuristic 검사 for macro_crc in self.word97_macro_crcs: if macro_crc.issubset( vba_keyword_crc32): if o: o.close() return True, 'Virus.MSWord.Generic', MALWARE_ID_WORD97, kernel.SUSPECT except IOError: pass except ole.Error: pass if o: o.close() # 악성코드를 발견하지 못했음을 리턴한다. return False, '', -1, kernel.INFECTED