├── analyzer └── darwin │ ├── lib │ ├── macamal │ │ ├── __init__.py │ │ ├── common.py │ │ └── macamal.py │ ├── common │ │ ├── __init__.py │ │ ├── abstracts.py │ │ ├── rand.py │ │ ├── exceptions.py │ │ ├── hashing.py │ │ ├── config.py │ │ └── results.py │ ├── api │ │ ├── __init__.py │ │ └── screenshot.py │ └── core │ │ ├── constants.py │ │ ├── osx.py │ │ ├── filetimes.py │ │ ├── data │ │ └── types.yml │ │ └── packages.py │ ├── modules │ ├── auxiliary │ │ ├── agree.png │ │ ├── close.png │ │ ├── continue.jpg │ │ ├── continue.png │ │ ├── install.png │ │ ├── human2.py │ │ └── screenshots.py │ └── packages │ │ ├── bash.py │ │ ├── python.py │ │ ├── app.py │ │ ├── macho.py │ │ ├── doc.py │ │ ├── generic.py │ │ ├── perl.py │ │ ├── jar.py │ │ ├── dmg.py │ │ └── zip.py │ └── analyzer.py ├── modules ├── __init__.pyc ├── machinery │ ├── vmware.pyc │ ├── __init__.pyc │ ├── virtualbox.pyc │ ├── __init__.py │ ├── kvm.py │ └── esx.py ├── __init__.py ├── processing │ └── platform │ │ └── __init__.py └── auxiliary │ └── sniffer.py ├── web └── templates │ ├── standalone_error.html │ ├── analysis │ ├── behavior │ │ ├── index.html │ │ ├── _tree.html │ │ ├── _tree_process.html │ │ ├── _chunk.html │ │ ├── _search.html │ │ ├── _api_call.html │ │ ├── _search_results.html │ │ └── _processes.html │ ├── static │ │ ├── _strings.html │ │ ├── _irma.html │ │ ├── _pdf.html │ │ ├── index.html │ │ ├── _antivirus.html │ │ ├── _office.html │ │ └── _pe32.html │ ├── overview │ │ ├── _url.html │ │ ├── _screenshots.html │ │ ├── index.html │ │ ├── _file.html │ │ ├── _signatures.html │ │ └── _info.html │ ├── network │ │ ├── _irc.html │ │ ├── _icmp.html │ │ ├── _hosts.html │ │ ├── _snort.html │ │ ├── _udp.html │ │ ├── _http.html │ │ ├── _suricata.html │ │ ├── _dns.html │ │ ├── _tcp.html │ │ └── index.html │ ├── memory │ │ ├── _yarascan.html │ │ ├── _callbacks.html │ │ ├── _malfind.html │ │ ├── _apihooks.html │ │ ├── _devicetree.html │ │ ├── _modscan.html │ │ ├── _sockscan.html │ │ ├── _idt.html │ │ ├── _timers.html │ │ ├── _netscan.html │ │ ├── _ssdt.html │ │ ├── _pslist.html │ │ ├── _gdt.html │ │ ├── _messagehooks.html │ │ ├── _svcscan.html │ │ └── index.html │ ├── admin │ │ └── index.html │ ├── search.html │ ├── misp │ │ └── index.html │ ├── search_results.html │ ├── pending.html │ ├── procmemory │ │ └── index.html │ ├── import.html │ ├── buffers │ │ └── index.html │ ├── export.html │ ├── dropped │ │ └── index.html │ ├── report.html │ └── index.html │ ├── error.html │ ├── base.html │ ├── success.html │ ├── submission │ ├── reboot.html │ ├── complete.html │ └── status.html │ ├── footer.html │ ├── compare │ ├── hash.html │ ├── _summary_table.html │ ├── _info.html │ ├── left.html │ └── both.html │ ├── dashboard │ └── index.html │ └── header.html ├── LICENSE └── README.md /analyzer/darwin/lib/macamal/__init__.py: -------------------------------------------------------------------------------- 1 | #Pham -------------------------------------------------------------------------------- /modules/__init__.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phdphuc/mac-a-mal-cuckoo/HEAD/modules/__init__.pyc -------------------------------------------------------------------------------- /web/templates/standalone_error.html: -------------------------------------------------------------------------------- 1 |
ERROR :-(
{{error}}
2 | -------------------------------------------------------------------------------- /modules/machinery/vmware.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phdphuc/mac-a-mal-cuckoo/HEAD/modules/machinery/vmware.pyc -------------------------------------------------------------------------------- /modules/machinery/__init__.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phdphuc/mac-a-mal-cuckoo/HEAD/modules/machinery/__init__.pyc -------------------------------------------------------------------------------- /modules/machinery/virtualbox.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phdphuc/mac-a-mal-cuckoo/HEAD/modules/machinery/virtualbox.pyc -------------------------------------------------------------------------------- /analyzer/darwin/modules/auxiliary/agree.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phdphuc/mac-a-mal-cuckoo/HEAD/analyzer/darwin/modules/auxiliary/agree.png -------------------------------------------------------------------------------- /analyzer/darwin/modules/auxiliary/close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phdphuc/mac-a-mal-cuckoo/HEAD/analyzer/darwin/modules/auxiliary/close.png -------------------------------------------------------------------------------- /analyzer/darwin/modules/auxiliary/continue.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phdphuc/mac-a-mal-cuckoo/HEAD/analyzer/darwin/modules/auxiliary/continue.jpg -------------------------------------------------------------------------------- /analyzer/darwin/modules/auxiliary/continue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phdphuc/mac-a-mal-cuckoo/HEAD/analyzer/darwin/modules/auxiliary/continue.png -------------------------------------------------------------------------------- /analyzer/darwin/modules/auxiliary/install.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phdphuc/mac-a-mal-cuckoo/HEAD/analyzer/darwin/modules/auxiliary/install.png -------------------------------------------------------------------------------- /web/templates/analysis/behavior/index.html: -------------------------------------------------------------------------------- 1 | {% include "analysis/behavior/_tree.html" %} 2 |
3 | {% include "analysis/behavior/_processes.html" %} -------------------------------------------------------------------------------- /web/templates/error.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | {% load staticfiles %} 3 | {% block content %} 4 |
ERROR :-(
{{error}}
5 | {% endblock %} 6 | -------------------------------------------------------------------------------- /analyzer/darwin/lib/common/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2014-2016 Cuckoo Foundation. 2 | # This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org 3 | # See the file 'docs/LICENSE' for copying permission. 4 | -------------------------------------------------------------------------------- /modules/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2010-2013 Claudio Guarnieri. 2 | # Copyright (C) 2014-2016 Cuckoo Foundation. 3 | # This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org 4 | # See the file 'docs/LICENSE' for copying permission. 5 | -------------------------------------------------------------------------------- /web/templates/analysis/behavior/_tree.html: -------------------------------------------------------------------------------- 1 |

Process Tree

2 | 7 | -------------------------------------------------------------------------------- /modules/machinery/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2010-2013 Claudio Guarnieri. 2 | # Copyright (C) 2014-2016 Cuckoo Foundation. 3 | # This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org 4 | # See the file 'docs/LICENSE' for copying permission. 5 | -------------------------------------------------------------------------------- /analyzer/darwin/lib/api/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2010-2013 Claudio Guarnieri. 2 | # Copyright (C) 2014-2016 Cuckoo Foundation. 3 | # This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org 4 | # See the file 'docs/LICENSE' for copying permission. 5 | -------------------------------------------------------------------------------- /modules/processing/platform/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2010-2013 Claudio Guarnieri. 2 | # Copyright (C) 2014-2016 Cuckoo Foundation. 3 | # This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org 4 | # See the file 'docs/LICENSE' for copying permission. 5 | -------------------------------------------------------------------------------- /web/templates/analysis/static/_strings.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | {% for string in analysis.strings %} 4 |
{{string}}
5 | {% endfor %} 6 |
7 |
-------------------------------------------------------------------------------- /web/templates/base.html: -------------------------------------------------------------------------------- 1 | {%include "header.html" %} 2 |
3 | {% autoescape on %} 4 | {% block content %}{% endblock %} 5 | {% endautoescape %} 6 |
7 | {%include "footer.html" %} 8 | -------------------------------------------------------------------------------- /web/templates/success.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | {% load staticfiles %} 3 | {% block content %} 4 |

5 |
Great! :-)
{{message}}
6 | {% endblock %} 7 | -------------------------------------------------------------------------------- /web/templates/submission/reboot.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | {% load staticfiles %} 3 | {% block content %} 4 |

Reboot analysis successful!

5 | The following reboot analysis was added successfully: 6 | {{ baseurl }}{% url "submission.views.status" task_id %}
7 |
8 | {% endblock %} 9 | -------------------------------------------------------------------------------- /analyzer/darwin/lib/common/abstracts.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2010-2013 Claudio Guarnieri. 2 | # Copyright (C) 2014-2016 Cuckoo Foundation. 3 | # This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org 4 | # See the file 'docs/LICENSE' for copying permission. 5 | 6 | class Auxiliary(object): 7 | def __init__(self, options={}, analyzer=None): 8 | self.options = options 9 | self.analyzer = analyzer 10 | -------------------------------------------------------------------------------- /analyzer/darwin/lib/common/rand.py: -------------------------------------------------------------------------------- 1 | import random 2 | import string 3 | 4 | def random_string(minimum, maximum=None): 5 | if maximum is None: 6 | maximum = minimum 7 | 8 | count = random.randint(minimum, maximum) 9 | return "".join(random.choice(string.ascii_letters) for x in xrange(count)) 10 | 11 | def random_integer(digits): 12 | start = 10 ** (digits - 1) 13 | end = (10 ** digits) - 1 14 | return random.randint(start, end) 15 | -------------------------------------------------------------------------------- /analyzer/darwin/modules/packages/bash.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Copyright (C) 2015 Dmitry Rodionov 3 | # This software may be modified and distributed under the terms 4 | # of the MIT license. See the LICENSE file for details. 5 | 6 | from lib.core.packages import Package 7 | 8 | class Bash(Package): 9 | """ Bash shell script analysys package. """ 10 | 11 | def prepare(self): 12 | self.args = [self.target] + self.args 13 | self.target = "/bin/bash" 14 | -------------------------------------------------------------------------------- /analyzer/darwin/modules/packages/python.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Copyright (C) 2018 phdphuc 3 | # This software may be modified and distributed under the terms 4 | # of the MIT license. See the LICENSE file for details. 5 | 6 | from lib.core.packages import Package 7 | 8 | class Python(Package): 9 | """ Python script analysis package. """ 10 | 11 | def prepare(self): 12 | self.args = [self.target] + self.args 13 | self.target = "/usr/bin/python" 14 | -------------------------------------------------------------------------------- /analyzer/darwin/lib/common/exceptions.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2010-2013 Claudio Guarnieri. 2 | # Copyright (C) 2014-2016 Cuckoo Foundation. 3 | # This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org 4 | # See the file 'docs/LICENSE' for copying permission. 5 | 6 | class CuckooError(Exception): 7 | pass 8 | 9 | class CuckooPackageError(Exception): 10 | pass 11 | 12 | class CuckooDisableModule(CuckooError): 13 | """Exception for disabling a module dynamically.""" 14 | -------------------------------------------------------------------------------- /modules/machinery/kvm.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2010-2013 Claudio Guarnieri. 2 | # Copyright (C) 2014-2016 Cuckoo Foundation. 3 | # This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org 4 | # See the file 'docs/LICENSE' for copying permission. 5 | 6 | from lib.cuckoo.common.abstracts import LibVirtMachinery 7 | 8 | class KVM(LibVirtMachinery): 9 | """Virtualization layer for KVM based on python-libvirt.""" 10 | 11 | # Set KVM connection string. 12 | dsn = "qemu:///system" 13 | -------------------------------------------------------------------------------- /analyzer/darwin/modules/packages/app.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Copyright (C) 2018 phdphuc 3 | # This software may be modified and distributed under the terms 4 | # of the MIT license. See the LICENSE file for details. 5 | 6 | from os import system, path 7 | from lib.core.packages import Package 8 | from plistlib import readPlist 9 | 10 | 11 | class App(Package): 12 | """ OS X application analysis package. """ 13 | 14 | def prepare(self): 15 | system("/bin/chmod -R +x \"%s\"" % self.target) 16 | -------------------------------------------------------------------------------- /analyzer/darwin/modules/packages/macho.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Copyright (C) 2015 Dmitry Rodionov 3 | # This software may be modified and distributed under the terms 4 | # of the MIT license. See the LICENSE file for details. 5 | 6 | from os import system 7 | from lib.core.packages import Package 8 | 9 | class Macho(Package): 10 | """ Mach-O executable analysys package. """ 11 | 12 | def prepare(self): 13 | # Make sure that our target is executable 14 | system("/bin/chmod -R +x \"%s\"" % self.target) 15 | -------------------------------------------------------------------------------- /web/templates/analysis/overview/_url.html: -------------------------------------------------------------------------------- 1 |
2 |

URL Details

3 |
4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
URL
{{analysis.target.url}}
16 |
17 |
18 | -------------------------------------------------------------------------------- /analyzer/darwin/modules/packages/doc.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Copyright (C) 2018 phdphuc 3 | # This software may be modified and distributed under the terms 4 | # of the MIT license. See the LICENSE file for details. 5 | 6 | from os import system 7 | from lib.core.packages import Package 8 | 9 | class Doc(Package): 10 | """ Mach-O executable analysys package. """ 11 | 12 | def prepare(self): 13 | # Make sure that our target is executable 14 | # /usr/bin/open will handle it 15 | system("/bin/chmod +x \"%s\"" % self.target) 16 | -------------------------------------------------------------------------------- /analyzer/darwin/modules/packages/generic.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Copyright (C) 2018 phdphuc 3 | # This software may be modified and distributed under the terms 4 | # of the MIT license. See the LICENSE file for details. 5 | 6 | from os import system 7 | from lib.core.packages import Package 8 | 9 | class Generic(Package): 10 | """ Generic analysis package. """ 11 | 12 | def prepare(self): 13 | # Make sure that our target is executable 14 | # /usr/bin/open will handle it 15 | system("/bin/chmod +x \"%s\"" % self.target) 16 | -------------------------------------------------------------------------------- /analyzer/darwin/modules/packages/perl.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Copyright (C) 2018 phdphuc 3 | # This software may be modified and distributed under the terms 4 | # of the MIT license. See the LICENSE file for details. 5 | 6 | from os import system 7 | from lib.core.packages import Package 8 | 9 | class Perl(Package): 10 | """ Mach-O executable analysys package. """ 11 | 12 | def prepare(self): 13 | # Make sure that our target is executable 14 | # /usr/bin/open will handle it 15 | system("/bin/chmod +x \"%s\"" % self.target) 16 | -------------------------------------------------------------------------------- /web/templates/analysis/behavior/_tree_process.html: -------------------------------------------------------------------------------- 1 |
  • 2 | {{process.process_name}} ({{process.pid}}) 3 | {{ process.command_line }} 4 | {% if process.children %} 5 | 12 | {% endif %} 13 |
  • 14 | -------------------------------------------------------------------------------- /web/templates/submission/complete.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | {% load staticfiles %} 3 | {% block content %} 4 |

    Submission complete!

    5 | The following tasks were added successfully: 6 | {% for task in tasks %} 7 | {{task}} 8 | {% endfor %}. 9 |

    10 | Click on the links to monitor the status of the submission:
    11 | {% for task in tasks %} 12 | {{ baseurl }}{% url "submission.views.status" task %}
    13 | {% endfor %} 14 |
    15 | {% endblock %} 16 | -------------------------------------------------------------------------------- /analyzer/darwin/modules/packages/jar.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Copyright (C) 2018 phdphuc 3 | # This software may be modified and distributed under the terms 4 | # of the MIT license. See the LICENSE file for details. 5 | 6 | from lib.core.packages import Package 7 | 8 | class Jar(Package): 9 | """Java analysis package.""" 10 | 11 | def prepare(self): 12 | class_path = self.options.get("class") 13 | if class_path: 14 | args = ["-cp", self.target, class_path] 15 | else: 16 | args = ["-jar", self.target] 17 | self.args = args + self.args 18 | self.target = "/usr/bin/java" -------------------------------------------------------------------------------- /web/templates/analysis/network/_irc.html: -------------------------------------------------------------------------------- 1 |

    IRC traffic

    2 | {% if analysis.network.irc %} 3 | 4 | 5 | 6 | 7 | 8 | 9 | {% for irc in analysis.network.irc %} 10 | 11 | 12 | 13 | 14 | 15 | {% endfor %} 16 |
    CommandParamsType
    {{irc.command}}{{irc.params}}{{irc.type}}
    17 | {% else %} 18 |

    No IRC requests performed.

    19 | {% endif %} -------------------------------------------------------------------------------- /web/templates/analysis/overview/_screenshots.html: -------------------------------------------------------------------------------- 1 |
    2 |

    Screenshots

    3 | {% if analysis.shots %} 4 |
    5 | {% for shot in analysis.shots %} 6 | 7 | 8 | 9 | {% endfor %} 10 |
    11 | {% else %} 12 | No screenshots available. 13 | {% endif %} 14 |
    15 | -------------------------------------------------------------------------------- /web/templates/submission/status.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | {% load staticfiles %} 3 | {% block content %} 4 | 5 |
    6 |

    Hang on...

    7 |

    The analysis is not completed yet, it's still {{status}}. This page will refresh every 5 seconds.

    8 |
    9 |
    10 |
    11 |
    12 | {% endblock %} 13 | -------------------------------------------------------------------------------- /analyzer/darwin/lib/common/hashing.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2014-2016 Cuckoo Foundation. 2 | # This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org 3 | # See the file 'docs/LICENSE' for copying permission. 4 | 5 | BUFSIZE = 1024*1024 6 | 7 | 8 | def hash_file(method, path): 9 | """Calculates an hash on a file by path. 10 | @param method: callable hashing method 11 | @param path: file path 12 | @return: computed hash string 13 | """ 14 | f = open(path, "rb") 15 | h = method() 16 | while True: 17 | buf = f.read(BUFSIZE) 18 | if not buf: 19 | break 20 | h.update(buf) 21 | return h.hexdigest() 22 | -------------------------------------------------------------------------------- /web/templates/analysis/memory/_yarascan.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | {% for row in analysis.memory.yarascan.data|volsort %} 11 | 12 | 13 | 14 | 15 | 16 | {% endfor %} 17 | 18 |
    OwnerRuleHexdump
    {{row.owner}}{{row.rule}}
    {{row.hexdump}}
    19 | -------------------------------------------------------------------------------- /analyzer/darwin/lib/core/constants.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2014-2016 Cuckoo Foundation. 2 | # This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org 3 | # See the file 'docs/LICENSE' for copying permission. 4 | 5 | import os 6 | from tempfile import gettempdir 7 | from ..common.rand import random_string 8 | 9 | ROOT = os.path.join(gettempdir() + os.sep, random_string(6, 10)) 10 | 11 | PATHS = { 12 | "root" : ROOT, 13 | "logs" : os.path.join(ROOT, "logs"), 14 | "files" : os.path.join(ROOT, "files"), 15 | "shots" : os.path.join(ROOT, "shots"), 16 | "memory" : os.path.join(ROOT, "memory"), 17 | "drop" : os.path.join(ROOT, "drop") 18 | } 19 | -------------------------------------------------------------------------------- /web/templates/analysis/behavior/_chunk.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | {% for call in chunk.calls %} 14 | 15 | {% include "analysis/behavior/_api_call.html" %} 16 | 17 | {% endfor %} 18 | 19 |
    Time & APIArgumentsStatusReturnRepeatedUID
    20 | -------------------------------------------------------------------------------- /web/templates/analysis/admin/index.html: -------------------------------------------------------------------------------- 1 | {% load analysis_tags %} 2 |
    3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 |
    Task ID{{analysis.info.id}}
    Mongo ID{{analysis|mongo_id}}
    Cuckoo release{{analysis.info.version}}
    Delete
    21 |
    22 | -------------------------------------------------------------------------------- /web/templates/analysis/memory/_callbacks.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | {% for row in analysis.memory.callbacks.data|volsort %} 12 | 13 | 14 | 15 | 16 | 17 | 18 | {% endfor %} 19 | 20 |
    TypeCallbackModuleDetails
    {{row.type}}{{row.callback}}{{row.module}}{{row.details}}
    21 | -------------------------------------------------------------------------------- /web/templates/analysis/memory/_malfind.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | {% for row in analysis.memory.malfind.data|volsort %} 12 | 13 | 14 | 15 | 16 | 17 | 18 | {% endfor %} 19 | 20 |
    PIDProcess NameStartTag
    {{row.process_id}}{{row.process_name}}{{row.vad_start}}{{row.vad_tag}}
    21 | -------------------------------------------------------------------------------- /web/templates/analysis/network/_icmp.html: -------------------------------------------------------------------------------- 1 |

    ICMP traffic

    2 | {% if analysis.network.icmp %} 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | {% for packet in analysis.network.icmp %} 11 | 12 | 13 | 14 | 15 | 16 | 17 | {% endfor %} 18 |
    SourceDestinationICMP TypeData
    {{packet.src}}{{packet.dst}}{{packet.type}}{{packet.data}}
    19 | {% else %} 20 |

    No ICMP traffic performed.

    21 | {% endif %} -------------------------------------------------------------------------------- /analyzer/darwin/lib/core/osx.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Copyright (C) 2015 Dmitry Rodionov 3 | # This software may be modified and distributed under the terms 4 | # of the MIT license. See the LICENSE file for details. 5 | 6 | from os import system 7 | from datetime import datetime 8 | 9 | def set_wallclock(clock_str, **kwargs): 10 | clock = datetime.strptime(clock_str, "%Y%m%dT%H:%M:%S") 11 | # NOTE: On OS X there's `date` utility that accepts 12 | # new date/time as a string of the folowing format: 13 | # {month}{day}{hour}{minutes}{year}.{seconds} 14 | # where every {x} is a 2 digit number. 15 | cmd = "sudo date {0}".format(clock.strftime("%m%d%H%M%y.%S")) 16 | 17 | if "just_testing" in kwargs: 18 | return cmd 19 | else: 20 | system(cmd) 21 | -------------------------------------------------------------------------------- /web/templates/footer.html: -------------------------------------------------------------------------------- 1 | {% load staticfiles %} 2 | 4 | 9 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /web/templates/analysis/memory/_apihooks.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | {% for row in analysis.memory.apihooks.data|volsort %} 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | {% endfor %} 21 | 22 |
    PIDProcess NameVictim FunctionHook TypeHooking Module
    {{row.process_id}}{{row.process_name}}{{row.victim_function}}{{row.hook_type}}{{row.hooking_module}}
    23 | -------------------------------------------------------------------------------- /web/templates/analysis/memory/_devicetree.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | {% for row in analysis.memory.devicetree.data|volsort %} 11 | 12 | 13 | 14 | 21 | 22 | {% endfor %} 23 | 24 |
    Driver NameDriver OffsetDevices
    {{row.driver_name}}{{row.driver_offset}} 15 | {% for device in row.devices %} 16 | {% if device.device_name %} 17 | {{device.device_name}}, 18 | {% endif %} 19 | {% endfor %} 20 |
    25 | -------------------------------------------------------------------------------- /web/templates/analysis/memory/_modscan.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | {% for row in analysis.memory.modscan.data|volsort %} 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | {% endfor %} 21 | 22 |
    Base AddressOffsetNameFileSize
    {{row.kernel_module_base}}{{row.kernel_module_offset}}{{row.kernel_module_name}}{{row.kernel_module_file}}{{row.kernel_module_size}}
    23 | -------------------------------------------------------------------------------- /web/templates/analysis/memory/_sockscan.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | {% for row in analysis.memory.sockscan.data|volsort %} 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | {% endfor %} 23 | 24 |
    OffsetPIDLocal AddressLocal PortProtocolCreation Time
    {{row.offset}}{{row.process_id}}{{row.address}}{{row.port}}{{row.protocol}}{{row.create_time}}
    25 | -------------------------------------------------------------------------------- /web/templates/analysis/memory/_idt.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | {% for row in analysis.memory.idt.data|volsort %} 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | {% endfor %} 23 | 24 |
    CPUIndexSelectorAddressModuleSection
    {{row.cpu_number}}{{row.index}}{{row.selector}}{{row.address}}{{row.module}}{{row.section}}
    25 | -------------------------------------------------------------------------------- /web/templates/analysis/memory/_timers.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | {% for row in analysis.memory.timers.data|volsort %} 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | {% endfor %} 23 | 24 |
    OffsetDue TimePeriodSignaledRoutineModule
    {{row.offset}}{{row.due_time}}{{row.period}}{{row.signaled}}{{row.routine}}{{row.module}}
    25 | -------------------------------------------------------------------------------- /web/templates/analysis/behavior/_search.html: -------------------------------------------------------------------------------- 1 | 15 | 16 | 29 | -------------------------------------------------------------------------------- /web/templates/compare/hash.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | {% load staticfiles %} 3 | {% block content %} 4 |

    5 | 6 |
    7 |
    8 |

    Analysis 1

    9 | 10 | {% include "compare/_info.html" with record=left %} 11 |
    12 |
    13 |

    Analysis 2

    14 | 15 |

    You need to select the second analysis.

    16 | {% if records.count > 0 %} 17 |

    Following are all the analyses of the file with provided MD5 or pattern {{hash}}:

    18 | {% include "compare/_summary_table.html" %} 19 | {% else %} 20 |

    There is no analysis for the specified file or you selected the same selected analysis.

    21 | {% endif %} 22 |
    23 |
    24 | {% endblock %} 25 | -------------------------------------------------------------------------------- /web/templates/analysis/network/_hosts.html: -------------------------------------------------------------------------------- 1 |
    2 |

    Hosts

    3 | {% if analysis.network.hosts %} 4 | 5 | 6 | 7 | 8 | {% for host in analysis.network.hosts %} 9 | 10 | {% if host|slice:":7" != "192.168" and ":" not in host %} 11 | 19 | {% endif %} 20 | 21 | {% endfor %} 22 |
    IP
    12 | 13 | {{ host }} 14 | {% if host|isdeadip:analysis %} 15 | (dead IP/port - was unable to connect during analysis) 16 | {% endif %} 17 | 18 |
    23 | {% else %} 24 |

    No hosts contacted.

    25 | {% endif %} 26 |
    27 | -------------------------------------------------------------------------------- /web/templates/analysis/memory/_netscan.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | {% for row in analysis.memory.netscan.data|volsort %} 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | {% endfor %} 25 | 26 |
    OffsetPIDLocal AddressLocal PortRemote AddressRemote PortProtocol
    {{row.offset}}{{row.process_id}}{{row.local_address}}{{row.local_port}}{{row.remote_address}}{{row.remote_port}}{{row.protocol}}
    27 | -------------------------------------------------------------------------------- /analyzer/darwin/lib/macamal/common.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Copyright (C) 2015 Dmitry Rodionov 3 | # This software may be modified and distributed under the terms 4 | # of the MIT license. See the LICENSE file for details. 5 | 6 | from os import path 7 | from time import sleep 8 | 9 | def sanitize_path(raw_path): 10 | """ Replace spaces with backslashes+spaces """ 11 | return raw_path.replace(" ", "\\ ") 12 | 13 | def path_for_script(script): 14 | """ Return the full path for the given script """ 15 | return path.join(current_directory(), script) 16 | 17 | def current_directory(): 18 | return path.dirname(path.abspath(__file__)) 19 | 20 | def filelines(source_file): 21 | """ A generator that returns lines of the file. 22 | If there're no new lines it waits until the file is updated. 23 | """ 24 | # Go to the end of the file 25 | source_file.seek(0, 2) 26 | while True: 27 | line = source_file.readline() 28 | if not line: 29 | # Sleep briefly 30 | sleep(0.1) 31 | continue 32 | yield line 33 | -------------------------------------------------------------------------------- /web/templates/compare/_summary_table.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | {% for record in records %} 14 | 15 | 16 | {% if record.target.category == "url" %} 17 | 18 | {% else %} 19 | 20 | {% endif %} 21 | 22 | 23 | 24 | 25 | 26 | {% endfor %} 27 | 28 |
    IDTargetMachineCompleted OnDurationSelect
    {{record.info.id}}{{record.target.url}}{{record.target.file.name}}{{record.info.machine.name}}{{record.info.ended}}{{record.info.duration}} secondsSelect
    -------------------------------------------------------------------------------- /web/templates/analysis/network/_snort.html: -------------------------------------------------------------------------------- 1 |

    Snort Alerts

    2 | {% if analysis.snort.alerts %} 3 | 4 | 5 | 6 | 7 | 8 | 9 | {% for alert in analysis.snort.alerts %} 10 | 11 | 16 | 17 | 18 | 19 | {% endfor %} 20 |
    FlowSIDMessage
    12 | {{alert.protocol}} 13 | {{alert.src_ip}}{% if alert.src_port %}:{{alert.src_port}}{% endif %} -> 14 | {{alert.dst_ip}}{% if alert.dst_port %}:{{alert.dst_port}}{% endif %} 15 | {{alert.sid}}{{alert.message}}
    21 | {% else %} 22 |

    No Snort Alerts

    23 | {% endif %} 24 | -------------------------------------------------------------------------------- /web/templates/analysis/static/_irma.html: -------------------------------------------------------------------------------- 1 |
    2 | {% if analysis.irma and analysis.irma.status %} 3 | 4 | 5 | 6 | {% if analysis.info.category == "file" %} 7 | 8 | {% else %} 9 | 10 | {% endif %} 11 | 12 | {% for probe in analysis.irma.probe_results %} 13 | 14 | 15 | 24 | 25 | {% endfor %} 26 |
    AntivirusSignatureResult
    {{probe.name}} 16 | {% if analysis.info.category == "file" %} 17 | {% if not probe.results %} 18 | Clean 19 | {% else %} 20 | {{probe.results}} 21 | {% endif %} 22 | {% endif %} 23 |
    27 | {% else %} 28 | No antivirus signatures available. 29 | {% endif %} 30 |
    -------------------------------------------------------------------------------- /web/templates/analysis/memory/_ssdt.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | {% for row in analysis.memory.ssdt.data|volsort %} 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | {% endfor %} 25 | 26 |
    IndexTableEntrySyscall NameSyscall AddrSyscall ModnameHook?
    {{row.index}}{{row.table}}{{row.entry}}{{row.syscall_name}}{{row.syscall_addr}}{{row.syscall_modname}}{{row.hook_dest_addr}}: {{row.hook_name}}
    27 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 phdphuc 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /web/templates/analysis/memory/_pslist.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | {% for row in analysis.memory.pslist.data|volsort %} 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | {% endfor %} 27 | 28 |
    Parent PIDPIDNameCreate TimeExit Time# Threads# HandlesSession ID
    {{row.parent_id}}{{row.process_id}}{{row.process_name}}{{row.create_time}}{{row.exit_time}}{{row.num_threads}}{{row.num_handles}}{{row.session_id}}
    29 | -------------------------------------------------------------------------------- /web/templates/analysis/memory/_gdt.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | {% for row in analysis.memory.gdt.data|volsort %} 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | {% endfor %} 27 | 28 |
    CPUSelectorBaseLimitTypeDplGranularityPresent
    {{row.cpu_number}}{{row.selector}}{{row.base}}{{row.limit}}{{row.type}}{{row.dpl}}{{row.granularity}}{{row.present}}
    29 | -------------------------------------------------------------------------------- /web/templates/analysis/memory/_messagehooks.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | {% for row in analysis.memory.messagehooks.data|volsort %} 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | {% endfor %} 27 | 28 |
    OffsetSessionDesktopThreadFilterFlagsFunctionModule
    {{row.offset}}{{row.session}}{{row.desktop}}{{row.thread}}{{row.filter}}{{row.flags}}{{row.function}}{{row.module}}
    29 | -------------------------------------------------------------------------------- /web/templates/analysis/memory/_svcscan.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | {% for row in analysis.memory.svcscan.data|volsort %} 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | {% endfor %} 27 | 28 |
    NameDisplay NameBinary PathPIDTypeOrderOffsetState
    {{row.service_name}}{{row.service_display_name}}{{row.service_binary_path}}{{row.process_id}}{{row.service_type}}{{row.service_order}}{{row.service_offset}}{{row.service_state}}
    29 | -------------------------------------------------------------------------------- /web/templates/compare/_info.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | {% if record.target.category == "url" %} 7 | 8 | {% else %} 9 | 10 | 11 | {% endif %} 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | {% if record.target.category == "url" %} 22 | 23 | {% else %} 24 | 25 | 26 | {% endif %} 27 | 28 | 29 | 30 | 31 | 32 |
    IDCategoryURLNameMD5MachineCompleted OnDuration
    {{record.info.id}}{{record.info.category|upper}}{{record.target.url}}{{record.target.file.name}}{{record.target.file.md5}}{{record.info.machine.name}}{{record.info.ended}}{{record.info.duration}} seconds
    33 | -------------------------------------------------------------------------------- /web/templates/analysis/network/_udp.html: -------------------------------------------------------------------------------- 1 | {% load staticfiles %} 2 | {% load analysis_tags %} 3 | 4 |
    5 |

    UDP

    6 | {% if analysis.network.udp %} 7 |
    8 |
    9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | {% for p in analysis.network.udp %} 17 | 18 | 19 | 20 | 21 | 22 | 23 | {% endfor %} 24 |
    SourceSource PortDestinationDestination Port
    {{p.src}}{{p.sport}}{{p.dst}} {{ iplookups|get_item:p.dst }}{{p.dport}}
    25 |
    26 |
    27 |
    28 | {% else %} 29 |

    No UDP connections recorded.

    30 | {% endif %} 31 |
    32 | -------------------------------------------------------------------------------- /web/templates/analysis/search.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | {% load staticfiles %} 3 | {% block content %} 4 |
    5 |
    6 |
    {% csrf_token %} 7 |

    For details on how to perform searches, get some help.

    8 | 9 |
    10 | 11 | 12 |
    13 | 14 |
    15 |
    16 |
    17 |
    18 | {% include "analysis/search_results.html" %} 19 |
    20 | 21 | 31 | {% endblock %} 32 | -------------------------------------------------------------------------------- /web/templates/dashboard/index.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | {% load staticfiles %} 3 | {% block content %} 4 |
    5 | Estimating ~{{report.estimate_hour}} analysis per hour, {{report.estimate_day}} per day. 6 |
    7 | 8 |
    9 |
    10 |
    11 |

    {{report.total_tasks}}

    12 | Total tasks 13 |
    14 |
    15 |
    16 |
    17 |

    {{report.total_samples}}

    18 | Total samples 19 |
    20 |
    21 |
    22 | 23 |
    24 |
    25 |

    States

    26 |
    27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | {% for state, count in report.states_count.items %} 36 | 37 | 38 | 39 | 40 | {% endfor %} 41 | 42 |
    StateCount
    {{state}}{{count}}
    43 |
    44 | {% endblock %} 45 | -------------------------------------------------------------------------------- /web/templates/analysis/static/_pdf.html: -------------------------------------------------------------------------------- 1 |
    2 | {% for js in analysis.static.pdf %} 3 | {% if js.javascript %} 4 | {% for code in js.javascript %} 5 |
    6 |
    7 |
    8 |
    9 |
    10 | 11 |
    12 | 13 |
    14 |
    15 |
    16 |
    17 |                                                 {{ code.orig_code }}
    18 |                                             
    19 |
    20 |
    21 |
    22 | 23 |
    24 |
    25 |
    26 |
    27 | {% endfor %} 28 | {% endif %} 29 | {% endfor %} 30 |
    31 | -------------------------------------------------------------------------------- /web/templates/compare/left.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | {% load staticfiles %} 3 | {% block content %} 4 |

    5 | 6 | 17 | 18 |
    19 |
    20 |

    Analysis 1

    21 | 22 | {% include "compare/_info.html" with record=left %} 23 |
    24 |
    25 |

    Analysis 2

    26 | 27 |

    You need to select the second analysis.

    28 | {% if records.count > 0 %} 29 |

    Following are all the other analyses of the same file or URL:

    30 | {% include "compare/_summary_table.html" %} 31 | {% else %} 32 |

    There is no other analysis for the same file or URL.

    33 | {% endif %} 34 | 35 |

    If you want to compare to a different analysis, please provide an MD5 hash or a URL:

    36 |
    37 | 38 |
    39 |
    40 |
    41 | {% endblock %} 42 | -------------------------------------------------------------------------------- /web/templates/analysis/static/index.html: -------------------------------------------------------------------------------- 1 |
    2 | 8 |
    9 |
    10 | {% if "PE32" in analysis.target.file.type %} 11 | {% include "analysis/static/_pe32.html" %} 12 | {% elif "Mach-O" in analysis.target.file.type %} 13 | {% include "analysis/static/_macho.html" %} 14 | {% elif "office" in analysis.static %} 15 | {% include "analysis/static/_office.html" %} 16 | {% elif "pdf" in analysis.static %} 17 | {% include "analysis/static/_pdf.html" %} 18 | {% else %} 19 | No static analysis available. 20 | {% endif %} 21 |
    22 |
    23 | {% include "analysis/static/_strings.html" %} 24 |
    25 |
    26 | {% include "analysis/static/_antivirus.html" %} 27 |
    28 |
    29 | {% include "analysis/static/_irma.html" %} 30 |
    31 |
    32 |
    33 | -------------------------------------------------------------------------------- /web/templates/analysis/misp/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | {% for event in analysis.misp %} 11 | 12 | 17 | 18 | 23 | 24 | 39 | 40 | {% endfor %} 41 | 42 |
    Event IDDateIOCsDescriptionLevel
    13 | {% if event.event_id != None %} 14 | {{event.event_id}} 15 | {% endif %} 16 | {{event.date}} 19 | {% for ioc in event.iocs %} 20 |
    {{ioc}}
    21 | {% endfor %} 22 |
    {{event.info}} 25 | {% if event.level %} 26 |

    27 | {% if event.level == "4" %} 28 | 4 29 | {% elif event.level == "3" %} 30 | 3 31 | {% elif event.level == "2" %} 32 | 2 33 | {% elif event.level == "1" %} 34 | 1 35 | {% endif %} 36 |

    37 | {% endif %} 38 |
    43 | -------------------------------------------------------------------------------- /web/templates/analysis/static/_antivirus.html: -------------------------------------------------------------------------------- 1 |
    2 | {% if analysis.virustotal and analysis.virustotal.response_code %} 3 | 4 | 5 | 6 | {% if analysis.info.category == "file" %} 7 | 8 | {% else %} 9 | 10 | {% endif %} 11 | 12 | {% for av, values in analysis.virustotal.scans.items %} 13 | 14 | 15 | 32 | 33 | {% endfor %} 34 |
    AntivirusSignatureResult
    {{av}} 16 | {% if analysis.info.category == "file" %} 17 | {% if not values.result %} 18 | Clean 19 | {% else %} 20 | {{values.result}} 21 | {% endif %} 22 | {% else %} 23 | {% if not values.detected %} 24 | 25 | {% else %} 26 | 27 | {% endif %} 28 | {{ values.result|title }} 29 | 30 | {% endif %} 31 |
    35 | {% else %} 36 | {% if analysis.virustotal.summary.permalink %} 37 | Your file is being analysed 38 | {% else %} 39 | No antivirus signatures available. 40 | {% endif %} 41 | {% endif %} 42 |
    43 | -------------------------------------------------------------------------------- /web/templates/analysis/static/_office.html: -------------------------------------------------------------------------------- 1 |
    2 | {% for office in analysis.static.office.macros %} 3 |
    4 |
    5 |
    6 |
    7 |
    8 | 9 |
    10 | 11 |
    12 |
    13 |
    14 |

    Original

    15 |
    16 |
    17 |                                         {{ office.orig_code.strip }}
    18 |                                     
    19 |
    20 | 21 | 22 |
    23 |

    Deobfuscated

    24 |
    25 |
    26 |                                         {{ office.deobf.strip }}
    27 |                                     
    28 |
    29 |
    30 |
    31 | 32 |
    33 |
    34 |
    35 |
    36 | {% endfor %} 37 |
    38 | -------------------------------------------------------------------------------- /web/templates/analysis/network/_http.html: -------------------------------------------------------------------------------- 1 | 8 | 9 |

    HTTP & HTTPS Requests

    10 | {% if analysis.network.http_ex or analysis.network.https_ex %} 11 | 12 | 13 | 14 | 15 | 16 | {% for http in analysis.network.http_ex %} 17 | 18 | 22 | 25 | 26 | {% endfor %} 27 | {% for http in analysis.network.https_ex %} 28 | 29 | 33 | 36 | 37 | {% endfor %} 38 |
    RequestResponse
    19 |
    URL: http://{{http.host}}{{http.uri}}
    20 |
    {{http.request}}
    21 |
    23 |
    {{http.response}}
    24 |
    30 |
    URL: https://{{http.host}}{{http.uri}}
    31 |
    {{http.request}}
    32 |
    34 |
    {{http.response}}
    35 |
    39 | {% elif analysis.network.http %} 40 | 41 | 42 | 43 | 44 | 45 | {% for request in analysis.network.http %} 46 | 47 | 48 | 49 | 50 | {% endfor %} 51 |
    URIData
    {{request.uri}}
    {{request.data}}
    52 | {% else %} 53 |

    No HTTP requests performed.

    54 | {% endif %} 55 | -------------------------------------------------------------------------------- /web/templates/analysis/behavior/_api_call.html: -------------------------------------------------------------------------------- 1 | {% load analysis_tags %} 2 | 3 | {{call.time}}
    4 | {{call.api}} 5 | {% if pid %} 6 |
    7 | 8 | 9 | 10 | {% endif %} 11 | 12 | 13 | {% for key, value in call.arguments.items %} 14 | {% if value|is_dict %} 15 | {% for k, v in value.items %} 16 | {{key}}.{{k}}: 17 | {{v}} 18 |
    19 | {% endfor %} 20 | {% else %} 21 | {{key}}: 22 | {% if key in call.raw %} 23 | {% for v in value|ensurelist %} 24 |
    {{v}}
    25 | {% endfor %} 26 | {% else %} 27 | {% for v in value|ensurelist %} 28 | {{v}} 29 | {% endfor %} 30 | {% endif %} 31 | {% if key in call.flags %} 32 | ({{ call.flags|get_item:key|ensurelist|join:", " }}) 33 | {% endif %} 34 |
    35 | {% endif %} 36 | {% endfor %} 37 | 38 | 39 | {% if call.status %} 40 | success 41 | {% else %} 42 | failed 43 | {% endif %} 44 | 45 | {{call.return_value}} 46 | 47 | {% if call.repeated %} 48 | {{call.repeated}} 49 | {% if call.repeated > 1 %} 50 | times 51 | {% else %} 52 | time 53 | {% endif %} 54 | {% else %} 55 | 0 56 | {% endif %} 57 | 58 | {{call.uid}} -------------------------------------------------------------------------------- /web/templates/analysis/search_results.html: -------------------------------------------------------------------------------- 1 | {% if term %} 2 |

    Term {{ term }}

    3 | {% endif %} 4 | {% if analyses %} 5 |
    6 |
    7 |

    Search Results

    8 |
    9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | {% for analysis in analyses %} 18 | 19 | 20 | 31 | 32 | {% endfor %} 33 | 34 |
    Task IDMatches
    Analysis #{{ analysis.task_id }} 21 | 22 | {% for key, value in analysis.matches %} 23 | 24 | 25 | 26 | 27 | {% endfor %} 28 |
    {{ key }}:{{ value }}
    29 | {% if analysis.total %}
    ({{ analysis.total }} more matches)
    {% endif %} 30 |
    35 |
    36 | {% elif analyses != None %} 37 |
    No results found.
    38 | {% else %} 39 | {% if error %} 40 |
    {{ error }}
    41 | {% endif %} 42 | {% endif %} 43 | -------------------------------------------------------------------------------- /web/templates/analysis/pending.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | {% load staticfiles %} 3 | {% block content %} 4 |
    5 |
    6 |

    Pending Tasks

    7 |
    8 | {% if tasks %} 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | {% for task in tasks %} 20 | 21 | 28 | 29 | 30 | 43 | 44 | {% endfor %} 45 | 46 |
    TimestampCategoryTargetStatus
    22 | {% if task.status == "reported" %} 23 | {{task.completed_on}} 24 | {% else %} 25 | {{task.added_on}} (added on) 26 | {% endif %} 27 | {{task.category}}{{task.target}} 31 | {% if task.status == "pending" %} 32 | pending 33 | {% elif task.status == "running" %} 34 | running 35 | {% elif task.status == "completed" %} 36 | completed 37 | {% elif task.status == "reported" %} 38 | reported 39 | {% else %} 40 | {{task.status}} 41 | {% endif %} 42 |
    47 | {% else %} 48 |
    No pending tasks.
    49 | {% endif %} 50 |
    51 | {% endblock %} 52 | -------------------------------------------------------------------------------- /web/templates/analysis/behavior/_search_results.html: -------------------------------------------------------------------------------- 1 | 2 | 8 |
    9 |

    Results

    10 |

    11 | network 12 | filesystem 13 | registry 14 | process 15 | services 16 | synchronization 17 |

    18 | {% if results %} 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | {% for match in results %} 32 | 33 | 36 | 37 | {% for sign in match.signs %} 38 | 39 | {% include "analysis/behavior/_api_call.html" with call=sign pid=match.process.pid cid=sign.id %} 40 | 41 | {% endfor %} 42 | {% endfor %} 43 | 44 |
    Time & APIArgumentsStatusReturnRepeatedUID
    34 | Process: {{match.process.process_name}} ({{match.process.pid}}) 35 |
    45 | {% else %} 46 |

    No results

    47 | {% endif %} 48 |
    49 | -------------------------------------------------------------------------------- /web/templates/analysis/network/_suricata.html: -------------------------------------------------------------------------------- 1 |

    Suricata Alerts

    2 | {% if analysis.suricata.alerts %} 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | {% for alert in analysis.suricata.alerts %} 11 | 12 | 17 | 18 | 19 | 20 | 21 | {% endfor %} 22 |
    FlowSIDSignatureCategory
    13 | {{alert.protocol}} 14 | {{alert.src_ip}}:{{alert.src_port}} -> 15 | {{alert.dst_ip}}:{{alert.dst_port}} 16 | {{alert.sid}}{{alert.signature}}{{alert.category}}
    23 | {% else %} 24 |

    No Suricata Alerts

    25 | {% endif %} 26 | 27 |

    Suricata TLS

    28 | {% if analysis.suricata.tls %} 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | {% for tls in analysis.suricata.tls %} 37 | 38 | 43 | 44 | 45 | 46 | 47 | {% endfor %} 48 |
    FlowIssuerSubjectFingerprint
    39 | {{tls.version}}
    40 | {{tls.src_ip}}:{{tls.src_port}}
    41 | {{tls.dst_ip}}:{{tls.dst_port}} 42 |
    {{tls.issuer}}{{tls.subject}}{{tls.fingerprint}}
    49 | 50 | {% else %} 51 |

    No Suricata TLS

    52 | {% endif %} 53 | -------------------------------------------------------------------------------- /analyzer/darwin/modules/auxiliary/human2.py: -------------------------------------------------------------------------------- 1 | # It's possible to use Quartz library only instead of using pyautogui (https://github.com/asweigart/pyautogui/blob/319d401bcec7341263e5c16acb6651534332d9a9/pyautogui/_pyautogui_osx.py) 2 | # Pham 3 | 4 | import random 5 | import logging 6 | import time 7 | from threading import Thread 8 | import Quartz.CoreGraphics as CG 9 | from Quartz import kCGWindowListOptionOnScreenOnly, kCGNullWindowID, CGWindowListCopyWindowInfo, CGEventCreateMouseEvent, kCGEventMouseMoved 10 | from AppKit import * 11 | import pyautogui 12 | 13 | workspace = NSWorkspace.sharedWorkspace() 14 | rect = NSScreen.mainScreen().frame() 15 | width = int(rect.size.width) 16 | 17 | def click_mouse(x,y): 18 | #create the event 19 | move = CG.CGEventCreateMouseEvent(None, CG.kCGEventMouseMoved, (x, y), 0) 20 | #send the event 21 | CG.CGEventPost(CG.kCGHIDEventTap, move) 22 | # Mouse down. 23 | down = CG.CGEventCreateMouseEvent(None, CG.kCGEventLeftMouseDown, (x, y), CG.kCGMouseButtonLeft) 24 | # Mouse up. 25 | up = CG.CGEventCreateMouseEvent(None, CG.kCGEventLeftMouseUp, (x, y), CG.kCGMouseButtonLeft) 26 | #send the events 27 | CG.CGEventPost(CG.kCGHIDEventTap, down) 28 | time.sleep(0.05) 29 | CG.CGEventPost(CG.kCGHIDEventTap, up) 30 | 31 | while True: 32 | activeApps = workspace.runningApplications() 33 | for app in activeApps: 34 | options = kCGWindowListOptionOnScreenOnly 35 | windowList = CGWindowListCopyWindowInfo(options, kCGNullWindowID) 36 | for window in windowList: 37 | if window['kCGWindowOwnerName'] == "SecurityAgent": 38 | pyautogui.typewrite('123456\n', interval=0.05) # Enter admin password then enter, TODO: use cuckoo admin password option 39 | break 40 | break 41 | buttons = ['continue.png', 'agree.png', 'install.png', 'close.png'] 42 | for button in buttons: 43 | try: 44 | buttonx,buttony = pyautogui.locateCenterOnScreen(button, grayscale=True) 45 | print "Detected defined button at: ", buttonx/2, buttony/2 #Assume we're under Retina monitor 46 | click_mouse(buttonx/2, buttony/2) 47 | except TypeError: 48 | continue 49 | time.sleep(1) -------------------------------------------------------------------------------- /web/templates/analysis/procmemory/index.html: -------------------------------------------------------------------------------- 1 | {% if analysis.procmemory %} 2 | {% for proc in analysis.procmemory %} 3 |
    4 |

    Process memory dump for {{ proc.pid|process_name:analysis }} (PID {{ proc.pid }}, dump {{ proc.num }})

    5 |
    6 | {% if proc.procmem_id %} 7 | Download 8 | {% endif %} 9 | 10 | {% if proc.extracted %} 11 | Extracted/injected images (may contain unpacked executables) 12 | 19 | {% endif %} 20 | 21 | {% if proc.yara %} 22 | Yara signatures matches on process memory 23 | {% for match in proc.yara %} 24 |

    Match: {{match.name}} 25 |

    30 | {% endfor %} 31 | {% endif %} 32 | 33 | {% if proc.urls %} 34 | URLs found in process memory 35 | 40 | {% endif %} 41 | 42 | {% if proc.procmem_id %} 43 | Download 44 | {% endif %} 45 |
    46 |
    47 | {% endfor %} 48 | {% endif %} 49 | -------------------------------------------------------------------------------- /web/templates/header.html: -------------------------------------------------------------------------------- 1 | {% load staticfiles %} 2 | 3 | 4 | 5 | 6 | Cuckoo Sandbox 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
    19 | 40 |
    41 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | This analyzer extends the open-source Cuckoo Sandbox (legacy) with functionality for analyzing macOS malware in macOS guest VM(s). 2 | 3 | 4 | See [Mac-A-Mal](https://github.com/phdphuc/mac-a-mal) for kernel monitor module on guest machine. 5 | 6 | 7 | ## Installation 8 | ### Host setup 9 | 10 | 1. Clone the [cuckoo-legacy branch](https://github.com/cuckoosandbox/cuckoo.git) 11 | 12 | 2. Run the following command to install the requirements packages: 13 | 14 | sudo pip install -r requirements.txt 15 | 16 | 3. Clone [Mac-a-mal-cuckoo](https://github.com/phdphuc/mac-a-mal-cuckoo.git) 17 | 18 | 5. Replace subfolders in cuckoo-legacy with mac-a-mal-cuckoo's subfolders. 19 | 20 | 6. Setting up VMWare/VirtualBox configuration in `conf/` folder. 21 | 22 | 6. Start cuckoo 23 | `python ./cuckoo.py` 24 | 25 | 7. Skip to guest setup and return to this step after you've done with Guest virtual machine installation. Submit samples with sample's path and optional options: **runas** _username_ instead of _root_, **gctimeout** timeout for kernel-mode macamal monitor, and **timeout** for total analysis time. 26 | `python submit.py --platform darwin sample -o runas=admin,gctimeout=60 --timeout=600` 27 | ## Guest setup 28 | 29 | macOS versions supported 10.6, 10.7, 10.8, 10.9, 10.10, 10.11, 10.12, and 10.13 (untested) 30 | 31 | 1. Guest machine can be setup manually using VMWare or VirtualBox. ([OSX 10.8](https://drive.google.com/file/d/0BxBVjisqLRIrSTRySWJJUUlRZm8/view) - password: summer) 32 | [Documentation]( https://github.com/rodionovd/cuckoo-osx-analyzer/wiki/Setting-up-the-environment ) for setting up the environment. 33 | 2. Download the Mac-a-mal for [guest machine monitor](https://github.com/phdphuc/mac-a-mal), compile 2 binaries using Xcode: mac-a-mal.kext and grey-cuckoo. The agent in user-mode requires libevent for multithreading. 34 | 3. Install dependencies: 35 | ``` 36 | sudo pip install pymongo 37 | brew install libtiff libjpeg webp little-cms2 38 | pip install Pillow 39 | ``` 40 | 4. Start the monitor and agent in super-user privilege is recommended. 41 | 42 | ``` homebrew libevent && 43 | sudo chown -R root:wheel mac-a-mal.kext && 44 | sudo kextload mac-a-mal.kext && 45 | cp grey-cuckoo /tmp/&& 46 | sudo chown root:wheel /tmp/grey-cuckoo && 47 | sudo python ./agent.py 48 | ``` 49 | 50 | 5. Take the snapshot of the guest machine 51 | 52 | ## Credits 53 | 54 | [Sfylabs](http://sfylabs.com) 55 | -------------------------------------------------------------------------------- /analyzer/darwin/lib/core/filetimes.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2009, David Buxton 2 | # All rights reserved. 3 | # 4 | # Redistribution and use in source and binary forms, with or without 5 | # modification, are permitted provided that the following conditions are 6 | # met: 7 | # 8 | # * Redistributions of source code must retain the above copyright 9 | # notice, this list of conditions and the following disclaimer. 10 | # * Redistributions in binary form must reproduce the above copyright 11 | # notice, this list of conditions and the following disclaimer in the 12 | # documentation and/or other materials provided with the distribution. 13 | # 14 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 15 | # IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 16 | # TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 17 | # PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 18 | # HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 19 | # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 20 | # TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 21 | # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 22 | # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 23 | # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | """Tools to convert between Python datetime instances and Microsoft times. 26 | """ 27 | from calendar import timegm 28 | 29 | 30 | # http://support.microsoft.com/kb/167296 31 | # How To Convert a UNIX time_t to a Win32 FILETIME or SYSTEMTIME 32 | EPOCH_AS_FILETIME = 116444736000000000 # January 1, 1970 as MS file time 33 | HUNDREDS_OF_NANOSECONDS = 10000000 34 | 35 | 36 | def dt_to_filetime(dt, delta_from_utc): 37 | """Converts a datetime to Microsoft filetime format. 38 | 39 | >>> "%.0f" % dt_to_filetime(datetime(2009, 7, 25, 23, 0)) 40 | '128930364000000000' 41 | 42 | >>> "%.0f" % dt_to_filetime(datetime(1970, 1, 1, 0, 0, tzinfo=utc)) 43 | '116444736000000000' 44 | 45 | >>> "%.0f" % dt_to_filetime(datetime(1970, 1, 1, 0, 0)) 46 | '116444736000000000' 47 | 48 | >>> dt_to_filetime(datetime(2009, 7, 25, 23, 0, 0, 100)) 49 | 128930364000001000 50 | """ 51 | dt += delta_from_utc 52 | ft = EPOCH_AS_FILETIME + (timegm(dt.timetuple()) * HUNDREDS_OF_NANOSECONDS) 53 | return ft + (dt.microsecond * 10) 54 | -------------------------------------------------------------------------------- /analyzer/darwin/modules/auxiliary/screenshots.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2010-2013 Claudio Guarnieri. 2 | # Copyright (C) 2014-2016 Cuckoo Foundation. 3 | # This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org 4 | # See the file 'docs/LICENSE' for copying permission. 5 | 6 | import time 7 | import logging 8 | import StringIO 9 | from threading import Thread 10 | 11 | from lib.common.abstracts import Auxiliary 12 | from lib.common.results import NetlogFile 13 | from lib.api.screenshot import Screenshot 14 | 15 | log = logging.getLogger(__name__) 16 | SHOT_DELAY = 1 17 | # Skip the following area when comparing screen shots. 18 | # Example for 800x600 screen resolution. 19 | # SKIP_AREA = ((735, 575), (790, 595)) 20 | SKIP_AREA = None 21 | 22 | class Screenshots(Auxiliary, Thread): 23 | """Take screenshots.""" 24 | 25 | def __init__(self, options={}, analyzer=None): 26 | Thread.__init__(self) 27 | Auxiliary.__init__(self, options, analyzer) 28 | self.do_run = True 29 | 30 | def stop(self): 31 | """Stop screenshotting.""" 32 | self.do_run = False 33 | 34 | def run(self): 35 | """Run screenshotting. 36 | @return: operation status. 37 | """ 38 | if "screenshots" in self.options: 39 | self.do_run = int(self.options["screenshots"]) 40 | 41 | if not Screenshot().have_pil(): 42 | log.warning("Python Image Library is not installed, " 43 | "screenshots are disabled") 44 | return False 45 | 46 | img_counter = 0 47 | img_last = None 48 | 49 | while self.do_run: 50 | time.sleep(SHOT_DELAY) 51 | 52 | try: 53 | img_current = Screenshot().take() 54 | except IOError as e: 55 | log.error("Cannot take screenshot: %s", e) 56 | continue 57 | 58 | if img_last: 59 | if Screenshot().equal(img_last, img_current, SKIP_AREA): 60 | continue 61 | 62 | img_counter += 1 63 | 64 | # workaround as PIL can't write to the socket file object :( 65 | tmpio = StringIO.StringIO() 66 | img_current.save(tmpio, format="JPEG") 67 | tmpio.seek(0) 68 | 69 | # now upload to host from the StringIO 70 | nf = NetlogFile("shots/%s.jpg" % str(img_counter).rjust(4, "0")) 71 | 72 | for chunk in tmpio: 73 | nf.sock.sendall(chunk) 74 | 75 | nf.close() 76 | 77 | img_last = img_current 78 | 79 | return True 80 | -------------------------------------------------------------------------------- /web/templates/analysis/overview/index.html: -------------------------------------------------------------------------------- 1 |
    2 |
    3 | {% if analysis.info.category == "file" and analysis.target %} 4 | {% include "analysis/overview/_file.html" %} 5 | {% elif analysis.info.category == "url" %} 6 | {% include "analysis/overview/_url.html" %} 7 | {% endif %} 8 |
    9 |
    10 |

    Score

    11 | {% if analysis.info.score < 1 %} 12 |
    13 | This {{ analysis.info.category }} appears fairly benign with a score of {{ analysis.info.score }} out of 10. 14 |
    15 | {% elif analysis.info.score < 2 %} 16 |
    17 |

    This {{ analysis.info.category }} shows some signs of potential malicious behavior.

    18 |

    The score of this {{ analysis.info.category}} is {{ analysis.info.score }} out of 10.

    19 |
    20 | {% elif analysis.info.score < 5 %} 21 |
    22 | This {{ analysis.info.category }} shows numerous signs of malicious behavior. 23 |

    24 | The score of this {{ analysis.info.category}} is {{ analysis.info.score }} out of 10. 25 |
    26 | {% else %} 27 |
    28 |

    This {{ analysis.info.category }} is very suspicious, with a score of {{ analysis.info.score }} out of 10!

    29 |
    30 | {% endif %} 31 | 32 |

    33 | Please notice: The scoring system is currently still in development and should be considered an alpha feature. 34 |

    35 |
    36 |
    37 | 38 | {% include "analysis/overview/_info.html" %} 39 | 40 |
    41 |
    42 | {% include "analysis/overview/_signatures.html" %} 43 |
    44 |
    45 | {% include "analysis/overview/_screenshots.html" %} 46 |
    47 |
    48 | 49 |
    50 | 51 |

    Network

    52 |
    53 |
    {% include "analysis/network/_dns.html" %}
    54 |
    {% include "analysis/network/_hosts.html" %}
    55 |
    56 | 57 | {% include "analysis/overview/_summary.html" %} 58 | -------------------------------------------------------------------------------- /web/templates/analysis/network/_dns.html: -------------------------------------------------------------------------------- 1 | {% load analysis_tags %} 2 |
    3 |

    DNS

    4 | {% if analysis.network.dns %} 5 | 6 | 7 | 8 | 9 | 10 | 11 | {% for p in analysis.network.dns %} 12 | {% if "AirSonos" not in p.request and "Mac._ssh._tcp.local" not in p.request%} 13 | 14 | 17 | 38 | 47 | 48 | {% endif %} 49 | {% endfor %} 50 |
    NameResponsePost-Analysis Lookup
    15 | {{p.request}} 16 | 18 | {% for a in p.answers %} 19 | {% if a.type == "A" %} 20 | {% if ":" not in a.data %} 21 | 22 | {{a.type}} {{a.data|linebreaksbr}} 23 | 24 | {% else %} 25 | {{a.type}} {{a.data|linebreaksbr}} 26 | {% endif %} 27 | {% if not forloop.last %}
    {% endif %} 28 | {% elif a.type == "CNAME" %} 29 | 30 | {{a.type}} {{a.data|linebreaksbr}} 31 | 32 | {% if not forloop.last %}
    {% endif %} 33 | {% else %} 34 | {{a.type}} {{a.data|linebreaksbr}}{% if not forloop.last %}
    {% endif %} 35 | {% endif %} 36 | {% endfor %} 37 |
    39 | {% if ":" not in domainlookups|get_item:p.request %} 40 | 41 | {{ domainlookups|get_item:p.request }} 42 | 43 | {% else %} 44 | {{ domainlookups|get_item:p.request }} 45 | {% endif %} 46 |
    51 | {% else %} 52 |

    No domains contacted.

    53 | {% endif %} 54 |
    55 | -------------------------------------------------------------------------------- /modules/machinery/esx.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2010-2013 Claudio Guarnieri. 2 | # Copyright (C) 2014-2016 Cuckoo Foundation. 3 | # Copyright (C) 2013 Christopher Schmitt 4 | # This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org 5 | # See the file 'docs/LICENSE' for copying permission. 6 | 7 | import libvirt 8 | 9 | from lib.cuckoo.common.abstracts import LibVirtMachinery 10 | from lib.cuckoo.common.exceptions import CuckooCriticalError 11 | from lib.cuckoo.common.exceptions import CuckooMachineError 12 | 13 | class ESX(LibVirtMachinery): 14 | """Virtualization layer for ESXi/ESX based on python-libvirt.""" 15 | 16 | def _initialize_check(self): 17 | """Runs all checks when a machine manager is initialized. 18 | @raise CuckooMachineError: if configuration is invalid 19 | """ 20 | if not self.options.esx.dsn: 21 | raise CuckooMachineError("ESX(i) DSN is missing, please add it to the config file") 22 | if not self.options.esx.username: 23 | raise CuckooMachineError("ESX(i) username is missing, please add it to the config file") 24 | if not self.options.esx.password: 25 | raise CuckooMachineError("ESX(i) password is missing, please add it to the config file") 26 | 27 | self.dsn = self.options.esx.dsn 28 | self.global_conn = self._global_connect() 29 | super(ESX, self)._initialize_check() 30 | 31 | def _auth_callback(self, credentials, user_data): 32 | for credential in credentials: 33 | if credential[0] == libvirt.VIR_CRED_AUTHNAME: 34 | credential[4] = self.options.esx.username 35 | elif credential[0] == libvirt.VIR_CRED_NOECHOPROMPT: 36 | credential[4] = self.options.esx.password 37 | else: 38 | raise CuckooCriticalError("ESX machinery did not recieve an object to inject a username or password into") 39 | 40 | return 0 41 | 42 | def _connect(self): 43 | """Return the already-connected single connection handle if set, otherwise set it.""" 44 | if self.global_conn is None: 45 | self.global_conn = self._global_connect() 46 | return self.global_conn 47 | 48 | def _global_connect(self): 49 | """Set the single connection handle.""" 50 | try: 51 | self.auth = [[libvirt.VIR_CRED_AUTHNAME, libvirt.VIR_CRED_NOECHOPROMPT], self._auth_callback, None] 52 | return libvirt.openAuth(self.dsn, self.auth, 0) 53 | except libvirt.libvirtError as libvex: 54 | raise CuckooCriticalError("libvirt returned an exception on connection: %s" % libvex) 55 | 56 | def _disconnect(self, conn): 57 | """Using one global connection we now disconnect in the destructor, ignore requests to disconnect.""" 58 | pass 59 | 60 | def __del__(self): 61 | self.global_conn.close() 62 | -------------------------------------------------------------------------------- /web/templates/analysis/import.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | {% load staticfiles %} 3 | {% block content %} 4 | 28 | 52 |
    53 |
    54 |

    55 | 56 |
    {% csrf_token %} 57 |
    58 |
    59 |
    60 | 61 | 62 | 63 |
    64 | 65 | 66 | 67 | Select 68 | 69 | 70 |
    71 |
    72 |
    73 |
    74 |
    75 |
    76 |
    77 |
    78 | {% endblock %} 79 | -------------------------------------------------------------------------------- /analyzer/darwin/lib/core/data/types.yml: -------------------------------------------------------------------------------- 1 | # =============================================== 2 | # Basic types 3 | # 4 | int: &int 5 | # We will print it with something like printf("%d", value) 6 | printf_specifier: "%d" 7 | # Is it a native C type (on OS X)? 8 | native: Yes 9 | # Alternative name for backward compatibility 10 | integer: *int 11 | 12 | unsigned int: &unsigned-int 13 | printf_specifier: "%ld" 14 | native: Yes 15 | 16 | long: &long 17 | printf_specifier: "%l" 18 | native: Yes 19 | 20 | unsigned long: &unsigned-long 21 | printf_specifier: "%lu" 22 | native: Yes 23 | 24 | unsigned long long: &unsigned-long-long 25 | printf_specifier: "%llu" 26 | native: Yes 27 | 28 | size_t: *unsigned-long 29 | 30 | char: &char 31 | printf_specifier: '"%c"' 32 | native: Yes 33 | 34 | float: &float 35 | printf_specifier: "%f" 36 | native: Yes 37 | 38 | double: &double 39 | printf_specifier: "%f" 40 | native: Yes 41 | # 42 | # Raw pointers: just dump their values (in *decimal* since dtrace will output 43 | # JSON that doesn't accept hex values) 44 | # 45 | "void *": 46 | <<: *unsigned-long-long 47 | cast: "unsigned long long" 48 | # 49 | # Strings 50 | # 51 | "char *": &char-pointer 52 | printf_specifier: '"%S"' 53 | native: No 54 | template: |- 55 | !!(${ARG}) ? copyinstr((uint64_t)${ARG}) : "" 56 | # 57 | # Arbitrary buffers 58 | # 59 | #buffer: &buffer 60 | # printf_specifier: '"%S"' 61 | # native: No 62 | # template: |- 63 | # ${ARG} != (int64_t)NULL ? stringof(copyin(${ARG}, ${SIZE_ARG})) : "" 64 | # 65 | # Fixed length C types 66 | # 67 | int8_t: &int8_t 68 | printf_specifier: "%d" 69 | native: Yes 70 | 71 | uint8_t: &uint8_t 72 | printf_specifier: "%u" 73 | native: Yes 74 | 75 | int16_t: &int16_t 76 | printf_specifier: "%d" 77 | native: Yes 78 | 79 | uint16_t: &uint16_t 80 | printf_specifier: "%u" 81 | native: Yes 82 | 83 | int32_t: &int32_t 84 | printf_specifier: "%d" 85 | native: Yes 86 | 87 | uint32_t: &uint32_t 88 | printf_specifier: "%u" 89 | native: Yes 90 | 91 | int64_t: &int64_t 92 | printf_specifier: "%lld" 93 | native: Yes 94 | 95 | uint64_t: &uint64_t 96 | printf_specifier: "%llu" 97 | native: Yes 98 | 99 | # 100 | # Structures for tests. 101 | # Please don't remove them. Thanks! 102 | # 103 | 104 | test_t: 105 | native: No 106 | struct: 107 | hash: "int" 108 | base: "test_internal_t *" 109 | description: "char *" 110 | 111 | test_internal_t: 112 | native: No 113 | struct: 114 | abc: "double *" 115 | hfa: "size_t" 116 | sss: "char *" 117 | 118 | test_extra_t: 119 | native: No 120 | struct: 121 | foo: int 122 | bar: uint64_t 123 | 124 | # 125 | # Your custom data types 126 | # 127 | -------------------------------------------------------------------------------- /analyzer/darwin/lib/api/screenshot.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2010-2013 Claudio Guarnieri. 2 | # Copyright (C) 2014-2016 Cuckoo Foundation. 3 | # This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org 4 | # See the file 'docs/LICENSE' for copying permission. 5 | 6 | import math 7 | 8 | try: 9 | import ImageChops 10 | import ImageGrab 11 | import ImageDraw 12 | HAVE_PIL = True 13 | except: 14 | try: 15 | from PIL import ImageChops 16 | from PIL import ImageGrab 17 | from PIL import ImageDraw 18 | HAVE_PIL = True 19 | except: 20 | HAVE_PIL = False 21 | 22 | class Screenshot: 23 | """Get screenshots.""" 24 | 25 | def _draw_rectangle(self, img, xy): 26 | """Draw a black rectangle. 27 | @param img: PIL Image object 28 | @param xy: Coordinates as refined in PIL rectangle() doc 29 | @return: Image with black rectangle 30 | """ 31 | dr = ImageDraw.Draw(img) 32 | dr.rectangle(xy, fill="black", outline="black") 33 | return img 34 | 35 | def have_pil(self): 36 | """Is Python Image Library installed? 37 | @return: installed status. 38 | """ 39 | return HAVE_PIL 40 | 41 | def equal(self, img1, img2, skip_area=None): 42 | """Compares two screenshots using Root-Mean-Square Difference (RMS). 43 | @param img1: screenshot to compare. 44 | @param img2: screenshot to compare. 45 | @return: equal status. 46 | """ 47 | if not HAVE_PIL: 48 | return None 49 | 50 | # Trick to avoid getting a lot of screen shots only because the time in the windows 51 | # clock is changed. 52 | # We draw a black rectangle on the coordinates where the clock is locates, and then 53 | # run the comparison. 54 | # NOTE: the coordinates are changing with VM screen resolution. 55 | if skip_area: 56 | # Copying objects to draw in another object. 57 | img1 = img1.copy() 58 | img2 = img2.copy() 59 | # Draw a rectangle to cover windows clock. 60 | for img in (img1, img2): 61 | self._draw_rectangle(img, skip_area) 62 | 63 | # To get a measure of how similar two images are, we use 64 | # root-mean-square (RMS). If the images are exactly identical, 65 | # this value is zero. 66 | diff = ImageChops.difference(img1, img2) 67 | h = diff.histogram() 68 | sq = (value * ((idx % 256)**2) for idx, value in enumerate(h)) 69 | sum_of_squares = sum(sq) 70 | rms = math.sqrt(sum_of_squares/float(img1.size[0] * img1.size[1])) 71 | 72 | # Might need to tweak the threshold. 73 | return rms < 8 74 | 75 | def take(self): 76 | """Take a screenshot. 77 | @return: screenshot or None. 78 | """ 79 | if not HAVE_PIL: 80 | return None 81 | 82 | return ImageGrab.grab() 83 | -------------------------------------------------------------------------------- /web/templates/analysis/buffers/index.html: -------------------------------------------------------------------------------- 1 | {% if analysis.buffer|length %} 2 | {% for file in analysis.buffer %} 3 |
    4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 50 | 51 | 52 | 53 | 54 | 55 | {% if file.object_id %} 56 | 57 | 58 | 59 | 60 | {% endif %} 61 |
    Name{{file.name}}
    Size{{ file.size | sizeof_fmt }}
    Type{{file.type}}
    MD5{{file.md5}}
    SHA1{{file.sha1}}
    SHA256{{file.sha256}}
    CRC32{{file.crc32}}
    ssdeep{{file.ssdeep}}
    Yara 40 | {% if file.yara %} 41 |
      42 | {% for sign in file.yara %} 43 |
    • {{sign.name}} - {{sign.meta.description}}
    • 44 | {% endfor %} 45 |
    46 | {% else %} 47 | None matched 48 | {% endif %} 49 |
    VirusTotalSearch for analysis
    Download
    62 |
    63 | {% endfor %} 64 | {% else %} 65 |
    Sorry! No dropped buffers.
    66 | {% endif %} 67 | -------------------------------------------------------------------------------- /web/templates/compare/both.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | {% load staticfiles %} 3 | {% block content %} 4 |

    5 | 6 | 11 | 12 |
    13 |
    14 |

    Analysis 1

    15 | 16 | {% include "compare/_info.html" with record=left %} 17 | 18 |
    19 |

    Execution Graph

    20 | 21 |

    This graph gives you an abstracted overview of the execution of the analyzer file. More specifically it represents the percentage of occurrences of behavioral events classified by category: the bigger the colored block, the higher is the count of events for the respective category performed by the analyzed malware

    22 |

    Comparing two graphs from different analyses can give you help estimate how much the behavior of the two files differ.

    23 |

    Following are the colored categories:

    24 | 25 |

    26 | registry 27 | file 28 | system 29 | network 30 | process 31 | services 32 | synchronization 33 | windows 34 |

    35 |
    36 | 37 |
    38 |
    39 | {% for cat, count in left_counts.items %} 40 |
    41 | {% endfor %} 42 |
    43 |
    44 |
    45 |
    46 |

    Analysis 2

    47 | 48 | {% include "compare/_info.html" with record=right %} 49 | 50 |
    51 |
    52 | {% for cat, count in right_counts.items %} 53 |
    54 | {% endfor %} 55 |
    56 |
    57 | 58 |
    59 |
    60 |
    61 |
    62 | {% endblock %} 63 | -------------------------------------------------------------------------------- /analyzer/darwin/lib/common/config.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2014-2016 Cuckoo Foundation. 2 | # This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org 3 | # See the file 'docs/LICENSE' for copying permission. 4 | 5 | import ConfigParser 6 | 7 | class Config: 8 | def __init__(self, cfg): 9 | """@param cfg: configuration file.""" 10 | config = ConfigParser.ConfigParser(allow_no_value=True) 11 | config.read(cfg) 12 | 13 | for section in config.sections(): 14 | for name, raw_value in config.items(section): 15 | if name == "file_name": 16 | value = config.get(section, name) 17 | else: 18 | try: 19 | value = config.getboolean(section, name) 20 | except ValueError: 21 | try: 22 | value = config.getint(section, name) 23 | except ValueError: 24 | value = config.get(section, name) 25 | setattr(self, name, value) 26 | 27 | def get_options(self): 28 | """Get analysis options. 29 | @return: options dict. 30 | """ 31 | # The analysis package can be provided with some options in the 32 | # following format: 33 | # option1=value1,option2=value2,option3=value3 34 | # 35 | # Here we parse such options and provide a dictionary that will be made 36 | # accessible to the analysis package. 37 | options = {} 38 | if hasattr(self, "options") and len(self.options) > 0: 39 | try: 40 | # Split the options by comma. 41 | fields = self.options.split(",") 42 | except ValueError: 43 | pass 44 | else: 45 | for field in fields: 46 | # Split the name and the value of the option. 47 | try: 48 | # Sometimes, we have a key without a value (i.e. it's a 49 | # command line argument), so we can't use the 50 | # `key, value = field.split("=", 1)` style here 51 | parts = field.split("=", 1) 52 | except ValueError: 53 | pass 54 | else: 55 | key = parts[0].strip() 56 | arg_prefix = "arg-" 57 | if not key.startswith(arg_prefix): 58 | # If the parsing went good, we add the option to the 59 | # dictionary. 60 | value = parts[1].strip() 61 | options[key] = value 62 | elif len(key) > len(arg_prefix): 63 | # Remove "arg-" prefix from the key 64 | key = key[4:]; parts[0] = key 65 | # Add this key (with a value maybe) to the args 66 | if "args" not in options: options["args"] = [] 67 | options["args"] += parts 68 | return options 69 | -------------------------------------------------------------------------------- /analyzer/darwin/lib/common/results.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2014-2016 Cuckoo Foundation. 2 | # This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org 3 | # See the file 'docs/LICENSE' for copying permission. 4 | 5 | import time 6 | import socket 7 | import logging 8 | from config import Config 9 | 10 | log = logging.getLogger(__name__) 11 | 12 | BUFSIZE = 1024*1024 13 | 14 | def upload_to_host(file_path, dump_path): 15 | nc = infd = None 16 | try: 17 | nc = NetlogFile(dump_path) 18 | 19 | infd = open(file_path, "rb") 20 | buf = infd.read(BUFSIZE) 21 | while buf: 22 | nc.send(buf, retry=False) 23 | buf = infd.read(BUFSIZE) 24 | except Exception as e: 25 | log.error("Exception uploading file %s to host: %s", file_path, e) 26 | finally: 27 | if infd: 28 | infd.close() 29 | if nc: 30 | nc.close() 31 | 32 | class NetlogConnection(object): 33 | def __init__(self, proto=""): 34 | config = Config(cfg="analysis.conf") 35 | self.hostip, self.hostport = config.ip, config.port 36 | self.sock, self.file = None, None 37 | self.proto = proto 38 | 39 | def connect(self): 40 | i = 1 41 | # this can loop forever, if we can't connect the whole analysis is useless anyways 42 | while True: 43 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 44 | try: 45 | s.connect((self.hostip, self.hostport)) 46 | s.sendall(self.proto) 47 | except: 48 | time.sleep(i) 49 | i = min(i + 1, 60) 50 | else: 51 | self.sock = s 52 | self.file = s.makefile() 53 | break 54 | 55 | def send(self, data, retry=True): 56 | if not self.sock: self.connect() 57 | 58 | try: 59 | self.sock.sendall(data) 60 | except socket.error as e: 61 | if retry: 62 | self.connect() 63 | self.send(data, retry=False) 64 | else: 65 | raise 66 | except Exception as e: 67 | log.error("Unhandled exception in NetlogConnection: %s", str(e)) 68 | # We really have nowhere to log this, if the netlog connection 69 | # does not work, we can assume that any logging won't work either. 70 | # So we just fail silently. 71 | self.close() 72 | 73 | def close(self): 74 | try: 75 | self.file.close() 76 | self.sock.close() 77 | except Exception: 78 | pass 79 | 80 | class NetlogFile(NetlogConnection): 81 | def __init__(self, filepath): 82 | self.filepath = filepath 83 | NetlogConnection.__init__(self, proto="FILE\n{0}\n".format(self.filepath)) 84 | self.connect() 85 | 86 | class NetlogHandler(logging.Handler, NetlogConnection): 87 | def __init__(self): 88 | logging.Handler.__init__(self) 89 | NetlogConnection.__init__(self, proto="LOG\n") 90 | self.connect() 91 | 92 | def emit(self, record): 93 | msg = self.format(record) 94 | self.send("{0}\n".format(msg)) 95 | -------------------------------------------------------------------------------- /web/templates/analysis/network/_tcp.html: -------------------------------------------------------------------------------- 1 | {% load staticfiles %} 2 | {% load analysis_tags %} 3 | 4 |
    5 |

    TCP

    6 | {% if analysis.network.tcp %} 7 |
    8 |
    9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | {% for p in analysis.network.tcp %} 17 | 18 | 19 | 20 | 21 | 22 | 23 | {% endfor %} 24 |
    SourceSource PortDestinationDestination Port
    {{p.src}}{{p.sport}}{{p.dst}} {{ iplookups|get_item:p.dst }}{{p.dport}}
    25 |
    26 |
    27 |
    28 | {% else %} 29 |

    No TCP connections recorded.

    30 | {% endif %} 31 |
    32 | 73 | -------------------------------------------------------------------------------- /web/templates/analysis/export.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | {% load staticfiles %} 3 | {% block content %} 4 | 28 |
    29 |
    30 |

    31 | 32 |
    {% csrf_token %} 33 |
    34 |
    35 |
    36 | 37 |
    38 | {% if analysis.info.category == "file" %} 39 | 40 | {% elif analysis.info.category == "url" %} 41 | 42 | 43 | {% else %} 44 | 45 | {% endif %} 46 |
    47 |
    48 |
    49 |
    50 |
    51 |
    52 |
    53 | 54 |
    55 |
    56 |
    57 | {% for dirname, count in dirs %} 58 |
    59 | {{ dirname }} ({{ count }} files) 60 |
    61 | {% endfor %} 62 | {% for filename in files %} 63 |
    64 | {{ filename }} 65 |
    66 | {% endfor %} 67 |
    68 |
    69 |
    70 |
    71 |
    72 | 73 |
    74 |
    75 |
    76 |
    77 | {% endblock %} 78 | -------------------------------------------------------------------------------- /web/templates/analysis/overview/_file.html: -------------------------------------------------------------------------------- 1 | {% load analysis_tags %} 2 |
    3 |

    File {{analysis.target.file.name}} 4 |

    5 |
    6 | 7 | 8 | 9 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | {% if analysis.static.pdb_path %} 57 | 58 | 59 | 60 | 61 | {% endif %} 62 | 63 | 64 | 75 | 76 |
    Size 10 | {% if analysis.target.file_id %} 11 | {{ analysis.target.file.size | sizeof_fmt }} 12 | 13 | 14 | Download 15 | 16 | 17 | Resubmit sample 18 | 19 | 20 | {% endif %} 21 |
    Type{{analysis.target.file.type}}
    MD5{{analysis.target.file.md5}}
    SHA1{{analysis.target.file.sha1}}
    SHA256{{analysis.target.file.sha256}}
    SHA512 42 | 45 |
    {{analysis.target.file.sha512}}
    46 |
    CRC32{{analysis.target.file.crc32}}
    ssdeep{{analysis.target.file.ssdeep}}
    PDB Path{{analysis.static.pdb_path}}
    Yara 65 | {% if analysis.target.file.yara %} 66 |
      67 | {% for sign in analysis.target.file.yara %} 68 |
    • {{sign.name}} - {{sign.meta.description}}
    • 69 | {% endfor %} 70 |
    71 | {% else %} 72 | None matched 73 | {% endif %} 74 |
    77 |
    78 |
    79 | -------------------------------------------------------------------------------- /web/templates/analysis/memory/index.html: -------------------------------------------------------------------------------- 1 | 4 |
    5 | 21 |
    22 |
    23 | {% include "analysis/memory/_pslist.html" %} 24 |
    25 |
    26 | {% include "analysis/memory/_svcscan.html" %} 27 |
    28 |
    29 | {% include "analysis/memory/_modscan.html" %} 30 |
    31 |
    32 | {% include "analysis/memory/_devicetree.html" %} 33 |
    34 |
    35 | {% include "analysis/memory/_malfind.html" %} 36 |
    37 |
    38 | {% include "analysis/memory/_apihooks.html" %} 39 |
    40 |
    41 | {% include "analysis/memory/_ssdt.html" %} 42 |
    43 |
    44 | {% include "analysis/memory/_idt.html" %} 45 |
    46 |
    47 | {% include "analysis/memory/_gdt.html" %} 48 |
    49 |
    50 | {% include "analysis/memory/_timers.html" %} 51 |
    52 |
    53 | {% include "analysis/memory/_messagehooks.html" %} 54 |
    55 |
    56 | {% include "analysis/memory/_yarascan.html" %} 57 |
    58 |
    59 | {% include "analysis/memory/_callbacks.html" %} 60 |
    61 |
    62 | {% if analysis.memory.sockscan %} 63 | {% include "analysis/memory/_sockscan.html" %} 64 | {% elif analysis.memory.netscan %} 65 | {% include "analysis/memory/_netscan.html" %} 66 | {% endif %} 67 |
    68 |
    69 |
    70 | -------------------------------------------------------------------------------- /web/templates/analysis/overview/_signatures.html: -------------------------------------------------------------------------------- 1 | {% load analysis_tags %} 2 | 3 | 19 |
    20 |

    Signatures

    21 | {% for signature in analysis.signatures %} 22 | 23 |
    24 | {{signature.description}} 25 | {% if signature.marks %} 26 | {% if signature.marks|length == 1 %} 27 | (1 event) 28 | {% elif signature.markcount == signature.marks|length %} 29 | ({{ signature.marks|length }} events) 30 | {% elif signature.markcount %} 31 | ({{ signature.marks|length }} out of {{ signature.markcount }} events) 32 | {% else %} 33 | ({{ signature.marks|length }} events) 34 | {% endif %} 35 | {% endif %} 36 |
    37 | 38 |
    39 | 40 | {% for mark in signature.marks|sigsort %} 41 | {% if mark.type == "call" %} 42 | {% if mark.first %} 43 | {# Close up the non-API call table #} 44 | {% if not forloop.first %} 45 |
    46 | 47 | {% endif %} 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | {% endif %} 59 | 60 | {% include "analysis/behavior/_api_call.html" with call=mark.call pid=mark.pid cid=mark.cid %} 61 | 62 | {% elif mark.type == "ioc" %} 63 | 64 | 65 | 66 | {% if mark.description %} 67 | 68 | {% endif %} 69 | 70 | {% elif mark.type == "generic" %} 71 | 72 | {% for key, value in mark.items %} 73 | {% if key != "type" %} 74 | 75 | 76 | {% endif %} 77 | {% endfor %} 78 | 79 | {% endif %} 80 | {% endfor %} 81 |
    Time & APIArgumentsStatusReturnRepeated
    {{ mark.category }}{{ mark.ioc }}{{ mark.description }}
    {{ key }}{{ value }}
    82 |
    83 | {% endfor %} 84 | {% if not analysis.signatures %} 85 |

    No signatures

    86 | {% endif %} 87 |
    88 | -------------------------------------------------------------------------------- /analyzer/darwin/modules/packages/dmg.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Copyright (C) 2018 phdphuc 3 | # This software may be modified and distributed under the terms 4 | # of the MIT license. See the LICENSE file for details. 5 | 6 | import logging 7 | from shutil import move 8 | from os import path, environ 9 | from random import SystemRandom 10 | from string import ascii_letters 11 | from subprocess import check_output 12 | from zipfile import ZipFile, BadZipfile 13 | from lib.core.packages import Package, choose_package_class 14 | from subprocess import Popen, PIPE 15 | import glob 16 | import time 17 | log = logging.getLogger(__name__) 18 | 19 | def current_directory(): 20 | return path.dirname(path.abspath(__file__)) 21 | 22 | class Dmg(Package): 23 | 24 | real_package = None 25 | 26 | def prepare(self): 27 | password = self.options.get("password") 28 | files = self._extract(self.target, password) 29 | if not files or len(files) == 0: 30 | raise Exception("Invalid (or empty) DMG %s" % self.target) 31 | # Look for a file to analyse 32 | target_name = self.options.get("file") 33 | if not target_name: 34 | # If no file name is provided via option, take the first file 35 | target_name = files[0] 36 | log.debug("Missing file option, auto executing: %s", target_name) 37 | else: 38 | for file in files: 39 | if target_name in file: 40 | target_name = file 41 | 42 | # Remove the trailing slash (if any) 43 | if target_name.endswith("/"): 44 | self.target = target_name[:-1] 45 | else: 46 | self.target = target_name 47 | 48 | # Since we don't know what kind of file we're going to analyse, let's 49 | # detect it automatically and create an appropriate analysis package 50 | # for this file 51 | file_info = _fileinfo(self.target) 52 | pkg_class = choose_package_class(file_info, target_name) 53 | 54 | if not pkg_class: 55 | raise Exception("Unable to detect analysis package for the file %s" % target_name) 56 | else: 57 | log.debug("Analysing file \"%s\" using package \"%s\"", target_name, pkg_class.__name__) 58 | 59 | kwargs = { 60 | "options" : self.options, 61 | "timeout" : self.timeout 62 | } 63 | # We'll forward start() method invocation to the proper package later 64 | self.real_package = pkg_class(self.target, self.host, **kwargs) 65 | 66 | def start(self): 67 | # We have nothing to do here; let the proper package do it's job 68 | self.prepare() 69 | if not self.real_package: 70 | raise Exception("Invalid analysis package, aborting") 71 | self.real_package.start() 72 | 73 | def _extract(self, filename, password): 74 | 75 | # Extraction. 76 | extract_path = environ.get("TEMP", "/tmp") 77 | filepath = path.join(extract_path, filename+".bar") 78 | mountpoint = path.join(extract_path, "mountpoint") 79 | print extract_path, filepath, mountpoint 80 | 81 | p1 = Popen(["/usr/bin/hdiutil", "convert","-quiet", filename, "-format", "UDTO", "-o", filepath], cwd=current_directory(), stdout=PIPE ) 82 | p1.communicate() 83 | 84 | p2 = Popen(["/usr/bin/hdiutil", "attach","-quiet", "-nobrowse", "-noverify", "-noautoopen", "-mountpoint", mountpoint, filepath+".cdr"], cwd=current_directory(), stdout=PIPE ) 85 | p2.communicate() 86 | 87 | return glob.glob(mountpoint + '/*.app') + glob.glob(mountpoint + '/*.dmg') 88 | 89 | 90 | def _fileinfo(target): 91 | raw = check_output(["file", target]) 92 | # The utility has the following output format: "%filename%: %description%", 93 | # so we just skip everything before the actual description 94 | return raw[raw.index(":")+2:] 95 | -------------------------------------------------------------------------------- /web/templates/analysis/dropped/index.html: -------------------------------------------------------------------------------- 1 | {% if analysis.dropped|length > 0 %} 2 | {% for file in analysis.dropped %} 3 |
    4 | 5 | 6 | 7 | 20 | 21 | 22 | {% if file.filepath %} 23 | 24 | 25 | 26 | 27 | {% endif %} 28 | 29 | 30 | 31 | 32 | {% if file.pids %} 33 | 34 | 35 | 40 | 41 | {% endif %} 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 79 | 80 | 81 | 82 | 83 | 84 |
    Name 8 | {{file.name}} 9 | {% if file.object_id %} 10 | 18 | {% endif %} 19 |
    Filepath{{ file.filepath }}
    Size{{ file.size | sizeof_fmt }}
    Processes 36 | {% for pid in file.pids %} 37 | {{ pid }} ({{ pid|process_name:analysis }}) 38 | {% endfor %} 39 |
    Type{{file.type}}
    MD5{{file.md5}}
    SHA1{{file.sha1}}
    SHA256{{file.sha256}}
    CRC32{{file.crc32}}
    ssdeep{{file.ssdeep}}
    Yara 69 | {% if file.yara %} 70 |
      71 | {% for sign in file.yara %} 72 |
    • {{sign.name}} - {{sign.meta.description}}
    • 73 | {% endfor %} 74 |
    75 | {% else %} 76 | None matched 77 | {% endif %} 78 |
    VirusTotalSearch for analysis
    85 |
    86 | {% endfor %} 87 | {% else %} 88 |
    Sorry! No dropped files.
    89 | {% endif %} 90 | -------------------------------------------------------------------------------- /web/templates/analysis/network/index.html: -------------------------------------------------------------------------------- 1 | {% if not httpreplay.have %} 2 |
    3 | Deprecation note: 4 | While processing this analysis you did not have the httpreplay Python 5 | library installed. Installing this library (i.e., pip install httpreplay) 6 | will allow Cuckoo to do more proper PCAP analysis including but not 7 | limited to showing full HTTP and HTTPS (!) requests and responses. 8 | It is recommended that you install this library and possibly reprocess any 9 | interesting analysis tasks. 10 |
    11 | {% elif httpreplay.deprecated %} 12 |
    13 | Deprecation note: 14 | You are using version {{ httpreplay.current_version }} of HTTPReplay, 15 | rather than the latest version {{ httpreplay.latest_version }}, which may 16 | not handle various corner cases and/or TLS cipher suites correctly. This 17 | could result in not getting all the HTTP/HTTPS streams that are available 18 | or corrupt some streams that were not handled correctly before. Please 19 | upgrade it to the latest version (`pip install --upgrade httpreplay`). 20 |
    21 | {% endif %} 22 | 23 |
    24 | 58 |
    59 |
    {% include "analysis/network/_hosts.html" %}
    60 |
    {% include "analysis/network/_dns.html" %}
    61 |
    {% include "analysis/network/_tcp.html" %}
    62 |
    {% include "analysis/network/_udp.html" %}
    63 |
    {% include "analysis/network/_http.html" %}
    64 |
    {% include "analysis/network/_icmp.html" %}
    65 |
    {% include "analysis/network/_irc.html" %}
    66 |
    {% include "analysis/network/_suricata.html" %}
    67 |
    {% include "analysis/network/_snort.html" %}
    68 |
    69 |
    70 | -------------------------------------------------------------------------------- /web/templates/analysis/overview/_info.html: -------------------------------------------------------------------------------- 1 |

    Information on Execution

    2 | 3 |
    4 |
    5 |
    6 |
    7 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 42 | 43 | 44 |
    CategoryStartedCompletedDurationLogs
    {{analysis.info.category|upper}}{{analysis.info.started}}{{analysis.info.ended}}{{analysis.info.duration}} seconds 39 | Show Analyzer Log
    40 | Show Cuckoo Log 41 |
    45 |
    46 | 47 | {% if analysis.debug.errors %} 48 |
      49 | {% for error in analysis.debug.errors %} 50 |
    • Error: {{error}}
    • 51 | {% endfor %} 52 |
    53 | {% endif %} 54 | 55 |
    56 |
    57 |
    58 | {% if analysis.info.machine and analysis.info.machine.name %} 59 |
    60 |
    61 |
    62 |

    Machine

    63 |
    64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 |
    NameLabelStarted OnShutdown On
    {{analysis.info.machine.name}}{{analysis.info.machine.label}}{{analysis.info.machine.started_on}}{{analysis.info.machine.shutdown_on}}
    82 |
    83 |
    84 | {% endif %} 85 | 86 |
    87 |
    88 | 89 |
    90 |
    91 |
    92 |

    Analyzer Log

    93 |
    {{analysis.debug.log|join:""}}
    94 |
    95 |
    96 |

    Cuckoo Log

    97 |
    {{analysis.debug.cuckoo|join:""}}
    98 |
    99 |
    100 |
    101 | -------------------------------------------------------------------------------- /web/templates/analysis/report.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | {% load staticfiles %} 3 | {% load analysis_tags %} 4 | {% block content %} 5 |