def listvirus(self): # 진단 가능한 악성코드 리스트 vlist = kavutil.handle_pattern_md5.get_sig_vlist('emalware') vlist.append('Backdoor.Linux.Mirai.a.gen') vlist = list(set(vlist)) vlist.sort() vlists = [] for vname in vlist: vlists.append(kavutil.normal_vname(vname)) vlists.append(kavutil.normal_vname('<n>AdWare.Win32.Sokuxuan.gen')) return vlists
def listvirus(self): # 진단 가능한 악성코드 리스트 vlist = kavutil.handle_pattern_vdb.get_sig_vlist('ve') vlist.sort() vlists = [] for vname in vlist: vlists.append(kavutil.normal_vname(vname)) return vlists
def listvirus(self): # 진단 가능한 악성코드 리스트 vlist = kavutil.handle_pattern_vdb.get_sig_vlist('ve') vlists = [] vlists.append('Virus.Win32.Small.a') vlists.append('Virus.Win32.SuperThreat.b') for vname in vlist: vlists.append(kavutil.normal_vname(vname)) vlists.sort() return vlists
def __scan_cs2(self, mm, ve_id, idx): cs2 = kavutil.handle_pattern_vdb.get_cs2(ve_id, idx) cs2_flag = cs2[0] cs2_off = cs2[1] cs2_size = cs2[2] cs2_crc = cs2[3] vname_id = cs2[4] crc32s = self.__get_data_crc32(mm, cs2_flag, cs2_off, cs2_size) if cs2_crc in crc32s: # 패턴 일치 vname = kavutil.handle_pattern_vdb.get_vname(ve_id, vname_id) if vname: return kavutil.normal_vname(vname) return None
def listvirus(self): # 진단 가능한 악성코드 리스트 vlist = kavutil.handle_pattern_md5.get_sig_vlist('adware') vlist = list(set(vlist)) vlist.sort() vlists = [] for vname in vlist: vname = kavutil.normal_vname(vname) if vname.find('<p>'): vlists.append(vname.replace('<p>', 'Win32')) vlists.append(vname.replace('<p>', 'MSIL')) else: vlists.append(vname) vlists.sort() return vlists
def __scan_asn1(self, filehandle, filename, fileformat, filename_ex): mm = filehandle ff = fileformat['ff_pe'] cert_off = ff['pe'].get('CERTIFICATE_Offset', 0) cert_size = ff['pe'].get('CERTIFICATE_Size', 0) if cert_off != 0 and cert_size != 0: if self.verbose: print '-' * 79 kavutil.vprint('Engine') kavutil.vprint(None, 'Engine', 'adware.kmd') # 인증서 추출 cert_data = mm[cert_off:cert_off + cert_size] asn1 = ASN1() asn1.set_data(cert_data[8:]) try: r = asn1.parse() # Signed Data 이면서 버전 정보가 1인가? if r[0][0] == '2A 86 48 86 F7 0D 01 07 02' and r[0][1][0][ 0] == '01': signeddata = r[0][1][0] certificates = signeddata[3] signerinfo = r[0][1][0][-1] issuer_and_serialnumber = signerinfo[0][1] issuer_serial = issuer_and_serialnumber[1] for cert in certificates: if cert[0][1] == issuer_serial: # 동일한 일련번호 찾기 for x in cert[0][5]: if x[0][0] == '55 04 03': # Common Name signer_name = x[0][1] break else: continue # no break encountered break else: raise IndexError # 일련번호의 길이가 제각각이라 md5 고정길이로 만듬 fmd5 = cryptolib.md5(issuer_serial) fsize = kavutil.get_uint16(fmd5.decode('hex'), 0) if self.verbose: kavutil.vprint('Signer') kavutil.vprint(None, 'Name', signer_name) kavutil.vprint(None, 'Serial Number', issuer_serial) msg = '%d:%s: # %s, %s\n' % (fsize, fmd5, signer_name, cryptolib.sha256(mm)) open('adware.mdb', 'at').write(msg) if fsize and kavutil.handle_pattern_md5.match_size( 'adware', fsize): vname = kavutil.handle_pattern_md5.scan( 'adware', fsize, fmd5) if vname: pos = ff['pe'].get('EntryPointRaw', 0) if mm[pos:pos + 4] == '\xff\x25\x00\x20': pf = 'MSIL' else: pf = 'Win32' vname = kavutil.normal_vname(vname, pf) return True, vname, 0, kernel.INFECTED except IndexError: pass # 악성코드를 발견하지 못했음을 리턴한다. return False, '', -1, kernel.NOT_FOUND
def scan(self, filehandle, filename, fileformat, filename_ex): # 악성코드 검사 try: mm = filehandle # 미리 분석된 파일 포맷중에 PE 포맷이 있는가? if 'ff_pe' in fileformat: ff = fileformat['ff_pe'] # case 1 : 섹션 전체를 hash로 검사 for idx, section in enumerate(ff['pe']['Sections']): # if (section['Characteristics'] & 0x20000000) == 0x20000000: # 실행 속성? # print section['Name'], hex(section['SizeRawData']) fsize = section['SizeRawData'] if fsize and kavutil.handle_pattern_md5.match_size( 'emalware', fsize): foff = section['PointerRawData'] fmd5 = cryptolib.md5(mm[foff:foff + fsize]) # print fsize, fmd5 vname = kavutil.handle_pattern_md5.scan( 'emalware', fsize, fmd5) if vname: vname = kavutil.normal_vname(vname) return True, vname, 0, kernel.INFECTED # case 2. 마지막 섹션에 실행 파일 존재 if len(ff['pe']['Sections']): # 마지막 섹션 sec = ff['pe']['Sections'][-1] off = sec['PointerRawData'] size = sec['SizeRawData'] # 실행 파일이 존재하는가? exe_offs = [ m.start() for m in re.finditer('MZ', mm[off:off + size]) ] for exe_pos in exe_offs: fsize = 0x1d5 if fsize and kavutil.handle_pattern_md5.match_size( 'emalware', fsize): fmd5 = cryptolib.md5(mm[off + exe_pos:off + exe_pos + fsize]) # print fsize, fmd5 vname = kavutil.handle_pattern_md5.scan( 'emalware', fsize, fmd5) if vname: # return True, vname, 0, kernel.INFECTED idx = len(ff['pe']['Sections']) - 1 vname = kavutil.normal_vname(vname) return True, vname, (0x80000000 + idx), kernel.INFECTED # case 3. pdb를 이용해서 악성코드 검사 if 'PDB_Name' in ff['pe']: pdb_sigs = { ':\\pz_git\\bin\\': '<n>AdWare.Win32.Sokuxuan.gen', ':\\CODE\\vitruvian\\': '<n>AdWare.Win32.Vitruvian.gen', '\\bin\\Release\\WebSparkle.': '<n>AdWare.MSIL.BrowseFox.gen', ':\\TeamCity\\BuildAgent1\\work\\': '<n>WebToolbar.Win32.Agent.avi', } for pat in pdb_sigs.keys(): if ff['pe']['PDB_Name'].find(pat) != -1: vname = kavutil.normal_vname(pdb_sigs[pat]) return True, vname, 0, kernel.INFECTED # case 4. Worm.Win32.Allaple.gen 검사 ep_off = ff['pe']['EntryPointRaw'] data = mm[ep_off:ep_off + 0x80] if self.p_allaple.search(data): return True, 'Worm.Win32.Allaple.gen', 0, kernel.INFECTED # 미리 분석된 파일 포맷중에 ELF 포맷이 있는가? elif 'ff_elf' in fileformat: ff = fileformat['ff_elf'] if len(ff['elf']['Sections']): for section in ff['elf']['Sections']: if (section['Type'] & 0x1) == 0x1 and ( section['Flag'] & 0x4) == 0x4: # 프로그램 데이터이면서 실행 속성? # print section['Name'], section['Size'], section['Offset'] fsize = section['Size'] if fsize and kavutil.handle_pattern_md5.match_size( 'emalware', fsize): foff = section['Offset'] fmd5 = cryptolib.md5(mm[foff:foff + fsize]) # print fsize, fmd5 vname = kavutil.handle_pattern_md5.scan( 'emalware', fsize, fmd5) if vname: vname = kavutil.normal_vname(vname) return True, vname, 0, kernel.INFECTED elif len(ff['elf']['ProgramHeaders']): for ph in ff['elf']['ProgramHeaders']: if (ph['Type'] & 0x1) == 0x1 and (ph['Flag'] & 0x1) == 0x1: fsize = ph['Size'] if fsize and kavutil.handle_pattern_md5.match_size( 'emalware', fsize): foff = ph['Offset'] fmd5 = cryptolib.md5(mm[foff:foff + fsize]) # print fsize, fmd5 vname = kavutil.handle_pattern_md5.scan( 'emalware', fsize, fmd5) if vname: vname = kavutil.normal_vname(vname) return True, vname, 0, kernel.INFECTED # Mirai 변종 진단 ''' for section in ff['elf']['Sections']: if section['Name'] == '.rodata': fsize = section['Size'] foff = section['Offset'] if self.p_linux_mirai.match(mm[foff:foff+fsize]): return True, 'Backdoor.Linux.Mirai.gen', 0, kernel.SUSPECT ''' for section in ff['elf']['Sections']: if section['Name'] == '.rodata': vstring = [] foff = section['Offset'] ret = self.aho_mirai_a.search(mm[foff:foff + 0x200]) for n in ret[:len(self.mirai_a_strings)]: vstring.append(n[1]) # print vstring # print len(set(vstring)), len(self.mirai_a_strings) if set(vstring) == set(self.mirai_a_strings): return True, 'Backdoor.Linux.Mirai.a.gen', 0, kernel.SUSPECT # NSIS 같은 설치 프로그램의 경우 첨부 영역에 존재하는데.. # 디컴파일하지 않고 오리지널 이미지 원본을 탐지하도록 했음.. if 'ff_attach' in fileformat: foff = fileformat['ff_attach']['Attached_Pos'] buf = mm[foff:] fsize = len(buf) if fsize and kavutil.handle_pattern_md5.match_size( 'emalware', fsize): fmd5 = cryptolib.md5(buf) # 첨부 위치부터 끝까지 vname = kavutil.handle_pattern_md5.scan( 'emalware', fsize, fmd5) if vname: vname = kavutil.normal_vname(vname) return True, vname, 0, kernel.INFECTED except IOError: pass # 악성코드를 발견하지 못했음을 리턴한다. return False, '', -1, kernel.NOT_FOUND
def scan(self, filehandle, filename, fileformat, filename_ex): # 악성코드 검사 try: mm = filehandle # 미리 분석된 파일 포맷중에 PE 포맷이 있는가? if 'ff_pe' in fileformat: ff = fileformat['ff_pe'] # case 1 : 섹션 전체를 hash로 검사 for idx, section in enumerate(ff['pe']['Sections']): # if (section['Characteristics'] & 0x20000000) == 0x20000000: # 실행 속성? # print section['Name'], hex(section['SizeRawData']) fsize = section['SizeRawData'] if fsize and kavutil.handle_pattern_md5.match_size('emalware', fsize): foff = section['PointerRawData'] fmd5 = cryptolib.md5(mm[foff:foff+fsize]) # print fsize, fmd5 vname = kavutil.handle_pattern_md5.scan('emalware', fsize, fmd5) if vname: vname = kavutil.normal_vname(vname) return True, vname, 0, kernel.INFECTED # case 2. 마지막 섹션에 실행 파일 존재 if len(ff['pe']['Sections']): # 마지막 섹션 sec = ff['pe']['Sections'][-1] off = sec['PointerRawData'] size = sec['SizeRawData'] # 실행 파일이 존재하는가? exe_offs = [m.start() for m in re.finditer('MZ', mm[off:off+size])] for exe_pos in exe_offs: fsize = 0x1d5 if fsize and kavutil.handle_pattern_md5.match_size('emalware', fsize): fmd5 = cryptolib.md5(mm[off + exe_pos:off + exe_pos + fsize]) # print fsize, fmd5 vname = kavutil.handle_pattern_md5.scan('emalware', fsize, fmd5) if vname: # return True, vname, 0, kernel.INFECTED idx = len(ff['pe']['Sections']) - 1 vname = kavutil.normal_vname(vname) return True, vname, (0x80000000 + idx), kernel.INFECTED # case 3. pdb를 이용해서 악성코드 검사 if 'PDB_Name' in ff['pe']: pdb_sigs = { ':\\pz_git\\bin\\': '<n>AdWare.Win32.Sokuxuan.gen', ':\\CODE\\vitruvian\\': '<n>AdWare.Win32.Vitruvian.gen', '\\bin\\Release\\WebSparkle.': '<n>AdWare.MSIL.BrowseFox.gen', ':\\TeamCity\\BuildAgent1\\work\\': '<n>WebToolbar.Win32.Agent.avi', } for pat in pdb_sigs.keys(): if ff['pe']['PDB_Name'].find(pat) != -1: vname = kavutil.normal_vname(pdb_sigs[pat]) return True, vname, 0, kernel.INFECTED # case 4. Worm.Win32.Allaple.gen 검사 ep_off = ff['pe']['EntryPointRaw'] data = mm[ep_off:ep_off+0x80] if self.p_allaple.search(data): return True, 'Worm.Win32.Allaple.gen', 0, kernel.INFECTED # 미리 분석된 파일 포맷중에 ELF 포맷이 있는가? elif 'ff_elf' in fileformat: ff = fileformat['ff_elf'] if len(ff['elf']['Sections']): for section in ff['elf']['Sections']: if (section['Type'] & 0x1) == 0x1 and (section['Flag'] & 0x4) == 0x4: # 프로그램 데이터이면서 실행 속성? # print section['Name'], section['Size'], section['Offset'] fsize = section['Size'] if fsize and kavutil.handle_pattern_md5.match_size('emalware', fsize): foff = section['Offset'] fmd5 = cryptolib.md5(mm[foff:foff + fsize]) # print fsize, fmd5 vname = kavutil.handle_pattern_md5.scan('emalware', fsize, fmd5) if vname: vname = kavutil.normal_vname(vname) return True, vname, 0, kernel.INFECTED elif len(ff['elf']['ProgramHeaders']): for ph in ff['elf']['ProgramHeaders']: if (ph['Type'] & 0x1) == 0x1 and (ph['Flag'] & 0x1) == 0x1: fsize = ph['Size'] if fsize and kavutil.handle_pattern_md5.match_size('emalware', fsize): foff = ph['Offset'] fmd5 = cryptolib.md5(mm[foff:foff + fsize]) # print fsize, fmd5 vname = kavutil.handle_pattern_md5.scan('emalware', fsize, fmd5) if vname: vname = kavutil.normal_vname(vname) return True, vname, 0, kernel.INFECTED # Mirai 변종 진단 ''' for section in ff['elf']['Sections']: if section['Name'] == '.rodata': fsize = section['Size'] foff = section['Offset'] if self.p_linux_mirai.match(mm[foff:foff+fsize]): return True, 'Backdoor.Linux.Mirai.gen', 0, kernel.SUSPECT ''' for section in ff['elf']['Sections']: if section['Name'] == '.rodata': vstring = [] foff = section['Offset'] ret = self.aho_mirai_a.search(mm[foff:foff + 0x200]) for n in ret[:len(self.mirai_a_strings)]: vstring.append(n[1]) # print vstring # print len(set(vstring)), len(self.mirai_a_strings) if set(vstring) == set(self.mirai_a_strings): return True, 'Backdoor.Linux.Mirai.a.gen', 0, kernel.SUSPECT # NSIS 같은 설치 프로그램의 경우 첨부 영역에 존재하는데.. # 디컴파일하지 않고 오리지널 이미지 원본을 탐지하도록 했음.. if 'ff_attach' in fileformat: foff = fileformat['ff_attach']['Attached_Pos'] buf = mm[foff:] fsize = len(buf) if fsize and kavutil.handle_pattern_md5.match_size('emalware', fsize): fmd5 = cryptolib.md5(buf) # 첨부 위치부터 끝까지 vname = kavutil.handle_pattern_md5.scan('emalware', fsize, fmd5) if vname: vname = kavutil.normal_vname(vname) return True, vname, 0, kernel.INFECTED except IOError: pass # 악성코드를 발견하지 못했음을 리턴한다. return False, '', -1, kernel.NOT_FOUND
def scan(self, filehandle, filename, fileformat, filename_ex): # 악성코드 검사 try: mm = filehandle # 미리 분석된 파일 포맷중에 PE 포맷이 있는가? if 'ff_pe' in fileformat: ff = fileformat['ff_pe'] # case 1 : 섹션 전체를 hash로 검사 for idx, section in enumerate(ff['pe']['Sections']): # if (section['Characteristics'] & 0x20000000) == 0x20000000: # 실행 속성? # print section['Name'], hex(section['SizeRawData']) fsize = section['SizeRawData'] if fsize and kavutil.handle_pattern_md5.match_size( 'emalware', fsize): foff = section['PointerRawData'] fmd5 = cryptolib.md5(mm[foff:foff + fsize]) # print fsize, fmd5 vname = kavutil.handle_pattern_md5.scan( 'emalware', fsize, fmd5) if vname: vname = kavutil.normal_vname(vname) return True, vname, 0, kernel.INFECTED # case 2. 마지막 섹션에 실행 파일 존재 if len(ff['pe']['Sections']): # 마지막 섹션 sec = ff['pe']['Sections'][-1] off = sec['PointerRawData'] size = sec['SizeRawData'] # 실행 파일이 존재하는가? exe_offs = [ m.start() for m in re.finditer('MZ', mm[off:off + size]) ] for exe_pos in exe_offs: fsize = 0x1d5 if fsize and kavutil.handle_pattern_md5.match_size( 'emalware', fsize): fmd5 = cryptolib.md5(mm[off + exe_pos:off + exe_pos + fsize]) # print fsize, fmd5 vname = kavutil.handle_pattern_md5.scan( 'emalware', fsize, fmd5) if vname: # return True, vname, 0, kernel.INFECTED idx = len(ff['pe']['Sections']) - 1 vname = kavutil.normal_vname(vname) return True, vname, (0x80000000 + idx), kernel.INFECTED # 미리 분석된 파일 포맷중에 ELF 포맷이 있는가? elif 'ff_elf' in fileformat: ff = fileformat['ff_elf'] if len(ff['elf']['Sections']): for section in ff['elf']['Sections']: if (section['Type'] & 0x1) == 0x1 and ( section['Flag'] & 0x4) == 0x4: # 프로그램 데이터이면서 실행 속성? # print section['Name'], section['Size'], section['Offset'] fsize = section['Size'] if fsize and kavutil.handle_pattern_md5.match_size( 'emalware', fsize): foff = section['Offset'] fmd5 = cryptolib.md5(mm[foff:foff + fsize]) # print fsize, fmd5 vname = kavutil.handle_pattern_md5.scan( 'emalware', fsize, fmd5) if vname: vname = kavutil.normal_vname(vname) return True, vname, 0, kernel.INFECTED elif len(ff['elf']['ProgramHeaders']): for ph in ff['elf']['ProgramHeaders']: if (ph['Type'] & 0x1) == 0x1 and (ph['Flag'] & 0x1) == 0x1: fsize = ph['Size'] if fsize and kavutil.handle_pattern_md5.match_size( 'emalware', fsize): foff = ph['Offset'] fmd5 = cryptolib.md5(mm[foff:foff + fsize]) # print fsize, fmd5 vname = kavutil.handle_pattern_md5.scan( 'emalware', fsize, fmd5) if vname: vname = kavutil.normal_vname(vname) return True, vname, 0, kernel.INFECTED # Mirai 변종 진단 ''' for section in ff['elf']['Sections']: if section['Name'] == '.rodata': fsize = section['Size'] foff = section['Offset'] if self.p_linux_mirai.match(mm[foff:foff+fsize]): return True, 'Backdoor.Linux.Mirai.gen', 0, kernel.SUSPECT ''' for section in ff['elf']['Sections']: if section['Name'] == '.rodata': vstring = [] foff = section['Offset'] ret = self.aho_mirai_a.search(mm[foff:foff + 0x200]) for n in ret[:len(self.mirai_a_strings)]: vstring.append(n[1]) # print vstring # print len(set(vstring)), len(self.mirai_a_strings) if set(vstring) == set(self.mirai_a_strings): return True, 'Backdoor.Linux.Mirai.a.gen', 0, kernel.SUSPECT # NSIS 같은 설치 프로그램의 경우 첨부 영역에 존재하는데.. # 디컴파일하지 않고 오리지널 이미지 원본을 탐지하도록 했음.. if 'ff_attach' in fileformat: foff = fileformat['ff_attach']['Attached_Pos'] buf = mm[foff:] fsize = len(buf) if fsize and kavutil.handle_pattern_md5.match_size( 'emalware', fsize): fmd5 = cryptolib.md5(buf) # 첨부 위치부터 끝까지 vname = kavutil.handle_pattern_md5.scan( 'emalware', fsize, fmd5) if vname: vname = kavutil.normal_vname(vname) return True, vname, 0, kernel.INFECTED except IOError: pass # 악성코드를 발견하지 못했음을 리턴한다. return False, '', -1, kernel.NOT_FOUND
def __scan_asn1(self, filehandle, filename, fileformat, filename_ex): mm = filehandle ff = fileformat['ff_pe'] cert_off = ff['pe'].get('CERTIFICATE_Offset', 0) cert_size = ff['pe'].get('CERTIFICATE_Size', 0) if cert_off != 0 and cert_size != 0: if self.verbose: print '-' * 79 kavutil.vprint('Engine') kavutil.vprint(None, 'Engine', 'adware.kmd') # 인증서 추출 cert_data = mm[cert_off:cert_off + cert_size] asn1 = ASN1() asn1.set_data(cert_data[8:]) try: r = asn1.parse() # Signed Data 이면서 버전 정보가 1인가? if r[0][0] == '2A 86 48 86 F7 0D 01 07 02' and r[0][1][0][0] == '01': signeddata = r[0][1][0] certificates = signeddata[3] signerinfo = r[0][1][0][-1] issuer_and_serialnumber = signerinfo[0][1] issuer_serial = issuer_and_serialnumber[1] for cert in certificates: if cert[0][1] == issuer_serial: # 동일한 일련번호 찾기 for x in cert[0][5]: if x[0][0] == '55 04 03': # Common Name signer_name = x[0][1] break else: continue # no break encountered break else: raise IndexError # 일련번호의 길이가 제각각이라 md5 고정길이로 만듬 fmd5 = cryptolib.md5(issuer_serial) fsize = kavutil.get_uint16(fmd5.decode('hex'), 0) if self.verbose: kavutil.vprint('Signer') kavutil.vprint(None, 'Name', signer_name) kavutil.vprint(None, 'Serial Number', issuer_serial) msg = '%d:%s: # %s, %s\n' % (fsize, fmd5, signer_name, cryptolib.sha256(mm)) open('adware.mdb', 'at').write(msg) if fsize and kavutil.handle_pattern_md5.match_size('adware', fsize): vname = kavutil.handle_pattern_md5.scan('adware', fsize, fmd5) if vname: pos = ff['pe'].get('EntryPointRaw', 0) if mm[pos:pos + 4] == '\xff\x25\x00\x20': pf = 'MSIL' else: pf = 'Win32' vname = kavutil.normal_vname(vname, pf) return True, vname, 0, kernel.INFECTED except IndexError: pass # 악성코드를 발견하지 못했음을 리턴한다. return False, '', -1, kernel.NOT_FOUND