def extract_os(): format_name = ida_loader.get_file_type_name() if "PE" in format_name: yield OS(OS_WINDOWS), 0x0 elif "ELF" in format_name: with contextlib.closing(capa.ida.helpers.IDAIO()) as f: os = capa.features.extractors.elf.detect_elf_os(f) yield OS(os), 0x0 else: # we likely end up here: # 1. handling shellcode, or # 2. handling a new file format (e.g. macho) # # for (1) we can't do much - its shellcode and all bets are off. # we could maybe accept a futher CLI argument to specify the OS, # but i think this would be rarely used. # rules that rely on OS conditions will fail to match on shellcode. # # for (2), this logic will need to be updated as the format is implemented. logger.debug("unsupported file format: %s, will not guess OS", format_name) return
def extract_os(buf): if buf.startswith(b"MZ"): yield OS(OS_WINDOWS), 0x0 elif buf.startswith(b"\x7fELF"): with contextlib.closing(io.BytesIO(buf)) as f: os = capa.features.extractors.elf.detect_elf_os(f) if os not in capa.features.common.VALID_OS: logger.debug("unsupported os: %s", os) return yield OS(os), 0x0 else: # we likely end up here: # 1. handling shellcode, or # 2. handling a new file format (e.g. macho) # # for (1) we can't do much - its shellcode and all bets are off. # we could maybe accept a futher CLI argument to specify the OS, # but i think this would be rarely used. # rules that rely on OS conditions will fail to match on shellcode. # # for (2), this logic will need to be updated as the format is implemented. logger.debug("unsupported file format: %s, will not guess OS", binascii.hexlify(buf[:4]).decode("ascii")) return
def test_os_features(): rule = textwrap.dedent( """ rule: meta: name: test rule scope: file features: - and: - os: windows """ ) r = capa.rules.Rule.from_yaml(rule) children = list(r.statement.get_children()) assert (OS(OS_WINDOWS) in children) == True assert (OS(OS_LINUX) not in children) == True
def extract_file_os(elf, buf, **kwargs): # our current approach does not always get an OS value, e.g. for packed samples # for file limitation purposes, we're more lax here try: os = next(capa.features.extractors.common.extract_os(buf)) yield os except StopIteration: yield OS("unknown"), 0x0
# insn/characteristic(calls from) ("mimikatz", "function=0x4556E5", capa.features.common.Characteristic("calls from"), True), ("mimikatz", "function=0x4702FD", capa.features.common.Characteristic("calls from"), False), # function/characteristic(calls to) ("mimikatz", "function=0x40105D", capa.features.common.Characteristic("calls to"), True), # before this we used ambiguous (0x4556E5, False), which has a data reference / indirect recursive call, see #386 ("mimikatz", "function=0x456BB9", capa.features.common.Characteristic("calls to"), False), # file/function-name ("pma16-01", "file", capa.features.file.FunctionName("__aulldiv"), True ), # os & format & arch ("pma16-01", "file", OS(OS_WINDOWS), True), ("pma16-01", "file", OS(OS_LINUX), False), ("pma16-01", "function=0x404356", OS(OS_WINDOWS), True), ("pma16-01", "function=0x404356,bb=0x4043B9", OS(OS_WINDOWS), True), ("pma16-01", "file", Arch(ARCH_I386), True), ("pma16-01", "file", Arch(ARCH_AMD64), False), ("pma16-01", "function=0x404356", Arch(ARCH_I386), True), ("pma16-01", "function=0x404356,bb=0x4043B9", Arch(ARCH_I386), True), ("pma16-01", "file", Format(FORMAT_PE), True), ("pma16-01", "file", Format(FORMAT_ELF), False), # elf support ("7351f.elf", "file", OS(OS_LINUX), True), ("7351f.elf", "file", OS(OS_WINDOWS), False), ("7351f.elf", "file", Format(FORMAT_ELF), True), ("7351f.elf", "file", Format(FORMAT_PE), False), ("7351f.elf", "file", Arch(ARCH_I386), False),
def extract_file_os(**kwargs) -> Iterator[Tuple[OS, int]]: yield OS(OS_ANY), 0x0
def extract_file_os(**kwargs): # assuming PE -> Windows # though i suppose they're also used by UEFI yield OS(OS_WINDOWS), 0x0