Ejemplo n.º 1
0
def main(filename=None):
    if filename is None:
        filename = fileopenbox(msg="Select PDF file", default="*.pdf", filetypes=["*.pdf"])
        if filename is None:
            return

    pyew = CPyew(batch=True)
    pyew.loadFile(filename)

    streams = pyew.plugins["pdfilter"](pyew, doprint=True)
    if len(streams) == 0:
        msgbox(title="PDF Streams",msg="No encoded streams found")

    l = []
    l.append("About PDF Streams Viewer")
    l.append("See all streams (both encoded and unencoded)")
    for x in streams:
        l.append("Stream %d encoded with %s" % (x, streams[x]))
    l.append("Quit")

    while 1:
        c = choicebox(msg="Select one stream to view it decoded", title="Stream Viewer", choices=l)
        if c is None:
            break
        elif c.lower() == "quit":
            break
        elif c.lower().startswith("about"):
            msgbox(title="About PDF Streams Viewer",
                   msg="Example usage of the Pyew APIs to see PDF streams. Written by Joxean Koret")
        elif c.lower().startswith("see all"):
            pyew.plugins["pdfview"](pyew, doprint=False, stream_id=-1)
        else:
            stream_id = int(c.split(" ")[1])
            pyew.plugins["pdfview"](pyew, stream_id=stream_id)
Ejemplo n.º 2
0
    def __init__(self, binary, sc, out):
        self.binary = binary
        self.sc = sc
        self.out = out
        self.pyew = CPyew(False, False)

        self.sc_buf = None
Ejemplo n.º 3
0
    def check_file(self, filename):
        self.current_file = filename

        pyew = CPyew(batch=True, plugins=True)
        pyew.codeanalysis = True
        pyew.deepcodeanalysis = self.deep

        try:
            pyew.loadFile(filename)
        except:
            raise Exception("Error loading file: %s" % str(sys.exc_info()[1]))

        if pyew.format not in ["PE", "ELF", "BOOT", "BIOS"]:
            sys.stderr.write("[INFO] Ignoring non supported executable file\n")
            sys.stderr.flush()
            return

        program_stats = pyew.program_stats
        md5_hash = md5(pyew.getBuffer()).hexdigest()
        if self.check_or_update(md5_hash, program_stats):
            print "[OK] Test %s (%s)" % (filename, md5_hash)
        else:
            msg = "[FAILED] *** Test %s (%s)"
            print msg % (filename, md5_hash)
            self.show_reason(program_stats)
Ejemplo n.º 4
0
    def processFile(self, filename):
        #print "[+] Analyzing file %s" % filename
        pyew = CPyew(batch=True)
        pyew.deepcodeanalysis = self.deep
        pyew.analysis_timeout = 0
        pyew.loadFile(filename)

        if pyew.format in ["PE", "ELF"]:
            hash = sha256(pyew.getBuffer()).hexdigest()
            self.data.append({hash: pyew})
        else:
            sys.stderr.writelines("Not a PE/ELF file")
            sys.stderr.flush()
Ejemplo n.º 5
0
def checkMebroot(path):
    pyew = CPyew(batch=True)
    pyew.codeanalysis = True

    try:
        pyew.loadFile(path)
    except:
        print "ERROR loading file %s" % path
        return

    if pyew.format == "PE":
        # Get 6 bytes at offset 0xB8
        if pyew.getBytes(0xB8, 6) != "Rich;\x2E":
            return
        printData(pyew, path, "Mebroot downloader")
        print
Ejemplo n.º 6
0
def entryPointCalls(path):
    pyew = CPyew(batch=True)
    pyew.codeanalysis = True
    try:
        pyew.loadFile(path)
    except KeyboardInterrupt:
        print "Abort"
        sys.exit(0)
    except:
        print "ERROR loading file %s" % path
        return

    if pyew.format != "PE":
        return

    calls = []
    # Get the disassembl of the first 100 lines
    l = pyew.disasm(pyew.ep,
                    processor=pyew.processor,
                    type=pyew.type,
                    lines=100,
                    bsize=1600)
    for i in l:
        mnem = str(i.mnemonic)

        # Is it a direct or indirect jump or call?
        if mnem == "CALL" or mnem.startswith("J") or mnem.startswith("LOOP"):
            operands = str(i.operands).replace("[", "").replace("]", "")

            try:
                if pyew.imports.has_key(int(operands, 16)):
                    x = pyew.imports[int(operands, 16)]

                    if x not in calls:
                        calls.append(x)
            except:
                pass

    if len(calls) > 0:
        printData(pyew, path, "Library calls at Entry Point")
        print "Library Calls:", ",".join(calls)
        print
Ejemplo n.º 7
0
def checkAntidebug(path):
    t = time.time()

    pyew = CPyew(batch=True)
    pyew.codeanalysis = True
    try:
        pyew.loadFile(path)
    except KeyboardInterrupt:
        print "Abort"
        sys.exit(0)
    except:
        print "ERROR loading file %s" % path
        return

    if pyew.format not in ["PE", "ELF"]:
        return

    if len(pyew.antidebug) > 0:
        print
        printData(pyew, path, pyew.antidebug)
        print "Time to analyze %f" % (time.time() - t)
        print
Ejemplo n.º 8
0
def checkMnemonics(path):
    pyew = CPyew(batch=True)
    pyew.codeanalysis = True

    try:
        pyew.loadFile(path)
    except:
        print "ERROR loading file %s" % path
        return

    # Is it a PE file?
    if pyew.format == "PE":
        # The most common x86 mnemonics
        commons = ["PUSH", "MOV", "SUB", "ADD", "LEA", "CALL", "JMP", "JZ", "JNZ", \
                   "OR", "XOR", "NOT", "POP", "AND", "TEST", "JL", "JG", "JE", \
                   "JLE", "CMP", "LEAVE", "RET", "NOP", "PUSHF", "POPF", "INC", \
                   "INT 3", "DEC", "PUSHA", "POPA"]

        try:
            # Get the 30 first mnemonics
            mnems = pyew.GetMnems(pyew.ep, 30)
        except:
            print "ERROR scanning file %s" % path
            return

        ret = []
        for x in mnems:
            if x not in commons and x not in ret:
                ret.append(x)

        if len(ret) > 0:
            printData(pyew, path, "Uncommon mnemonics")
            print "Mnemonics:", ",".join(ret)
            print
            # Seek to the entry point
            pyew.seek(pyew.ep)
            # Hexdump the first 64 bytes at the entry point
            print pyew.hexdump(pyew.buf, length=16, bsize=64)
Ejemplo n.º 9
0
    def analyse(self, path):
        filename = path

        t = time.time()
        buf = open(filename, "rb").read()
        sha1_hash = sha1(buf).hexdigest()
        if self.file_exists(sha1_hash):
            log("Already existing file %s..." % sha1_hash)
            return ANALYSIS_ALREADY

        pyew = CPyew(batch=True)
        pyew.analysis_timeout = 300
        pyew.codeanalysis = True
        pyew.deepcodeanalysis = True

        try:
            pyew.loadFile(path)
            load_error = False
        except KeyboardInterrupt:
            log("Abort")
            return ANALYSIS_FAILED
        except:
            log("ERROR loading file %s" % path)
            load_error = True

        if not load_error:
            if pyew.format not in ["PE", "ELF", "bootsector"]:
                if pyew.format not in ["PDF", "OLE2"]:
                    log("Not a known executable/document format")
                load_error = True

        if load_error:
            return ANALYSIS_FAILED

        primes = []
        total_functions = len(pyew.function_stats)
        if not load_error and total_functions > 0:
            nodes = []
            edges = []
            ccs = []
            callgraph = 1
            for x in pyew.function_stats:
                nodes.append(pyew.function_stats[x][0])
                edges.append(pyew.function_stats[x][1])
                cc = pyew.function_stats[x][2]
                ccs.append(cc)

                prime = self.primes_table[cc]
                callgraph *= prime
                primes.append(prime)

            avg_nodes = abs(sum(nodes) / total_functions)
            avg_edges = abs(sum(edges) / total_functions)
            avg_ccs = abs(sum(ccs) / total_functions)
        elif load_error:
            total_functions = avg_nodes = avg_edges = avg_ccs = -1
            callgraph = -1

        msg = "%d-%d-%d-%d" % (total_functions, avg_nodes, avg_edges, avg_ccs)
        log("File analysed %s, callgraph signature %s" % (msg, callgraph))
        log("Time to analyze %f" % (time.time() - t))

        callgraph = str(callgraph)
        primes = ",".join(map(str, primes))
        desc = self.get_description(buf)
        self.db.insert("samples", filename=filename, callgraph=callgraph,  \
                       hash=sha1_hash, total_functions=total_functions,    \
                       format=pyew.format, primes=primes, description=desc,\
                       analysis_date=time.asctime())
        return ANALYSIS_SUCCESS
Ejemplo n.º 10
0
import os, sys
from pyew_core import CPyew

sys.path.append("plugins")

#import diagrams
#import easygui
#import graphs
#import ole2
#import OleFileIO_PL
#import packer
#import pdf
#import pdfid_PL
#import shellcode
#import threatexpert
#import url
#import virustotal
#import vmdetect
#import xdot

filename = sys.argv[1]

pyew = CPyew(batch=True)
pyew.loadFile(filename, "rb")
pyew.offset = 0

#pyew.pe.header

for addr in pyew.basic_blocks.keys():
    print addr
Ejemplo n.º 11
0
def main(filename):
    pyew = CPyew()
    if os.getenv("PYEW_DEBUG"):
        pyew.debug=True
    else:
        pyew.debug = False

    pyew.loadFile(filename, "rb")

    if pyew.format in ["PE", "ELF"]:
        saveAndCompareInDatabase(pyew)

    pyew.offset = 0
    print pyew.hexdump(pyew.buf, pyew.hexcolumns)

    oldpyew = None
    cmd = ""
    last_cmd = ""
    pyew.previousoffset = []

    # Add global object's references for easier usage
    pe = pyew.pe
    elf = pyew.elf

    # Set AutoCompletion
    setupAutoCompletion(pyew)

    # Check if there is runme.py file
    if os.path.exists('runme.py'):
        f = open('runme.py', 'r')
        commands = f.readlines()
        f.close()

    while 1:
        try:
            last_cmd = cmd
            
            if len(pyew.previousoffset) > 0:
                if pyew.previousoffset[len(pyew.previousoffset)-1] != pyew.offset:
                    pyew.previousoffset.append(pyew.offset)
            else:
                pyew.previousoffset.append(pyew.offset)
            
            va = None
            if pyew.virtual:
                va = pyew.getVirtualAddressFromOffset(pyew.offset)
            
            if va:
                prompt = "[0x%08x:0x%08x]> " % (pyew.offset, va)
            else:
                prompt = "[0x%08x]> " % pyew.offset
            
            try:
                cmd = commands[0].rstrip()
                commands.pop(0)
            except:
                cmd = raw_input(prompt)
            
            if cmd in ["", "b"] and (last_cmd in ["b", "x", "c", "d", "dump", "hexdump", "dis", "pd", "p", "r", "buf"] or last_cmd.isdigit()):
                if cmd == "b":
                    tmp = pyew.previousoffset.pop()
                    
                    if len(pyew.previousoffset) > 0:
                        tmp = pyew.previousoffset[len(pyew.previousoffset)-1]
                    else:
                        tmp = 0
                        
                    pyew.offset = tmp
                    pyew.lastasmoffset = tmp
                    pyew.seek(tmp)
                    if last_cmd.isdigit():
                        last_cmd = "c"
                    
                elif cmd == "b" and last_cmd == "b":
                    if len(pyew.previousoffset) < 2:
                        continue
                    
                    tmp = pyew.previousoffset.pop()
                    tmp = pyew.previousoffset[len(pyew.previousoffset)-1]
                    pyew.seek(tmp)
                    continue
                elif last_cmd in ["c", "d", "pd"] or last_cmd.isdigit():
                    pyew.offset = pyew.lastasmoffset
                    pyew.seek(pyew.offset)
                    if last_cmd.isdigit():
                        last_cmd = "c"
                else:
                    pyew.offset = pyew.offset+pyew.bsize
                    pyew.seek(pyew.offset)
                cmd = last_cmd
        except EOFError:
            break
        except KeyboardInterrupt:
            break
        
        try:
            if cmd.strip(" ") == "":
                continue
            
            if cmd.lower() in ["exit", "quit", "q"]:
                break
            elif cmd.lower() in ["a", "anal"]:
                pyew.findFunctions(pyew.processor)
                print
            elif cmd.lower() in ["x", "dump", "hexdump"]:
                print pyew.hexdump(pyew.buf, pyew.hexcolumns, baseoffset=pyew.offset)
            elif cmd.split(" ")[0] in ["s", "seek"]:
                data = cmd.split(" ")
                if len(data) > 1:
                    if data[1].lower() in ["ep", "entrypoint"]:
                        if pyew.ep:
                            pyew.offset = pyew.ep
                    else:
                        pyew.names.has_key(data[1].lower())
                        
                        if data[1].lower()[0] in ["+", "-"]:
                            pyew.offset += int(data[1])
                        elif data[1].lower().startswith("0x"):
                            pyew.offset = int(data[1], 16)
                        elif data[1] in pyew.names.values():
                            for x in pyew.names:
                                if pyew.names[x] == data[1]:
                                    pyew.offset = x
                                    break
                        else:
                            pyew.offset = int(data[1])
                        
                pyew.seek(pyew.offset)
            elif cmd.lower().split(" ")[0] in ["c", "d", "dis", "pd"]:
                data = cmd.lower().split(" ")
                if len(data) > 1:
                    if not data[1].startswith("/"):
                        type = int(data[1])
                        dis = pyew.disassemble(pyew.buf, pyew.processor, pyew.type, pyew.lines, pyew.bsize, baseoffset=pyew.offset)
                        print dis
                    else:
                        cmd = data[1:]
                        if len(cmd) > 1:
                            ret = pyew.dosearch(pyew.f, cmd[0][1:2], cmd[1], cols=60, doprint=False, offset=pyew.offset)
                        else:
                            ret = pyew.dosearch(pyew.f, cmd[0][1:2], "", cols=60, doprint=False, offset=pyew.offset)
                        
                        for x in ret:
                            dis = pyew.disassemble(x.values()[0], pyew.processor, pyew.type, pyew.lines, pyew.bsize, baseoffset=x.keys()[0])
                            print dis
                else:
                    dis = pyew.disassemble(pyew.buf, pyew.processor, pyew.type, pyew.lines, pyew.bsize, baseoffset=pyew.offset)
                    print dis
            elif cmd.isdigit() and int(cmd) < len(pyew.calls)+1 and int(cmd) > 0:
                pyew.offset = pyew.calls[int(cmd)-1]
                pyew.seek(pyew.offset)
                dis = pyew.disassemble(pyew.buf, pyew.processor, pyew.type, pyew.lines, pyew.bsize, baseoffset=pyew.offset)
                print dis
            elif cmd == "buf":
                lines = 0
                line = ""
                for c in pyew.buf:
                    line += c
                    if len(line) == pyew.hexcolumns:
                        print repr(line)
                        line = ""
                
                if line != "":
                    print repr(line)
            elif cmd == "byte":
                lines = 0
                line = ""
                for c in pyew.buf:
                    line += "0x%x, " % ord(c)
                    if len(line) >= pyew.hexcolumns / (1.00/4.00):
                        print line
                        line = ""
                
                if line != "":
                    print "%s" % line
            elif cmd.lower().split(" ")[0] in ["r", "repr"]:
                print repr(pyew.buf)
            elif cmd.lower().split(" ")[0] in ["p"]:
                print pyew.buf
            elif cmd.lower() in ["settings", "options"]:
                pyew.showSettings()
            elif cmd.startswith("/"):
                ret = pyew.dosearch(pyew.f, cmd[1:2], cmd[3:], cols=60, offset=pyew.offset)
            elif cmd.lower() in ["?", "help"]:
                showHelp(pyew)
            elif cmd.lower() in ["imports"]:
                if pyew.format == "PE":
                    for entry in pyew.pe.DIRECTORY_ENTRY_IMPORT:
                        print entry.dll
                        for imp in entry.imports:
                            print '\t', hex(imp.address), imp.name
                elif pyew.format == "ELF":
                    for x in pyew.elf.relocs:
                        print x
            elif cmd.lower() in ["exports"]:
                if pyew.format == "PE":
                    for exp in pyew.pe.DIRECTORY_ENTRY_EXPORT.symbols:
                        print hex(pyew.pe.OPTIONAL_HEADER.ImageBase + exp.address), exp.name, exp.ordinal
                elif pyew.format == "ELF":
                    print "Not yet implemented"
            elif cmd.lower() in ["sections"]:
                if pyew.format == "PE":
                    for x in pyew.pe.sections:
                        print x
                elif pyew.format == "ELF":
                    for x in pyew.elf.secnames:
                        print pyew.elf.secnames[x]
            elif cmd.lower() in ["elf", "pe"]:
                if cmd.lower() == "elf":
                    print pyew.elf
                else:
                    print pyew.pe
            elif cmd.lower() == "g":
                if cmd == "g":
                    pyew.offset = 0
                else:
                    pyew.offset = pyew.maxsize - pyew.bsize
                    if pyew.offset < 0:
                        pyew.offset = pyew.maxsize - 32
                pyew.seek(pyew.offset)
            elif cmd in ["-", "+"]:
                if cmd == "+":
                    pyew.offset += pyew.bsize
                else:
                    pyew.offset -= pyew.bsize
                pyew.seek(pyew.offset)
            elif pyew.plugins.has_key(cmd.split(" ")[0]):
                plg = cmd.split(" ")
                if len(plg) == 1:
                    pyew.plugins[plg[0]](pyew)
                else:
                    pyew.plugins[plg[0]](pyew, plg[1:])
            elif cmd.lower().split(" ")[0] in ["md5", "sha1", "sha224", "sha256", "sha384", "sha512"]:
                func = eval(cmd)
                print "%s: %s" % (cmd, func(pyew.getBuffer()).hexdigest())
            elif cmd.startswith("!"):
                os.system(cmd[1:])
            elif cmd == "ret" and oldpyew is not None:
                pyew = oldpyew
                pyew.seek(pyew.offset)
                oldpyew = None
            elif cmd == "file":
                oldpyew = pyew
                del pyew
                pyew = CPyew()
                buf = oldpyew.getBytes(oldpyew.offset, oldpyew.maxsize)
                pyew.loadFromBuffer(buf, oldpyew.filename + "[embed]")
            elif cmd == "interact":
                code.interact(local=locals())
            elif cmd == "edit":
                pyew.f.close()
                pyew.f = open(filename, "r+wb")
                pyew.seek(0)
            elif cmd.split(" ")[0] in ["ls"]:
                data = cmd.split(" ")
                if len(data) == 2:
                    #print "parsing script file:", data[1]
                    f = open('scripts/' + data[1], 'r')
                    commands = f.readlines()
                    f.close()
                else:
                    scripts = os.listdir('scripts/')
                    print "Scripts available:"
                    for script in scripts:
                        print "\t", script
            elif cmd.split(" ")[0] in ["wx", "wa"]:
                if cmd.split(" ")[0] == "wx":
                    data = unhexlify(cmd.split(" ")[1])
                else:
                    data = cmd.split(" ")[1]
                
                pyew.f.seek(pyew.offset)
                pyew.f.write(data)
                pyew.seek(pyew.offset)
            else:
                if cmd.find("=") > -1 or cmd.startswith("print") or cmd.startswith("import "):
                    exec(cmd)
                else:
                    x = eval(cmd)
                    if "hexdigest" in dir(x):
                        print "%s: %s" % (cmd, x.hexdigest())
                    else:
                        pprint.pprint(x)
        except:
            print "Error:", sys.exc_info()[1]
            if pyew.debug:
                raise
Ejemplo n.º 12
0
# Configure some stuff...
wine = '/path/to/wine'
sigcheck = '/path/to/sigcheck.exe'
subfile = '/path/to/hachoir-subfile'
# These get passed to PEScanner
yrules = 'apt1.yara'
peid = 'userdb.txt'
clamscan_path = '/path/to/clamscan' 

# Sanity check just to make sure it's a legit PE file before trying to analyze
try:
    pe = pefile.PE(file)
except Exception, msg:
    print msg
    sys.exit() # will this exit everything if there's a directory being analyzed?
pyew = CPyew()

if args['verbose'] == True:
    verb = True
else:
    verb = False

def header(msg):
    return msg + "\n" + ("=" * 90)

def subTitle(msg):
    return "\n" + msg + "\n" + ("-" * 40)

def q(s):
        quote = "\""
        s = quote + s + quote