├── .gitignore ├── IDA ├── idag_patched.exe └── script.idc ├── README.md ├── Volatility ├── heap_entropy.py └── qemuelf.py ├── WP_AND_PRESENTATION ├── Automated Memory Analysis - Slide.pdf └── Automated Memory Analysis - WP.pdf ├── agent └── agent.py ├── analyzer └── windows │ ├── analyzer.py │ ├── bin │ └── execsc.exe │ ├── dll │ ├── cuckoomon.dll │ ├── cuckoomon_bson.dll │ └── cuckoomon_netlog.dll │ ├── lib │ ├── __init__.py │ ├── api │ │ ├── __init__.py │ │ ├── process.py │ │ └── screenshot.py │ ├── common │ │ ├── __init__.py │ │ ├── abstracts.py │ │ ├── constants.py │ │ ├── defines.py │ │ ├── errors.py │ │ ├── exceptions.py │ │ ├── rand.py │ │ └── results.py │ └── core │ │ ├── __init__.py │ │ ├── config.py │ │ ├── packages.py │ │ ├── privileges.py │ │ └── startup.py │ └── modules │ ├── __init__.py │ ├── auxiliary │ ├── __init__.py │ ├── disguise.py │ ├── human.py │ └── screenshots.py │ └── packages │ ├── __init__.py │ ├── applet.py │ ├── bin.py │ ├── cpl.py │ ├── dll.py │ ├── doc.py │ ├── exe.py │ ├── generic.py │ ├── html.py │ ├── ie.py │ ├── jar.py │ ├── pdf.py │ ├── vbs.py │ ├── xls.py │ └── zip.py ├── conf ├── auxiliary.conf ├── cuckoo.conf ├── esx.conf ├── kvm.conf ├── memory.conf ├── memoryanalysis.conf ├── processing.conf ├── reporting.conf ├── triggers.conf ├── virtualbox.conf └── vmware.conf ├── cuckoo.py ├── data ├── html │ ├── base-report.html │ ├── base-web.html │ ├── browse.html │ ├── css │ │ ├── bootstrap-responsive.min.css │ │ └── bootstrap.min.css │ ├── error.html │ ├── graphic │ │ └── logo.html │ ├── img │ │ ├── glyphicons-halflings-white.png │ │ └── glyphicons-halflings.png │ ├── js │ │ ├── bootstrap.min.js │ │ ├── functions.js │ │ └── jquery.min.js │ ├── pagination-menu.html │ ├── pagination-rpp.html │ ├── report.html │ ├── sections │ │ ├── behavior.html │ │ ├── dropped.html │ │ ├── errors.html │ │ ├── file.html │ │ ├── info.html │ │ ├── network.html │ │ ├── screenshots.html │ │ ├── signatures.html │ │ ├── static.html │ │ ├── url.html │ │ └── volatility.html │ ├── submit.html │ └── success.html ├── patchers │ └── patchpe.xml ├── peutils │ └── UserDB.TXT ├── src │ └── binpackage │ │ ├── Makefile │ │ └── execsc.c └── yara │ ├── index_binary.yar │ └── signatures │ ├── embedded.yar │ ├── shellcodes.yar │ └── vmdetect.yar ├── docs ├── AUTHORS ├── CHANGELOG ├── LICENSE ├── README └── book │ └── src │ ├── Makefile │ ├── _images │ ├── logo │ │ └── cuckoo.png │ ├── schemas │ │ └── architecture-main.png │ └── screenshots │ │ ├── shared_folders.png │ │ └── windows_security.png │ ├── conf.py │ ├── customization │ ├── auxiliary.rst │ ├── index.rst │ ├── machinery.rst │ ├── packages.rst │ ├── processing.rst │ ├── reporting.rst │ └── signatures.rst │ ├── development │ ├── code_style.rst │ ├── development_notes.rst │ └── index.rst │ ├── faq │ └── index.rst │ ├── finalremarks │ └── index.rst │ ├── index.rst │ ├── installation │ ├── guest │ │ ├── agent.rst │ │ ├── cloning.rst │ │ ├── creation.rst │ │ ├── index.rst │ │ ├── network.rst │ │ ├── requirements.rst │ │ └── saving.rst │ ├── host │ │ ├── configuration.rst │ │ ├── index.rst │ │ ├── installation.rst │ │ └── requirements.rst │ ├── index.rst │ └── upgrade.rst │ ├── introduction │ ├── index.rst │ ├── license.rst │ ├── sandboxing.rst │ └── what.rst │ └── usage │ ├── api.rst │ ├── index.rst │ ├── packages.rst │ ├── results.rst │ ├── start.rst │ ├── submit.rst │ ├── utilities.rst │ └── web.rst ├── external └── CPU.exe ├── lib ├── __init__.py ├── cuckoo │ ├── __init__.py │ ├── common │ │ ├── __init__.py │ │ ├── abstracts.py │ │ ├── colors.py │ │ ├── config.py │ │ ├── constants.py │ │ ├── defines.py │ │ ├── dns.py │ │ ├── exceptions.py │ │ ├── irc.py │ │ ├── logo.py │ │ ├── logtbl.py │ │ ├── netlog.py │ │ ├── objects.py │ │ └── utils.py │ └── core │ │ ├── __init__.py │ │ ├── database.py │ │ ├── guest.py │ │ ├── plugins.py │ │ ├── resultserver.py │ │ ├── scheduler.py │ │ └── startup.py ├── hpfeeds.py └── maec │ ├── __init__.py │ ├── maec11.py │ └── maec40.py ├── modules ├── __init__.py ├── auxiliary │ ├── __init__.py │ └── sniffer.py ├── machinery │ ├── __init__.py │ ├── esx.py │ ├── kvm.py │ ├── virtualbox.py │ └── vmware.py ├── processing │ ├── __init__.py │ ├── analysisinfo.py │ ├── behavior.py │ ├── debug.py │ ├── dropped.py │ ├── memory.py │ ├── memoryanalysis.py │ ├── network.py │ ├── static.py │ ├── strings.py │ ├── targetinfo.py │ └── virustotal.py ├── reporting │ ├── __init__.py │ ├── hpfclient.py │ ├── jsondump.py │ ├── maec40.py │ ├── mmdef.py │ ├── mongodb.py │ └── reporthtml.py └── signatures │ ├── __init__.py │ ├── creates_exe.py │ └── generic_metrics.py ├── tests ├── abstracts_tests.py ├── colors_tests.py ├── config_tests.py ├── objects_tests.py ├── processor_tests.py ├── reporter_tests.py ├── sniffer_tests.py └── utils_tests.py ├── utils ├── api.py ├── clean.sh ├── community.py ├── process.py ├── stats.py ├── submit.py └── web.py └── web ├── analysis ├── __init__.py ├── forms.py ├── urls.py └── views.py ├── dashboard ├── __init__.py ├── urls.py └── views.py ├── manage.py ├── static ├── css │ ├── bootstrap-responsive.min.css │ ├── bootstrap.min.css │ ├── lightbox.css │ └── style.css ├── fonts │ ├── glyphicons-halflings-regular.eot │ ├── glyphicons-halflings-regular.svg │ ├── glyphicons-halflings-regular.ttf │ └── glyphicons-halflings-regular.woff ├── graphic │ ├── background.png │ └── cuckoo.png ├── img │ ├── close.png │ ├── loading.gif │ ├── next.png │ └── prev.png └── js │ ├── bootstrap-fileupload.js │ ├── bootstrap.min.js │ ├── jquery.js │ └── lightbox.js ├── submission ├── __init__.py ├── urls.py └── views.py ├── templates ├── analysis │ ├── behavior │ │ ├── _chunk.html │ │ ├── _processes.html │ │ ├── _tree.html │ │ ├── _tree_process.html │ │ └── index.html │ ├── dropped │ │ └── index.html │ ├── index.html │ ├── memory │ │ ├── _malfind.html │ │ ├── _modscan.html │ │ ├── _pslist.html │ │ ├── _svcscan.html │ │ └── index.html │ ├── network │ │ ├── _dns.html │ │ ├── _hosts.html │ │ ├── _http.html │ │ ├── _icmp.html │ │ ├── _irc.html │ │ └── index.html │ ├── overview │ │ ├── _file.html │ │ ├── _info.html │ │ ├── _screenshots.html │ │ ├── _signatures.html │ │ ├── _summary.html │ │ ├── _url.html │ │ └── index.html │ ├── pending.html │ ├── report.html │ ├── search.html │ └── static │ │ ├── _antivirus.html │ │ ├── _pe32.html │ │ ├── _strings.html │ │ └── index.html ├── base.html ├── dashboard │ └── index.html ├── error.html ├── footer.html ├── header.html ├── submission │ └── index.html └── success.html └── web ├── __init__.py ├── headers.py ├── local_settings.py ├── settings.py ├── upload.py ├── urls.py └── wsgi.py /.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore Cuckoo Database 2 | db/cuckoo.db 3 | 4 | # Ignore Cuckoo logs 5 | log/*.log 6 | 7 | # Ignore Cuckoo analyses 8 | storage/* 9 | 10 | # Ignore Python byte code 11 | *.pyc 12 | 13 | # Ignore certificates 14 | *.pem 15 | *.cert 16 | 17 | # Ignore OS generated files 18 | .DS_Store* 19 | ehthumbs.db 20 | Icon? 21 | Thumbs.db 22 | -------------------------------------------------------------------------------- /IDA/idag_patched.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djteller/MemoryAnalysis/13554135ec4614e1fa2a051c1ba76525a92eac1a/IDA/idag_patched.exe -------------------------------------------------------------------------------- /IDA/script.idc: -------------------------------------------------------------------------------- 1 | // 2 | // Reference Lister 3 | // 4 | // List all functions and all references to them in the current section. 5 | // 6 | // Implemented in IDC 7 | // 8 | #include 9 | 10 | 11 | static get_disasm_blob(f, func_start, func_end) 12 | { 13 | auto curAddr, endAddr; 14 | curAddr = func_start; 15 | endAddr = func_end; 16 | 17 | while ((curAddr <= endAddr) && (curAddr != 0xffffffff)) { 18 | fprintf(f, GetDisasm(curAddr)); 19 | fprintf(f, "\n"); 20 | curAddr = NextHead(curAddr, endAddr); 21 | 22 | } 23 | 24 | } 25 | static FuncDump(start) 26 | { 27 | auto ea, str, count, ref, x, i, f; 28 | auto end; 29 | auto teststr; 30 | f = fopen("/tmp/functions", "a+"); 31 | ea = start; 32 | 33 | while( ea != BADADDR ) 34 | { 35 | str = GetFunctionName(ea); 36 | if( str != 0 ) 37 | { 38 | end = FindFuncEnd(ea); 39 | 40 | count = 0; 41 | ref = RfirstB(ea); 42 | while(ref != BADADDR) 43 | { 44 | count = count + 1; 45 | ref = RnextB(ea, ref); 46 | } 47 | 48 | teststr = form("sub_%X", ea); 49 | if( teststr == str ) 50 | { 51 | //fprintf(f, "-s 0x%X=%s\n", ea, str ); 52 | 53 | 54 | fprintf(f, "%s^", str); 55 | // fprintf(f, form("%s,", GetDisasm(ea)) ); 56 | 57 | for ( i=ea; i < end; i=i+1 ) { 58 | x = Byte(i); // fetch the byte 59 | //Message(x); 60 | fprintf(f, form("%x",x)); 61 | } 62 | 63 | fprintf(f, "^"); 64 | //Message(form("%d", end)); 65 | get_disasm_blob(f, ea, end); 66 | fprintf(f, "--------------\n"); 67 | 68 | //Message("%s, 0x%d, 0x%x, 0x%x, 0x%x, %d, 0x%x\n", str, count, ea, end, end-ea, end-ea, x ); 69 | } 70 | 71 | } 72 | 73 | ea = NextFunction(ea); 74 | } 75 | 76 | 77 | } 78 | 79 | static main() 80 | { 81 | auto ea, func, ref; 82 | Wait(); 83 | //Message("FuncDump: Start\n"); 84 | 85 | 86 | FuncDump(0x40000); 87 | 88 | //Message("FuncDump: Done\n"); 89 | 90 | 91 | // Get current ea 92 | //ea = ScreenEA(); 93 | 94 | // Loop from start to end in the current segment 95 | /*for (func=SegStart(ea); 96 | func != BADADDR && func < SegEnd(ea); 97 | func=NextFunction(func)) 98 | { 99 | // If the current address is function process it 100 | if (GetFunctionFlags(func) != -1) 101 | { 102 | //Message("Function %s at 0x%x\n", GetFunctionName(func), func); 103 | 104 | // Find all code references to func 105 | for (ref=RfirstB(func); ref != BADADDR; ref=RnextB(func, ref)) 106 | { 107 | //Message(" called from %s(0x%x)\n", GetFunctionName(ref), ref); 108 | } 109 | 110 | } 111 | } 112 | */ 113 | } 114 | 115 | 116 | 117 | 118 | -------------------------------------------------------------------------------- /WP_AND_PRESENTATION/Automated Memory Analysis - Slide.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djteller/MemoryAnalysis/13554135ec4614e1fa2a051c1ba76525a92eac1a/WP_AND_PRESENTATION/Automated Memory Analysis - Slide.pdf -------------------------------------------------------------------------------- /WP_AND_PRESENTATION/Automated Memory Analysis - WP.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djteller/MemoryAnalysis/13554135ec4614e1fa2a051c1ba76525a92eac1a/WP_AND_PRESENTATION/Automated Memory Analysis - WP.pdf -------------------------------------------------------------------------------- /analyzer/windows/bin/execsc.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djteller/MemoryAnalysis/13554135ec4614e1fa2a051c1ba76525a92eac1a/analyzer/windows/bin/execsc.exe -------------------------------------------------------------------------------- /analyzer/windows/dll/cuckoomon.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djteller/MemoryAnalysis/13554135ec4614e1fa2a051c1ba76525a92eac1a/analyzer/windows/dll/cuckoomon.dll -------------------------------------------------------------------------------- /analyzer/windows/dll/cuckoomon_bson.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djteller/MemoryAnalysis/13554135ec4614e1fa2a051c1ba76525a92eac1a/analyzer/windows/dll/cuckoomon_bson.dll -------------------------------------------------------------------------------- /analyzer/windows/dll/cuckoomon_netlog.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djteller/MemoryAnalysis/13554135ec4614e1fa2a051c1ba76525a92eac1a/analyzer/windows/dll/cuckoomon_netlog.dll -------------------------------------------------------------------------------- /analyzer/windows/lib/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2010-2014 Cuckoo Sandbox Developers. 2 | # This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org 3 | # See the file 'docs/LICENSE' for copying permission. 4 | -------------------------------------------------------------------------------- /analyzer/windows/lib/api/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2010-2014 Cuckoo Sandbox Developers. 2 | # This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org 3 | # See the file 'docs/LICENSE' for copying permission. 4 | -------------------------------------------------------------------------------- /analyzer/windows/lib/api/screenshot.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2010-2014 Cuckoo Sandbox Developers. 2 | # This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org 3 | # See the file 'docs/LICENSE' for copying permission. 4 | 5 | import math 6 | 7 | try: 8 | import ImageChops 9 | import ImageGrab 10 | HAVE_PIL = True 11 | except: 12 | HAVE_PIL = False 13 | 14 | class Screenshot: 15 | """Get screenshots.""" 16 | 17 | def have_pil(self): 18 | """Is Python Image Library installed? 19 | @return: installed status. 20 | """ 21 | return HAVE_PIL 22 | 23 | def equal(self, img1, img2): 24 | """Compares two screenshots using Root-Mean-Square Difference (RMS). 25 | @param img1: screenshot to compare. 26 | @param img2: screenshot to compare. 27 | @return: equal status. 28 | """ 29 | if not HAVE_PIL: 30 | return None 31 | 32 | # To get a measure of how similar two images are, we use 33 | # root-mean-square (RMS). If the images are exactly identical, 34 | # this value is zero. 35 | diff = ImageChops.difference(img1, img2) 36 | h = diff.histogram() 37 | sq = (value*((idx%256)**2) for idx, value in enumerate(h)) 38 | sum_of_squares = sum(sq) 39 | rms = math.sqrt(sum_of_squares/float(img1.size[0] * img1.size[1])) 40 | 41 | # Might need to tweak the threshold. 42 | return rms < 8 43 | 44 | def take(self): 45 | """Take a screenshot. 46 | @return: screenshot or None. 47 | """ 48 | if not HAVE_PIL: 49 | return None 50 | 51 | return ImageGrab.grab() 52 | -------------------------------------------------------------------------------- /analyzer/windows/lib/common/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2010-2014 Cuckoo Sandbox Developers. 2 | # This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org 3 | # See the file 'docs/LICENSE' for copying permission. 4 | -------------------------------------------------------------------------------- /analyzer/windows/lib/common/abstracts.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2010-2014 Cuckoo Sandbox Developers. 2 | # This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org 3 | # See the file 'docs/LICENSE' for copying permission. 4 | 5 | class Package(object): 6 | """Base abstact analysis package.""" 7 | 8 | def __init__(self, options={}): 9 | """@param options: options dict.""" 10 | self.options = options 11 | self.pids = [] 12 | 13 | def set_pids(self, pids): 14 | """Update list of monitored PIDs in the package context. 15 | @param pids: list of pids. 16 | """ 17 | self.pids = pids 18 | 19 | def start(self): 20 | """Run analysis packege. 21 | @param path: sample path. 22 | @raise NotImplementedError: this method is abstract. 23 | """ 24 | raise NotImplementedError 25 | 26 | def check(self): 27 | """Check. 28 | @raise NotImplementedError: this method is abstract. 29 | """ 30 | raise NotImplementedError 31 | 32 | def finish(self): 33 | """Finish run. 34 | @raise NotImplementedError: this method is abstract. 35 | """ 36 | raise NotImplementedError 37 | 38 | 39 | class Auxiliary(object): 40 | pass 41 | -------------------------------------------------------------------------------- /analyzer/windows/lib/common/constants.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2010-2014 Cuckoo Sandbox Developers. 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 lib.common.rand import random_string 7 | 8 | 9 | ROOT = os.path.join(os.getenv("SystemDrive"), "\\", random_string(6, 10)) 10 | 11 | PATHS = {"root" : ROOT, 12 | "logs" : os.path.join(ROOT, "logs"), 13 | "files" : os.path.join(ROOT, "files"), 14 | "shots" : os.path.join(ROOT, "shots"), 15 | "memory" : os.path.join(ROOT, "memory"), 16 | "drop" : os.path.join(ROOT, "drop")} 17 | 18 | PIPE = "\\\\.\\PIPE\\" + random_string(6, 10) 19 | -------------------------------------------------------------------------------- /analyzer/windows/lib/common/exceptions.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2010-2014 Cuckoo Sandbox Developers. 2 | # This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org 3 | # See the file 'docs/LICENSE' for copying permission. 4 | 5 | 6 | class CuckooError(Exception): 7 | pass 8 | 9 | 10 | class CuckooPackageError(Exception): 11 | pass 12 | -------------------------------------------------------------------------------- /analyzer/windows/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/windows/lib/common/results.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2010-2014 Cuckoo Sandbox Developers. 2 | # This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org 3 | # See the file 'docs/LICENSE' for copying permission. 4 | 5 | import logging 6 | import socket 7 | 8 | from lib.core.config import Config 9 | 10 | log = logging.getLogger(__name__) 11 | 12 | BUFSIZE = 16 * 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 | tmp = infd.read(BUFSIZE) 21 | while tmp: 22 | nc.send(tmp) 23 | tmp = infd.read(BUFSIZE) 24 | except Exception as e: 25 | log.error("Exception uploading file to host: %s", 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 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 41 | try: 42 | s.connect((self.hostip, self.hostport)) 43 | s.sendall(self.proto) 44 | except: 45 | pass 46 | else: 47 | self.sock = s 48 | self.file = s.makefile() 49 | 50 | def send(self, data, retry=True): 51 | try: 52 | self.sock.sendall(data) 53 | except socket.error: 54 | self.connect() 55 | if retry: 56 | self.send(data, retry=False) 57 | except: 58 | # We really have nowhere to log this, if the netlog connection 59 | # does not work, we can assume that any logging won't work either. 60 | # So we just fail silently. 61 | self.close() 62 | 63 | def close(self): 64 | try: 65 | self.file.close() 66 | self.sock.close() 67 | except socket.error: 68 | pass 69 | 70 | class NetlogFile(NetlogConnection): 71 | def __init__(self, filepath): 72 | self.filepath = filepath 73 | NetlogConnection.__init__(self, proto="FILE\n{0}\n".format(self.filepath)) 74 | self.connect() 75 | 76 | class NetlogHandler(logging.Handler, NetlogConnection): 77 | def __init__(self): 78 | logging.Handler.__init__(self) 79 | NetlogConnection.__init__(self, proto="LOG\n") 80 | self.connect() 81 | 82 | def emit(self, record): 83 | msg = self.format(record) 84 | self.send("{0}\n".format(msg)) 85 | -------------------------------------------------------------------------------- /analyzer/windows/lib/core/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2010-2014 Cuckoo Sandbox Developers. 2 | # This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org 3 | # See the file 'docs/LICENSE' for copying permission. 4 | -------------------------------------------------------------------------------- /analyzer/windows/lib/core/config.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2010-2014 Cuckoo Sandbox Developers. 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 | -------------------------------------------------------------------------------- /analyzer/windows/lib/core/packages.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2010-2014 Cuckoo Sandbox Developers. 2 | # This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org 3 | # See the file 'docs/LICENSE' for copying permission. 4 | 5 | def choose_package(file_type, file_name): 6 | """Choose analysis package due to file type and file extension. 7 | @param file_type: file type. 8 | @return: package or None. 9 | """ 10 | if not file_type: 11 | return None 12 | 13 | file_name = file_name.lower() 14 | 15 | if "DLL" in file_type: 16 | return "dll" 17 | elif "PE32" in file_type or "MS-DOS" in file_type: 18 | return "exe" 19 | elif "PDF" in file_type or file_name.endswith(".pdf"): 20 | return "pdf" 21 | elif "Rich Text Format" in file_type or \ 22 | "Microsoft Word" in file_type or \ 23 | "Microsoft Office Word" in file_type or \ 24 | ("Composite Document File" in file_type and not "Installer" in file_type) or \ 25 | file_name.endswith(".docx") or \ 26 | file_name.endswith(".doc") or \ 27 | file_name.endswith(".rtf"): 28 | return "doc" 29 | elif "Microsoft Office Excel" in file_type or file_name.endswith(".xlsx") or file_name.endswith(".xls"): 30 | return "xls" 31 | elif "HTML" in file_type or file_name.endswith(".htm") or file_name.endswith(".html"): 32 | return "html" 33 | elif file_name.endswith(".jar"): 34 | return "jar" 35 | elif "Zip" in file_type: 36 | return "zip" 37 | else: 38 | return "generic" 39 | -------------------------------------------------------------------------------- /analyzer/windows/lib/core/privileges.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2010-2014 Cuckoo Sandbox Developers. 2 | # This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org 3 | # See the file 'docs/LICENSE' for copying permission. 4 | 5 | from ctypes import wintypes, POINTER 6 | 7 | from lib.common.defines import ADVAPI32, KERNEL32, SE_PRIVILEGE_ENABLED 8 | from lib.common.defines import LUID, TOKEN_PRIVILEGES, PROCESS_ALL_ACCESS 9 | from lib.common.defines import TOKEN_ALL_ACCESS, LUID_AND_ATTRIBUTES 10 | 11 | def grant_debug_privilege(pid=None): 12 | """Grant debug privileges. 13 | @param pid: PID. 14 | @return: operation status. 15 | """ 16 | ADVAPI32.OpenProcessToken.argtypes = (wintypes.HANDLE, 17 | wintypes.DWORD, 18 | POINTER(wintypes.HANDLE)) 19 | 20 | ADVAPI32.LookupPrivilegeValueW.argtypes = (wintypes.LPWSTR, 21 | wintypes.LPWSTR, 22 | POINTER(LUID)) 23 | 24 | ADVAPI32.AdjustTokenPrivileges.argtypes = (wintypes.HANDLE, 25 | wintypes.BOOL, 26 | POINTER(TOKEN_PRIVILEGES), 27 | wintypes.DWORD, 28 | POINTER(TOKEN_PRIVILEGES), 29 | POINTER(wintypes.DWORD)) 30 | 31 | if pid is None: 32 | h_process = KERNEL32.GetCurrentProcess() 33 | else: 34 | h_process = KERNEL32.OpenProcess(PROCESS_ALL_ACCESS, False, pid) 35 | 36 | if not h_process: 37 | return False 38 | 39 | h_current_token = wintypes.HANDLE() 40 | if not ADVAPI32.OpenProcessToken(h_process, 41 | TOKEN_ALL_ACCESS, 42 | h_current_token): 43 | return False 44 | 45 | se_original_luid = LUID() 46 | if not ADVAPI32.LookupPrivilegeValueW(None, 47 | "SeDebugPrivilege", 48 | se_original_luid): 49 | return False 50 | 51 | luid_attributes = LUID_AND_ATTRIBUTES() 52 | luid_attributes.Luid = se_original_luid 53 | luid_attributes.Attributes = SE_PRIVILEGE_ENABLED 54 | token_privs = TOKEN_PRIVILEGES() 55 | token_privs.PrivilegeCount = 1 56 | token_privs.Privileges = luid_attributes 57 | 58 | if not ADVAPI32.AdjustTokenPrivileges(h_current_token, False, token_privs, 59 | 0, None, None): 60 | return False 61 | 62 | KERNEL32.CloseHandle(h_current_token) 63 | KERNEL32.CloseHandle(h_process) 64 | return True 65 | -------------------------------------------------------------------------------- /analyzer/windows/lib/core/startup.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2010-2014 Cuckoo Sandbox Developers. 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 | import logging 7 | 8 | from lib.common.constants import PATHS 9 | from lib.common.results import NetlogHandler 10 | 11 | log = logging.getLogger() 12 | 13 | def create_folders(): 14 | """Create folders in PATHS.""" 15 | for name, folder in PATHS.items(): 16 | if os.path.exists(folder): 17 | continue 18 | 19 | try: 20 | os.makedirs(folder) 21 | except OSError: 22 | pass 23 | 24 | def init_logging(): 25 | """Initialize logger.""" 26 | formatter = logging.Formatter("%(asctime)s [%(name)s] %(levelname)s: %(message)s") 27 | sh = logging.StreamHandler() 28 | sh.setFormatter(formatter) 29 | log.addHandler(sh) 30 | 31 | nh = NetlogHandler() 32 | nh.setFormatter(formatter) 33 | log.addHandler(nh) 34 | 35 | log.setLevel(logging.DEBUG) 36 | -------------------------------------------------------------------------------- /analyzer/windows/modules/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2010-2014 Cuckoo Sandbox Developers. 2 | # This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org 3 | # See the file 'docs/LICENSE' for copying permission. 4 | -------------------------------------------------------------------------------- /analyzer/windows/modules/auxiliary/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2010-2014 Cuckoo Sandbox Developers. 2 | # This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org 3 | # See the file 'docs/LICENSE' for copying permission. 4 | -------------------------------------------------------------------------------- /analyzer/windows/modules/auxiliary/disguise.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2010-2014 Cuckoo Sandbox Developers. 2 | # This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org 3 | # See the file 'docs/LICENSE' for copying permission. 4 | 5 | import logging 6 | from _winreg import OpenKey, SetValueEx 7 | from _winreg import HKEY_LOCAL_MACHINE, KEY_SET_VALUE, REG_SZ 8 | 9 | 10 | from lib.common.abstracts import Auxiliary 11 | from lib.common.rand import random_integer 12 | 13 | log = logging.getLogger(__name__) 14 | 15 | class Disguise(Auxiliary): 16 | """Disguise the analysis environment.""" 17 | 18 | def change_productid(self): 19 | """Randomizes Windows ProductId, which is occasionally used by malware 20 | to detect public setups of Cuckoo, e.g. Malwr.com. 21 | """ 22 | key = OpenKey( 23 | HKEY_LOCAL_MACHINE, 24 | "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", 25 | 0, 26 | KEY_SET_VALUE 27 | ) 28 | 29 | value = "{0}-{1}-{2}-{3}".format( 30 | random_integer(5), 31 | random_integer(3), 32 | random_integer(7), 33 | random_integer(5) 34 | ) 35 | 36 | SetValueEx(key, "ProductId", 0, REG_SZ, value) 37 | 38 | def start(self): 39 | self.change_productid() 40 | return True 41 | -------------------------------------------------------------------------------- /analyzer/windows/modules/auxiliary/screenshots.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2010-2014 Cuckoo Sandbox Developers. 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 logging 7 | import StringIO 8 | from threading import Thread 9 | 10 | from lib.common.abstracts import Auxiliary 11 | from lib.common.results import NetlogFile 12 | from lib.api.screenshot import Screenshot 13 | 14 | log = logging.getLogger(__name__) 15 | SHOT_DELAY = 1 16 | 17 | class Screenshots(Auxiliary, Thread): 18 | """Take screenshots.""" 19 | 20 | def __init__(self): 21 | Thread.__init__(self) 22 | self.do_run = True 23 | 24 | def stop(self): 25 | """Stop screenshotting.""" 26 | self.do_run = False 27 | 28 | def run(self): 29 | """Run screenshotting. 30 | @return: operation status. 31 | """ 32 | if not Screenshot().have_pil(): 33 | log.warning("Python Image Library is not installed, " 34 | "screenshots are disabled") 35 | return False 36 | 37 | img_counter = 0 38 | img_last = None 39 | 40 | while self.do_run: 41 | time.sleep(SHOT_DELAY) 42 | 43 | try: 44 | img_current = Screenshot().take() 45 | except IOError as e: 46 | log.error("Cannot take screenshot: %s", e) 47 | continue 48 | 49 | if img_last: 50 | if Screenshot().equal(img_last, img_current): 51 | continue 52 | 53 | img_counter += 1 54 | 55 | # workaround as PIL can't write to the socket file object :( 56 | tmpio = StringIO.StringIO() 57 | img_current.save(tmpio, format="JPEG") 58 | tmpio.seek(0) 59 | 60 | # now upload to host from the StringIO 61 | nf = NetlogFile("shots/%s.jpg" % str(img_counter).rjust(4, "0")) 62 | 63 | for chunk in tmpio: 64 | nf.sock.sendall(chunk) 65 | 66 | nf.close() 67 | 68 | img_last = img_current 69 | 70 | return True 71 | -------------------------------------------------------------------------------- /analyzer/windows/modules/packages/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2010-2014 Cuckoo Sandbox Developers. 2 | # This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org 3 | # See the file 'docs/LICENSE' for copying permission. 4 | -------------------------------------------------------------------------------- /analyzer/windows/modules/packages/applet.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2010-2014 Cuckoo Sandbox Developers. 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 | import string 7 | import random 8 | 9 | from lib.common.abstracts import Package 10 | from lib.api.process import Process 11 | from lib.common.exceptions import CuckooPackageError 12 | 13 | class Applet(Package): 14 | """Java Applet analysis package.""" 15 | 16 | def get_path(self): 17 | prog_files = os.getenv("ProgramFiles") 18 | paths = [ 19 | os.path.join(prog_files, "Mozilla Firefox", "firefox.exe"), 20 | os.path.join(prog_files, "Internet Explorer", "iexplore.exe"), 21 | ] 22 | 23 | for path in paths: 24 | if os.path.exists(path): 25 | return path 26 | 27 | return None 28 | 29 | def make_html(self, path, class_name): 30 | html = "" 31 | html += "" 32 | html += "" % (path, class_name) 33 | html += "" 34 | html += "" 35 | html += "" 36 | 37 | file_name = "".join(random.choice(string.ascii_lowercase) for x in range(6)) + ".html" 38 | file_path = os.path.join(os.getenv("TEMP"), file_name) 39 | with open(file_path, "w") as file_handle: 40 | file_handle.write(html) 41 | 42 | return file_path 43 | 44 | def start(self, path): 45 | browser = self.get_path() 46 | if not browser: 47 | raise CuckooPackageError("Unable to find any browser " 48 | "executable available") 49 | 50 | dll = self.options.get("dll", None) 51 | free = self.options.get("free", False) 52 | class_name = self.options.get("class", None) 53 | suspended = True 54 | if free: 55 | suspended = False 56 | 57 | html_path = self.make_html(path, class_name) 58 | 59 | p = Process() 60 | if not p.execute(path=browser, args="\"%s\"" % html_path, suspended=suspended): 61 | raise CuckooPackageError("Unable to execute initial Internet " 62 | "Explorer process, analysis aborted") 63 | 64 | if not free and suspended: 65 | p.inject(dll) 66 | p.resume() 67 | return p.pid 68 | else: 69 | return None 70 | 71 | def check(self): 72 | return True 73 | 74 | def finish(self): 75 | if self.options.get("procmemdump", False): 76 | for pid in self.pids: 77 | p = Process(pid=pid) 78 | p.dump_memory() 79 | 80 | return True 81 | -------------------------------------------------------------------------------- /analyzer/windows/modules/packages/bin.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2010-2014 Cuckoo Sandbox Developers. 2 | # This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org 3 | # See the file 'docs/LICENSE' for copying permission. 4 | 5 | from lib.common.abstracts import Package 6 | from lib.api.process import Process 7 | 8 | class Shellcode(Package): 9 | """Shellcode (any x86 executable code) analysis package.""" 10 | 11 | def start(self, path): 12 | p = Process() 13 | dll = self.options.get("dll") 14 | p.execute(path="bin/execsc.exe", args=path, suspended=True) 15 | p.inject(dll) 16 | p.resume() 17 | 18 | return p.pid 19 | 20 | def check(self): 21 | return True 22 | 23 | def finish(self): 24 | if self.options.get("procmemdump", False): 25 | for pid in self.pids: 26 | p = Process(pid=pid) 27 | p.dump_memory() 28 | 29 | return True 30 | -------------------------------------------------------------------------------- /analyzer/windows/modules/packages/cpl.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2010-2014 Cuckoo Sandbox Developers. 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 | 7 | from lib.common.abstracts import Package 8 | from lib.api.process import Process 9 | from lib.common.exceptions import CuckooPackageError 10 | 11 | class CPL(Package): 12 | """Control Panel Applet analysis package.""" 13 | 14 | def get_path(self): 15 | path = os.path.join(os.getenv("SystemRoot"), "system32", "control.exe") 16 | if os.path.exists(path): 17 | return path 18 | 19 | return 20 | 21 | def start(self, path): 22 | control = self.get_path() 23 | if not control: 24 | raise CuckooPackageError("Unable to find any control.exe " 25 | "executable available") 26 | 27 | dll = self.options.get("dll", None) 28 | free = self.options.get("free", False) 29 | suspended = True 30 | if free: 31 | suspended = False 32 | 33 | p = Process() 34 | if not p.execute(path=control, args="\"%s\"" % path, 35 | suspended=suspended): 36 | raise CuckooPackageError("Unable to execute initial Control " 37 | "process, analysis aborted") 38 | 39 | if not free and suspended: 40 | p.inject(dll) 41 | p.resume() 42 | return p.pid 43 | else: 44 | return None 45 | 46 | def check(self): 47 | return True 48 | 49 | def finish(self): 50 | if self.options.get("procmemdump", False): 51 | for pid in self.pids: 52 | p = Process(pid=pid) 53 | p.dump_memory() 54 | 55 | return True 56 | -------------------------------------------------------------------------------- /analyzer/windows/modules/packages/dll.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2010-2014 Cuckoo Sandbox Developers. 2 | # This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org 3 | # See the file 'docs/LICENSE' for copying permission. 4 | 5 | from lib.common.abstracts import Package 6 | from lib.api.process import Process 7 | from lib.common.exceptions import CuckooPackageError 8 | 9 | class Dll(Package): 10 | """DLL analysis package.""" 11 | 12 | def start(self, path): 13 | free = self.options.get("free", False) 14 | function = self.options.get("function", "DllMain") 15 | arguments = self.options.get("arguments", None) 16 | dll = self.options.get("dll", None) 17 | suspended = True 18 | if free: 19 | suspended = False 20 | 21 | args = "{0},{1}".format(path, function) 22 | if arguments: 23 | args += " {0}".format(arguments) 24 | 25 | p = Process() 26 | if not p.execute(path="C:\\WINDOWS\\system32\\rundll32.exe", args=args, suspended=suspended): 27 | raise CuckooPackageError("Unable to execute rundll32, " 28 | "analysis aborted") 29 | 30 | if not free and suspended: 31 | p.inject(dll) 32 | p.resume() 33 | return p.pid 34 | else: 35 | return None 36 | 37 | def check(self): 38 | return True 39 | 40 | def finish(self): 41 | if self.options.get("procmemdump", False): 42 | for pid in self.pids: 43 | p = Process(pid=pid) 44 | p.dump_memory() 45 | 46 | return True 47 | -------------------------------------------------------------------------------- /analyzer/windows/modules/packages/doc.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2010-2014 Cuckoo Sandbox Developers. 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 | 7 | from lib.common.abstracts import Package 8 | from lib.api.process import Process 9 | from lib.common.exceptions import CuckooPackageError 10 | 11 | class DOC(Package): 12 | """Word analysis package.""" 13 | 14 | def get_path(self): 15 | ms_office = os.path.join(os.getenv("ProgramFiles"), "Microsoft Office") 16 | paths = [ 17 | os.path.join(ms_office, "WINWORD.EXE"), 18 | os.path.join(ms_office, "Office11", "WINWORD.EXE"), 19 | os.path.join(ms_office, "Office12", "WINWORD.EXE"), 20 | os.path.join(ms_office, "Office14", "WINWORD.EXE"), 21 | os.path.join(ms_office, "Office15", "WINWORD.EXE"), 22 | os.path.join(ms_office, "WORDVIEW.EXE"), 23 | os.path.join(ms_office, "Office11", "WORDVIEW.EXE") 24 | ] 25 | 26 | for path in paths: 27 | if os.path.exists(path): 28 | return path 29 | 30 | return None 31 | 32 | def start(self, path): 33 | word = self.get_path() 34 | if not word: 35 | raise CuckooPackageError("Unable to find any Microsoft " 36 | "Office Word executable available") 37 | 38 | dll = self.options.get("dll", None) 39 | free = self.options.get("free", False) 40 | suspended = True 41 | if free: 42 | suspended = False 43 | 44 | p = Process() 45 | if not p.execute(path=word, args="\"%s\"" % path, suspended=suspended): 46 | raise CuckooPackageError("Unable to execute initial Microsoft " 47 | "Office Word process, analysis aborted") 48 | 49 | if not free and suspended: 50 | p.inject(dll) 51 | p.resume() 52 | return p.pid 53 | else: 54 | return None 55 | 56 | def check(self): 57 | return True 58 | 59 | def finish(self): 60 | if self.options.get("procmemdump", False): 61 | for pid in self.pids: 62 | p = Process(pid=pid) 63 | p.dump_memory() 64 | 65 | return True 66 | -------------------------------------------------------------------------------- /analyzer/windows/modules/packages/exe.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2010-2014 Cuckoo Sandbox Developers. 2 | # This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org 3 | # See the file 'docs/LICENSE' for copying permission. 4 | 5 | from lib.common.abstracts import Package 6 | from lib.api.process import Process 7 | from lib.common.exceptions import CuckooPackageError 8 | 9 | class Exe(Package): 10 | """EXE analysis package.""" 11 | 12 | def start(self, path): 13 | free = self.options.get("free", False) 14 | args = self.options.get("arguments", None) 15 | dll = self.options.get("dll", None) 16 | suspended = True 17 | if free: 18 | suspended = False 19 | 20 | p = Process() 21 | if not p.execute(path=path, args=args, suspended=suspended): 22 | raise CuckooPackageError("Unable to execute initial process, " 23 | "analysis aborted") 24 | 25 | if not free and suspended: 26 | p.inject(dll) 27 | p.resume() 28 | p.close() 29 | return p.pid 30 | else: 31 | return None 32 | 33 | def check(self): 34 | return True 35 | 36 | def finish(self): 37 | if self.options.get("procmemdump", False): 38 | for pid in self.pids: 39 | p = Process(pid=pid) 40 | p.dump_memory() 41 | 42 | return True 43 | -------------------------------------------------------------------------------- /analyzer/windows/modules/packages/generic.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2010-2014 Cuckoo Sandbox Developers. 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 | 7 | from lib.common.abstracts import Package 8 | from lib.api.process import Process 9 | from lib.common.exceptions import CuckooPackageError 10 | 11 | class Genric(Package): 12 | """Generic analysis package.""" 13 | 14 | def start(self, path): 15 | free = self.options.get("free", False) 16 | dll = self.options.get("dll", None) 17 | suspended = True 18 | if free: 19 | suspended = False 20 | 21 | cmd_path = os.path.join(os.getenv("SystemRoot"), "system32", "cmd.exe") 22 | cmd_args = "/c start \"{0}\"".format(path) 23 | 24 | p = Process() 25 | if not p.execute(path=cmd_path, args=cmd_args, suspended=suspended): 26 | raise CuckooPackageError("Unable to execute initial process, " 27 | "analysis aborted") 28 | 29 | if not free and suspended: 30 | p.inject(dll) 31 | p.resume() 32 | p.close() 33 | return p.pid 34 | else: 35 | return None 36 | 37 | def check(self): 38 | return True 39 | 40 | def finish(self): 41 | if self.options.get("procmemdump", False): 42 | for pid in self.pids: 43 | p = Process(pid=pid) 44 | p.dump_memory() 45 | 46 | return True 47 | -------------------------------------------------------------------------------- /analyzer/windows/modules/packages/html.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2010-2014 Cuckoo Sandbox Developers. 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 | 7 | from lib.common.abstracts import Package 8 | from lib.api.process import Process 9 | from lib.common.exceptions import CuckooPackageError 10 | 11 | class HTML(Package): 12 | """HTML file analysis package.""" 13 | 14 | def start(self, path): 15 | free = self.options.get("free", False) 16 | dll = self.options.get("dll", None) 17 | suspended = True 18 | if free: 19 | suspended = False 20 | 21 | iexplore = os.path.join(os.getenv("ProgramFiles"), "Internet Explorer", "iexplore.exe") 22 | 23 | p = Process() 24 | if not p.execute(path=iexplore, args="\"%s\"" % path, suspended=suspended): 25 | raise CuckooPackageError("Unable to execute initial Internet " 26 | "Explorer process, analysis aborted") 27 | 28 | if not free and suspended: 29 | p.inject(dll) 30 | p.resume() 31 | return p.pid 32 | else: 33 | return None 34 | 35 | def check(self): 36 | return True 37 | 38 | def finish(self): 39 | if self.options.get("procmemdump", False): 40 | for pid in self.pids: 41 | p = Process(pid=pid) 42 | p.dump_memory() 43 | 44 | return True 45 | -------------------------------------------------------------------------------- /analyzer/windows/modules/packages/ie.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2010-2014 Cuckoo Sandbox Developers. 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 | 7 | from lib.common.abstracts import Package 8 | from lib.api.process import Process 9 | from lib.common.exceptions import CuckooPackageError 10 | 11 | 12 | class IE(Package): 13 | """Internet Explorer analysis package.""" 14 | 15 | def start(self, url): 16 | free = self.options.get("free", False) 17 | dll = self.options.get("dll", None) 18 | suspended = True 19 | if free: 20 | suspended = False 21 | 22 | iexplore = os.path.join(os.getenv("ProgramFiles"), "Internet Explorer", "iexplore.exe") 23 | 24 | p = Process() 25 | if not p.execute(path=iexplore, args="\"%s\"" % url, suspended=suspended): 26 | raise CuckooPackageError("Unable to execute initial Internet " 27 | "Explorer process, analysis aborted") 28 | 29 | if not free and suspended: 30 | p.inject(dll) 31 | p.resume() 32 | return p.pid 33 | else: 34 | return None 35 | 36 | def check(self): 37 | return True 38 | 39 | def finish(self): 40 | if self.options.get("procmemdump", False): 41 | for pid in self.pids: 42 | p = Process(pid=pid) 43 | p.dump_memory() 44 | 45 | return True 46 | -------------------------------------------------------------------------------- /analyzer/windows/modules/packages/jar.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2010-2014 Cuckoo Sandbox Developers. 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 | 7 | from lib.common.abstracts import Package 8 | from lib.api.process import Process 9 | from lib.common.exceptions import CuckooPackageError 10 | 11 | class Jar(Package): 12 | """Java analysis package.""" 13 | 14 | def get_path(self): 15 | java = os.path.join(os.getenv("ProgramFiles"), "Java") 16 | paths = [ 17 | os.path.join(java, "jre7", "bin", "java.exe"), 18 | os.path.join(java, "jre6", "bin", "java.exe"), 19 | ] 20 | 21 | for path in paths: 22 | if os.path.exists(path): 23 | return path 24 | 25 | return None 26 | 27 | def start(self, path): 28 | java = self.get_path() 29 | if not java: 30 | raise CuckooPackageError("Unable to find any Java " 31 | "executable available") 32 | 33 | dll = self.options.get("dll", None) 34 | free = self.options.get("free", False) 35 | class_path = self.options.get("class", None) 36 | suspended = True 37 | if free: 38 | suspended = False 39 | 40 | if class_path: 41 | args = "-cp \"%s\" %s" % (path, class_path) 42 | else: 43 | args = "-jar \"%s\"" % path 44 | 45 | p = Process() 46 | if not p.execute(path=java, args=args, suspended=suspended): 47 | raise CuckooPackageError("Unable to execute initial Java " 48 | "process, analysis aborted") 49 | 50 | if not free and suspended: 51 | p.inject(dll) 52 | p.resume() 53 | return p.pid 54 | else: 55 | return None 56 | 57 | def check(self): 58 | return True 59 | 60 | def finish(self): 61 | if self.options.get("procmemdump", False): 62 | for pid in self.pids: 63 | p = Process(pid=pid) 64 | p.dump_memory() 65 | 66 | return True 67 | -------------------------------------------------------------------------------- /analyzer/windows/modules/packages/pdf.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2010-2014 Cuckoo Sandbox Developers. 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 | 7 | from lib.common.abstracts import Package 8 | from lib.api.process import Process 9 | from lib.common.exceptions import CuckooPackageError 10 | 11 | class PDF(Package): 12 | """PDF analysis package.""" 13 | 14 | def get_path(self): 15 | adobe = os.path.join(os.getenv("ProgramFiles"), "Adobe") 16 | paths = [ 17 | os.path.join(adobe, "Reader 8.0", "Reader", "AcroRd32.exe"), 18 | os.path.join(adobe, "Reader 9.0", "Reader", "AcroRd32.exe"), 19 | os.path.join(adobe, "Reader 10.0", "Reader", "AcroRd32.exe"), 20 | os.path.join(adobe, "Reader 11.0", "Reader", "AcroRd32.exe"), 21 | ] 22 | 23 | for path in paths: 24 | if os.path.exists(path): 25 | return path 26 | 27 | return None 28 | 29 | def start(self, path): 30 | reader = self.get_path() 31 | if not reader: 32 | raise CuckooPackageError("Unable to find any Adobe Reader " 33 | "executable available") 34 | 35 | dll = self.options.get("dll", None) 36 | free = self.options.get("free", False) 37 | suspended = True 38 | if free: 39 | suspended = False 40 | 41 | p = Process() 42 | if not p.execute(path=reader, args="\"%s\"" % path, suspended=suspended): 43 | raise CuckooPackageError("Unable to execute initial Adobe Reader " 44 | "process, analysis aborted") 45 | 46 | if not free and suspended: 47 | p.inject(dll) 48 | p.resume() 49 | return p.pid 50 | else: 51 | return None 52 | 53 | def check(self): 54 | return True 55 | 56 | def finish(self): 57 | if self.options.get("procmemdump", False): 58 | for pid in self.pids: 59 | p = Process(pid=pid) 60 | p.dump_memory() 61 | 62 | return True 63 | -------------------------------------------------------------------------------- /analyzer/windows/modules/packages/vbs.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2010-2014 Cuckoo Sandbox Developers. 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 | 7 | from lib.common.abstracts import Package 8 | from lib.api.process import Process 9 | from lib.common.exceptions import CuckooPackageError 10 | 11 | # Originally proposed by kidrek: 12 | # https://github.com/cuckoobox/cuckoo/pull/136 13 | 14 | class VBS(Package): 15 | """VBS analysis package.""" 16 | 17 | def get_path(self): 18 | paths = [ 19 | os.path.join(os.getenv("SystemRoot"), "system32", "wscript.exe") 20 | ] 21 | 22 | for path in paths: 23 | if os.path.exists(path): 24 | return path 25 | 26 | return None 27 | 28 | def start(self, path): 29 | wscript = self.get_path() 30 | if not wscript: 31 | raise CuckooPackageError("Unable to find any WScript " 32 | "executable available") 33 | 34 | dll = self.options.get("dll", None) 35 | free = self.options.get("free", False) 36 | suspended = True 37 | if free: 38 | suspended = False 39 | 40 | p = Process() 41 | if not p.execute(path=wscript, args="\"{0}\"".format(path), suspended=suspended): 42 | raise CuckooPackageError("Unable to execute initial WScript " 43 | "process, analysis aborted") 44 | 45 | if not free and suspended: 46 | p.inject(dll) 47 | p.resume() 48 | return p.pid 49 | else: 50 | return None 51 | 52 | def check(self): 53 | return True 54 | 55 | def finish(self): 56 | if self.options.get("procmemdump", False): 57 | for pid in self.pids: 58 | p = Process(pid=pid) 59 | p.dump_memory() 60 | 61 | return True 62 | -------------------------------------------------------------------------------- /analyzer/windows/modules/packages/xls.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2010-2014 Cuckoo Sandbox Developers. 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 | 7 | from lib.common.abstracts import Package 8 | from lib.api.process import Process 9 | from lib.common.exceptions import CuckooPackageError 10 | 11 | 12 | class XLS(Package): 13 | """Excel analysis package.""" 14 | 15 | def get_path(self): 16 | office = os.path.join(os.getenv("ProgramFiles"), "Microsoft Office") 17 | paths = [ 18 | os.path.join(office, "EXCEL.EXE"), 19 | os.path.join(office, "Office11", "EXCEL.EXE"), 20 | os.path.join(office, "Office12", "EXCEL.EXE"), 21 | os.path.join(office, "Office14", "EXCEL.EXE"), 22 | os.path.join(office, "Office15", "EXCEL.EXE"), 23 | ] 24 | 25 | for path in paths: 26 | if os.path.exists(path): 27 | return path 28 | 29 | return None 30 | 31 | def start(self, path): 32 | excel = self.get_path() 33 | if not excel: 34 | raise CuckooPackageError("Unable to find any Microsoft " 35 | "Office Excel executable available") 36 | 37 | dll = self.options.get("dll", None) 38 | free = self.options.get("free", False) 39 | suspended = True 40 | if free: 41 | suspended = False 42 | 43 | p = Process() 44 | if not p.execute(path=excel, args="\"%s\"" % path, suspended=suspended): 45 | raise CuckooPackageError("Unable to execute initial Microsoft " 46 | "Office Excel process, analysis aborted") 47 | 48 | if not free and suspended: 49 | p.inject(dll) 50 | p.resume() 51 | return p.pid 52 | else: 53 | return None 54 | 55 | def check(self): 56 | return True 57 | 58 | def finish(self): 59 | if self.options.get("procmemdump", False): 60 | for pid in self.pids: 61 | p = Process(pid=pid) 62 | p.dump_memory() 63 | 64 | return True 65 | -------------------------------------------------------------------------------- /analyzer/windows/modules/packages/zip.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2010-2014 Cuckoo Sandbox Developers. 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 zipfile import ZipFile, BadZipfile 7 | 8 | from lib.common.abstracts import Package 9 | from lib.common.exceptions import CuckooPackageError 10 | from lib.api.process import Process 11 | 12 | class Zip(Package): 13 | """Zip analysis package.""" 14 | 15 | def start(self, path): 16 | root = os.environ["TEMP"] 17 | password = self.options.get("password", None) 18 | default_file_name = "sample.exe" 19 | 20 | with ZipFile(path, "r") as archive: 21 | zipinfos = archive.infolist() 22 | try: 23 | archive.extractall(path=root, pwd=password) 24 | except BadZipfile as e: 25 | raise CuckooPackageError("Invalid Zip file") 26 | except RuntimeError: 27 | try: 28 | password = self.options.get("password", "infected") 29 | archive.extractall(path=root, pwd=password) 30 | except RuntimeError as e: 31 | raise CuckooPackageError("Unable to extract Zip file: " 32 | "{0}".format(e)) 33 | 34 | file_name = self.options.get("file", default_file_name) 35 | if file_name == default_file_name: 36 | #no name provided try to find a better name 37 | if len(zipinfos) > 0: 38 | #take the first one 39 | file_name = zipinfos[0].filename 40 | 41 | file_path = os.path.join(root, file_name) 42 | 43 | dll = self.options.get("dll", None) 44 | free = self.options.get("free", False) 45 | args = self.options.get("arguments", None) 46 | suspended = True 47 | if free: 48 | suspended = False 49 | 50 | p = Process() 51 | if not p.execute(path=file_path, args=args, suspended=suspended): 52 | raise CuckooPackageError("Unable to execute initial process, " 53 | "analysis aborted") 54 | 55 | if not free and suspended: 56 | p.inject(dll) 57 | p.resume() 58 | return p.pid 59 | else: 60 | return None 61 | 62 | def check(self): 63 | return True 64 | 65 | def finish(self): 66 | if self.options.get("procmemdump", False): 67 | for pid in self.pids: 68 | p = Process(pid=pid) 69 | p.dump_memory() 70 | 71 | return True 72 | -------------------------------------------------------------------------------- /conf/auxiliary.conf: -------------------------------------------------------------------------------- 1 | [sniffer] 2 | # Enable or disable the use of an external sniffer (tcpdump) [yes/no]. 3 | enabled = yes 4 | 5 | # Specify the path to your local installation of tcpdump. Make sure this 6 | # path is correct. 7 | tcpdump = /usr/sbin/tcpdump 8 | 9 | # Specify the network interface name on which tcpdump should monitor the 10 | # traffic. Make sure the interface is active. 11 | interface = vboxnet0 12 | 13 | # Specify a Berkeley packet filter to pass to tcpdump. 14 | # bpf = not arp 15 | -------------------------------------------------------------------------------- /conf/esx.conf: -------------------------------------------------------------------------------- 1 | [esx] 2 | # ?no_verify disables the SSL signature check. By default it is self signed 3 | dsn = esx://127.0.0.1/?no_verify=1 4 | username = username_goes_here 5 | password = password_goes_here 6 | 7 | machines = analysis1 8 | 9 | [analysis1] 10 | # Specify the label name of the current machine as specified in your 11 | # libvirt configuration. 12 | label = cuckoo1 13 | 14 | # Specify the operating system platform used by current machine 15 | # [windows/darwin/linux]. 16 | platform = windows 17 | 18 | # Please specify the name of the base snapshot. This snapshot should be taken 19 | # with agent in startup and the machine shut down. 20 | snapshot = clean_snapshot 21 | 22 | # Specify the IP address of the current virtual machine. Make sure that the 23 | # IP address is valid and that the host machine is able to reach it. If not, 24 | # the analysis will fail. You may want to configure your network settings in 25 | # /etc/libvirt//networks/ 26 | ip = 192.168.122.105 27 | 28 | # (Optional) Specify the snapshot name to use. If you do not specify a snapshot 29 | # name, the KVM MachineManager will use the current snapshot. 30 | # Example (Snapshot1 is the snapshot name): 31 | # snapshot = Snapshot1 32 | 33 | # (Optional) Specify the name of the network interface that should be used 34 | # when dumping network traffic from this machine with tcpdump. If specified, 35 | # overrides the default interface specified in cuckoo.conf 36 | # Example (eth0 is the interface name): 37 | # interface = eth0 38 | 39 | # (Optional) Specify the IP of the Result Server, as your virtual machine sees it. 40 | # The Result Server will always bind to the address and port specified in cuckoo.conf, 41 | # however you could set up your virtual network to use NAT/PAT, so you can specify here 42 | # the IP address for the Result Server as your machine sees it. If you don't specify an 43 | # address here, the machine will use the default value from cuckoo.conf. 44 | # NOTE: if you set this option you have to set result server IP to 0.0.0.0 in cuckoo.conf. 45 | # Example: 46 | # resultserver_ip = 192.168.122.101 47 | 48 | # (Optional) Specify the port for the Result Server, as your virtual machine sees it. 49 | # The Result Server will always bind to the address and port specified in cuckoo.conf, 50 | # however you could set up your virtual network to use NAT/PAT, so you can specify here 51 | # the port for the Result Server as your machine sees it. If you don't specify a port 52 | # here, the machine will use the default value from cuckoo.conf. 53 | # Example: 54 | # resultserver_port = 2042 55 | 56 | # (Optional) Set your own tags. These are comma separated and help to identify 57 | # specific VMs. You can run samples on VMs with tag you require. 58 | # tags = windows_xp_sp3,32_bit,acrobat_reader_6 -------------------------------------------------------------------------------- /conf/kvm.conf: -------------------------------------------------------------------------------- 1 | [kvm] 2 | # Specify a comma-separated list of available machines to be used. For each 3 | # specified ID you have to define a dedicated section containing the details 4 | # on the respective machine. (E.g. cuckoo1,cuckoo2,cuckoo3) 5 | machines = cuckoo1 6 | 7 | [cuckoo1] 8 | # Specify the label name of the current machine as specified in your 9 | # libvirt configuration. 10 | label = cuckoo1 11 | 12 | # Specify the operating system platform used by current machine 13 | # [windows/darwin/linux]. 14 | platform = windows 15 | 16 | # Specify the IP address of the current virtual machine. Make sure that the 17 | # IP address is valid and that the host machine is able to reach it. If not, 18 | # the analysis will fail. You may want to configure your network settings in 19 | # /etc/libvirt//networks/ 20 | ip = 192.168.122.105 21 | 22 | # (Optional) Specify the snapshot name to use. If you do not specify a snapshot 23 | # name, the KVM MachineManager will use the current snapshot. 24 | # Example (Snapshot1 is the snapshot name): 25 | # snapshot = Snapshot1 26 | 27 | # (Optional) Specify the name of the network interface that should be used 28 | # when dumping network traffic from this machine with tcpdump. If specified, 29 | # overrides the default interface specified in cuckoo.conf 30 | # Example (virbr0 is the interface name): 31 | # interface = virbr0 32 | 33 | # (Optional) Specify the IP of the Result Server, as your virtual machine sees it. 34 | # The Result Server will always bind to the address and port specified in cuckoo.conf, 35 | # however you could set up your virtual network to use NAT/PAT, so you can specify here 36 | # the IP address for the Result Server as your machine sees it. If you don't specify an 37 | # address here, the machine will use the default value from cuckoo.conf. 38 | # NOTE: if you set this option you have to set result server IP to 0.0.0.0 in cuckoo.conf. 39 | # Example: 40 | # resultserver_ip = 192.168.122.101 41 | 42 | # (Optional) Specify the port for the Result Server, as your virtual machine sees it. 43 | # The Result Server will always bind to the address and port specified in cuckoo.conf, 44 | # however you could set up your virtual network to use NAT/PAT, so you can specify here 45 | # the port for the Result Server as your machine sees it. If you don't specify a port 46 | # here, the machine will use the default value from cuckoo.conf. 47 | # Example: 48 | # resultserver_port = 2042 49 | 50 | # (Optional) Set your own tags. These are comma separated and help to identify 51 | # specific VMs. You can run samples on VMs with tag you require. 52 | # tags = windows_xp_sp3,32_bit,acrobat_reader_6 53 | -------------------------------------------------------------------------------- /conf/processing.conf: -------------------------------------------------------------------------------- 1 | # Enable or disable the available processing modules [on/off]. 2 | # If you add a custom processing module to your Cuckoo setup, you have to add 3 | # a dedicated entry in this file, or it won't be executed. 4 | # You can also add additional options under the section of your module and 5 | # they will be available in your Python class. 6 | 7 | [analysisinfo] 8 | enabled = yes 9 | 10 | [behavior] 11 | enabled = yes 12 | 13 | [debug] 14 | enabled = yes 15 | 16 | [dropped] 17 | enabled = yes 18 | 19 | [memory] 20 | enabled = yes 21 | 22 | [memoryanalysis] 23 | enabled = yes 24 | 25 | [network] 26 | enabled = yes 27 | 28 | [static] 29 | enabled = yes 30 | 31 | [strings] 32 | enabled = yes 33 | 34 | [targetinfo] 35 | enabled = no 36 | 37 | [virustotal] 38 | enabled = yes 39 | # Add your VirusTotal API key here. The default API key, kindly provided 40 | # by the VirusTotal team, should enable you with a sufficient throughput 41 | # and while being shared with all our users, it shouldn't affect your use. 42 | key = a0283a2c3d55728300d064874239b5346fb991317e8449fe43c902879d758088 43 | -------------------------------------------------------------------------------- /conf/reporting.conf: -------------------------------------------------------------------------------- 1 | # Enable or disable the available reporting modules [on/off]. 2 | # If you add a custom reporting module to your Cuckoo setup, you have to add 3 | # a dedicated entry in this file, or it won't be executed. 4 | # You can also add additional options under the section of your module and 5 | # they will be available in your Python class. 6 | 7 | [jsondump] 8 | enabled = yes 9 | 10 | [reporthtml] 11 | enabled = yes 12 | 13 | [mmdef] 14 | enabled = no 15 | 16 | [maec40] 17 | enabled = no 18 | mode = overview 19 | processtree = true 20 | output_handles = false 21 | static = true 22 | strings = true 23 | virustotal = true 24 | 25 | [mongodb] 26 | enabled = no 27 | host = 127.0.0.1 28 | port = 27017 29 | 30 | [hpfclient] 31 | enabled = no 32 | host = 33 | port = 10000 34 | ident = 35 | secret = 36 | channel = 37 | -------------------------------------------------------------------------------- /conf/virtualbox.conf: -------------------------------------------------------------------------------- 1 | [virtualbox] 2 | # Specify which VirtualBox mode you want to run your machines on. 3 | # Can be "gui", "sdl" or "headless". Refer to VirtualBox's official 4 | # documentation to understand the differences. 5 | mode = gui 6 | 7 | # Path to the local installation of the VBoxManage utility. 8 | path = /usr/bin/VBoxManage 9 | 10 | # Specify a comma-separated list of available machines to be used. For each 11 | # specified ID you have to define a dedicated section containing the details 12 | # on the respective machine. (E.g. cuckoo1,cuckoo2,cuckoo3) 13 | machines = cuckoo1 14 | 15 | [cuckoo1] 16 | # Specify the label name of the current machine as specified in your 17 | # VirtualBox configuration. 18 | label = cuckoo1 19 | 20 | # Specify the operating system platform used by current machine 21 | # [windows/darwin/linux]. 22 | platform = windows 23 | 24 | # Specify the IP address of the current virtual machine. Make sure that the 25 | # IP address is valid and that the host machine is able to reach it. If not, 26 | # the analysis will fail. 27 | ip = 192.168.56.101 28 | 29 | # (Optional) Specify the snapshot name to use. If you do not specify a snapshot 30 | # name, the VirtualBox MachineManager will use the current snapshot. 31 | # Example (Snapshot1 is the snapshot name): 32 | # snapshot = Snapshot1 33 | 34 | # (Optional) Specify the name of the network interface that should be used 35 | # when dumping network traffic from this machine with tcpdump. If specified, 36 | # overrides the default interface specified in cuckoo.conf 37 | # Example (vboxnet0 is the interface name): 38 | # interface = vboxnet0 39 | 40 | # (Optional) Specify the IP of the Result Server, as your virtual machine sees it. 41 | # The Result Server will always bind to the address and port specified in cuckoo.conf, 42 | # however you could set up your virtual network to use NAT/PAT, so you can specify here 43 | # the IP address for the Result Server as your machine sees it. If you don't specify an 44 | # address here, the machine will use the default value from cuckoo.conf. 45 | # NOTE: if you set this option you have to set result server IP to 0.0.0.0 in cuckoo.conf. 46 | # Example: 47 | # resultserver_ip = 192.168.56.1 48 | 49 | # (Optional) Specify the port for the Result Server, as your virtual machine sees it. 50 | # The Result Server will always bind to the address and port specified in cuckoo.conf, 51 | # however you could set up your virtual network to use NAT/PAT, so you can specify here 52 | # the port for the Result Server as your machine sees it. If you don't specify a port 53 | # here, the machine will use the default value from cuckoo.conf. 54 | # Example: 55 | # resultserver_port = 2042 56 | 57 | # (Optional) Set your own tags. These are comma separated and help to identify 58 | # specific VMs. You can run samples on VMs with tag you require. 59 | # tags = windows_xp_sp3,32_bit,acrobat_reader_6 60 | -------------------------------------------------------------------------------- /conf/vmware.conf: -------------------------------------------------------------------------------- 1 | [vmware] 2 | # Specify which Vmware Workstation mode you want to run your machines on. 3 | # Can be "gui" or "nogui". Refer to VMware's official 4 | # documentation to understand the differences. 5 | mode = gui 6 | 7 | # Path to the local installation of the vmrun utility. 8 | path = /usr/bin/vmrun 9 | 10 | # Specify a comma-separated list of available machines to be used. For each 11 | # specified ID you have to define a dedicated section containing the details 12 | # on the respective machine. (E.g. cuckoo1,cuckoo2,cuckoo3) 13 | machines = cuckoo1 14 | 15 | [cuckoo1] 16 | # Specify the path to vmx file of the current machine 17 | label = ../vmware-xp3.vmx 18 | 19 | # Specify the snapshot name to use. 20 | snapshot = Snapshot1 21 | 22 | # Specify the operating system platform used by current machine 23 | # [windows/darwin/linux]. 24 | platform = windows 25 | 26 | # Specify the IP address of the current virtual machine. Make sure that the 27 | # IP address is valid and that the host machine is able to reach it. If not, 28 | # the analysis will fail. 29 | ip = 192.168.54.111 30 | 31 | # (Optional) Specify the name of the network interface that should be used 32 | # when dumping network traffic from this machine with tcpdump. If specified, 33 | # overrides the default interface specified in cuckoo.conf 34 | # Example (virbr0 is the interface name): 35 | # interface = virbr0 36 | 37 | # (Optional) Specify the IP of the Result Server, as your virtual machine sees it. 38 | # The Result Server will always bind to the address and port specified in cuckoo.conf, 39 | # however you could set up your virtual network to use NAT/PAT, so you can specify here 40 | # the IP address for the Result Server as your machine sees it. If you don't specify an 41 | # address here, the machine will use the default value from cuckoo.conf. 42 | # NOTE: if you set this option you have to set result server IP to 0.0.0.0 in cuckoo.conf. 43 | # Example: 44 | # resultserver_ip = 192.168.122.101 45 | 46 | # (Optional) Specify the port for the Result Server, as your virtual machine sees it. 47 | # The Result Server will always bind to the address and port specified in cuckoo.conf, 48 | # however you could set up your virtual network to use NAT/PAT, so you can specify here 49 | # the port for the Result Server as your machine sees it. If you don't specify a port 50 | # here, the machine will use the default value from cuckoo.conf. 51 | # Example: 52 | # resultserver_port = 2042 53 | 54 | # (Optional) Set your own tags. These are comma separated and help to identify 55 | # specific VMs. You can run samples on VMs with tag you require. 56 | # tags = windows_xp_sp3,32_bit,acrobat_reader_6 57 | -------------------------------------------------------------------------------- /cuckoo.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Copyright (C) 2010-2014 Cuckoo Sandbox Developers. 3 | # This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org 4 | # See the file 'docs/LICENSE' for copying permission. 5 | 6 | import sys 7 | import logging 8 | import argparse 9 | 10 | try: 11 | from lib.cuckoo.common.logo import logo 12 | from lib.cuckoo.common.constants import CUCKOO_VERSION 13 | from lib.cuckoo.common.exceptions import CuckooCriticalError 14 | from lib.cuckoo.common.exceptions import CuckooDependencyError 15 | from lib.cuckoo.core.startup import check_working_directory, check_configs 16 | from lib.cuckoo.core.startup import check_version, create_structure 17 | from lib.cuckoo.core.startup import init_logging, init_modules, init_tasks 18 | from lib.cuckoo.core.scheduler import Scheduler 19 | from lib.cuckoo.core.resultserver import Resultserver 20 | except (CuckooDependencyError, ImportError) as e: 21 | sys.exit("ERROR: Missing dependency: {0}".format(e)) 22 | 23 | log = logging.getLogger() 24 | 25 | def main(): 26 | logo() 27 | check_working_directory() 28 | check_configs() 29 | #check_version() 30 | create_structure() 31 | 32 | parser = argparse.ArgumentParser() 33 | parser.add_argument("-q", "--quiet", help="Display only error messages", action="store_true", required=False) 34 | parser.add_argument("-d", "--debug", help="Display debug messages", action="store_true", required=False) 35 | parser.add_argument("-v", "--version", action="version", version="You are running Cuckoo Sandbox {0}".format(CUCKOO_VERSION)) 36 | parser.add_argument("-a", "--artwork", help="Show artwork", action="store_true", required=False) 37 | args = parser.parse_args() 38 | 39 | if args.artwork: 40 | import time 41 | try: 42 | while True: 43 | time.sleep(1) 44 | logo() 45 | except KeyboardInterrupt: 46 | return 47 | 48 | init_logging() 49 | 50 | if args.quiet: 51 | log.setLevel(logging.WARN) 52 | elif args.debug: 53 | log.setLevel(logging.DEBUG) 54 | 55 | init_modules() 56 | init_tasks() 57 | 58 | Resultserver() 59 | 60 | try: 61 | sched = Scheduler() 62 | sched.start() 63 | except KeyboardInterrupt: 64 | sched.stop() 65 | 66 | if __name__ == "__main__": 67 | try: 68 | main() 69 | except CuckooCriticalError as e: 70 | message = "{0}: {1}".format(e.__class__.__name__, e) 71 | if len(log.handlers) > 0: 72 | log.critical(message) 73 | else: 74 | sys.stderr.write("{0}\n".format(message)) 75 | 76 | sys.exit(1) 77 | -------------------------------------------------------------------------------- /data/html/browse.html: -------------------------------------------------------------------------------- 1 | {% extends "base-web.html" %} 2 | {% block content %} 3 |
4 | 12 | {% if rows %} 13 | {% include "pagination-menu.html" %} 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | {% for row in rows %} 26 | 27 | 28 | 29 | 44 | 45 | 46 | 47 | {% endfor %} 48 | 49 |
IDCategoryTargetAddedStatus
{{row.id}}{{row.category|upper}} 30 | {% if row.processed %} 31 | 32 | {% endif %} 33 | 34 | {% if row.category == "file" %} 35 | {{row.md5}} 36 | {% elif row.category == "url" %} 37 | {{row.target}} 38 | {% endif %} 39 | 40 | {% if row.processed %} 41 | 42 | {% endif %} 43 | {{row.added_on}}{{row.status}}
50 | {% include "pagination-menu.html" %} 51 | {% else %} 52 |
53 | Analysis not found! Your database is empty. Run an analysis. 54 |
55 | {% endif %} 56 |
57 | {% endblock %} -------------------------------------------------------------------------------- /data/html/error.html: -------------------------------------------------------------------------------- 1 | {% extends "base-web.html" %} 2 | {% block content %} 3 | 6 |
7 |
8 | Error: {{error}} 9 |
10 |
11 | {% endblock %} -------------------------------------------------------------------------------- /data/html/img/glyphicons-halflings-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djteller/MemoryAnalysis/13554135ec4614e1fa2a051c1ba76525a92eac1a/data/html/img/glyphicons-halflings-white.png -------------------------------------------------------------------------------- /data/html/img/glyphicons-halflings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djteller/MemoryAnalysis/13554135ec4614e1fa2a051c1ba76525a92eac1a/data/html/img/glyphicons-halflings.png -------------------------------------------------------------------------------- /data/html/js/functions.js: -------------------------------------------------------------------------------- 1 | function showHide(id) { 2 | var e = document.getElementById(id); 3 | 4 | if(e.style.display == "none") 5 | e.style.display = "block"; 6 | else 7 | e.style.display = "none"; 8 | } 9 | -------------------------------------------------------------------------------- /data/html/pagination-rpp.html: -------------------------------------------------------------------------------- 1 | 4 |
5 | 16 |
17 | -------------------------------------------------------------------------------- /data/html/report.html: -------------------------------------------------------------------------------- 1 | {% extends "base-report.html" %} 2 | {% block content %} 3 | {% include "sections/info.html" %} 4 | {% include "sections/errors.html" %} 5 | {% if results.info.category == "file" %} 6 | {% include "sections/file.html" %} 7 | {% elif results.info.category == "url" %} 8 | {% include "sections/url.html" %} 9 | {% endif %} 10 | {% include "sections/signatures.html" %} 11 | {% include "sections/screenshots.html" %} 12 | {% if results.info.category == "file" %} 13 | {% include "sections/static.html" %} 14 | {% endif %} 15 | {% include "sections/dropped.html" %} 16 | {% include "sections/network.html" %} 17 | {% include "sections/behavior.html" %} 18 | {% include "sections/volatility.html" %} 19 | {% endblock %} -------------------------------------------------------------------------------- /data/html/sections/errors.html: -------------------------------------------------------------------------------- 1 | {% if results.debug.errors %} 2 |
3 |

Errors

4 |
5 |
6 |
    7 | {% for error in results.debug.errors %} 8 |
  • {{error}}
  • 9 | {% endfor %} 10 |
11 |
12 | {% endif %} -------------------------------------------------------------------------------- /data/html/sections/info.html: -------------------------------------------------------------------------------- 1 |
2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 |
CategoryStarted OnCompleted OnDurationCuckoo Version
{{results.info.category|upper}}{{results.info.started}}{{results.info.ended}}{{results.info.duration}} seconds{{results.info.version}}
22 |
-------------------------------------------------------------------------------- /data/html/sections/screenshots.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |

Screenshots

4 |
5 | {% if results.screenshots %} 6 | {% for shot in results.screenshots %} 7 | 8 | {% endfor %} 9 | {% else %} 10 | No screenshots available. 11 | {% endif %} 12 |
13 | -------------------------------------------------------------------------------- /data/html/sections/signatures.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |

Signatures

4 |
5 | {% if results.signatures %} 6 | {% for sign in results.signatures %} 7 | {% if sign.severity == 1 %} 8 |
9 | {% elif sign.severity == 2 %} 10 |
11 | {% elif sign.severity >= 3 %} 12 |
13 | {% else %} 14 |
15 | {% endif %} 16 | {{sign.description}} 17 |
18 | {% endfor %} 19 | {% else %} 20 | No signatures matched 21 | {% endif %} 22 |
23 | -------------------------------------------------------------------------------- /data/html/sections/url.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |

URL Details

4 |
5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 48 | 49 |
URL{{results.target.url}}
VirusTotal 17 | {% if results.virustotal %} 18 | {% if results.virustotal.response_code == 1 %} 19 | Permalink
20 | VirusTotal Scan Date: {{results.virustotal.scan_date}}
21 | Detection Rate: {{results.virustotal.positives}}/{{results.virustotal.total}} (collapse) 22 | 41 | {% else %} 42 | Domain not found on VirusTotal 43 | {% endif %} 44 | {% else %} 45 | VirusTotal lookup disabled, add your API key to the module 46 | {% endif %} 47 |
50 |
51 | -------------------------------------------------------------------------------- /data/html/success.html: -------------------------------------------------------------------------------- 1 | {% extends "base-web.html" %} 2 | {% block content %} 3 | 6 |
7 |
8 | GOOD! File {{submitfile}} was submitted for analysis with Task ID {{taskid}}. 9 |
10 |
11 | {% endblock %} -------------------------------------------------------------------------------- /data/patchers/patchpe.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 000000000300000004000000ffff0000b8 5 | 6 | 7 | 4d5a90 8 | 5045 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /data/peutils/UserDB.TXT: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djteller/MemoryAnalysis/13554135ec4614e1fa2a051c1ba76525a92eac1a/data/peutils/UserDB.TXT -------------------------------------------------------------------------------- /data/src/binpackage/Makefile: -------------------------------------------------------------------------------- 1 | execsc.exe: execsc.c 2 | i586-mingw32msvc-cc -Wall -o $@ $< 3 | 4 | -------------------------------------------------------------------------------- /data/src/binpackage/execsc.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main (int argc, char ** argv) { 6 | int fd; 7 | char buf[2048] = {0}; 8 | 9 | if (argc < 2) return 1; 10 | 11 | // read in shellcode from analysis target file 12 | fd = open(argv[1], 0); 13 | read(fd, buf, 2048); 14 | close(fd); 15 | 16 | // jump into shellcode 17 | int (*func)(); 18 | func = (int (*)()) buf; 19 | (int)(*func)(); 20 | 21 | return 0; 22 | } 23 | 24 | -------------------------------------------------------------------------------- /data/yara/index_binary.yar: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2010-2014 Cuckoo Sandbox Developers. 2 | // This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org 3 | // See the file 'docs/LICENSE' for copying permission. 4 | 5 | include "signatures/embedded.yar" 6 | include "signatures/shellcodes.yar" 7 | include "signatures/vmdetect.yar" 8 | -------------------------------------------------------------------------------- /data/yara/signatures/embedded.yar: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2010-2014 Cuckoo Sandbox Developers. 2 | // This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org 3 | // See the file 'docs/LICENSE' for copying permission. 4 | 5 | rule embedded_macho 6 | { 7 | meta: 8 | author = "nex" 9 | description = "Contains an embedded Mach-O file" 10 | 11 | strings: 12 | $magic1 = { ca fe ba be } 13 | $magic2 = { ce fa ed fe } 14 | $magic3 = { fe ed fa ce } 15 | condition: 16 | any of ($magic*) and not ($magic1 at 0) and not ($magic2 at 0) and not ($magic3 at 0) 17 | } 18 | 19 | rule embedded_pe 20 | { 21 | meta: 22 | author = "nex" 23 | description = "Contains an embedded PE32 file" 24 | 25 | strings: 26 | $a = "PE32" 27 | $b = "This program" 28 | $mz = { 4d 5a } 29 | condition: 30 | ($a or $b) and not ($mz at 0) 31 | } 32 | 33 | rule embedded_win_api 34 | { 35 | meta: 36 | author = "nex" 37 | description = "A non-Windows executable contains win32 API functions names" 38 | 39 | strings: 40 | $mz = { 4d 5a } 41 | $api1 = "CreateFileA" 42 | $api2 = "GetProcAddress" 43 | $api3 = "LoadLibraryA" 44 | $api4 = "WinExec" 45 | $api5 = "GetSystemDirectoryA" 46 | $api6 = "WriteFile" 47 | $api7 = "ShellExecute" 48 | $api8 = "GetWindowsDirectory" 49 | $api9 = "URLDownloadToFile" 50 | $api10 = "IsBadReadPtr" 51 | $api11 = "IsBadWritePtr" 52 | $api12 = "SetFilePointer" 53 | $api13 = "GetTempPath" 54 | $api14 = "GetWindowsDirectory" 55 | condition: 56 | not ($mz at 0) and any of ($api*) 57 | } 58 | -------------------------------------------------------------------------------- /data/yara/signatures/shellcodes.yar: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2010-2014 Cuckoo Sandbox Developers. 2 | // This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org 3 | // See the file 'docs/LICENSE' for copying permission. 4 | 5 | rule shellcode 6 | { 7 | meta: 8 | author = "nex" 9 | description = "Matched shellcode byte patterns" 10 | 11 | strings: 12 | $a = { 64 8b 64 } 13 | $b = { 64 a1 30 } 14 | $c = { 64 8b 15 30 } 15 | $d = { 64 8b 35 30 } 16 | $e = { 55 8b ec 83 c4 } 17 | $f = { 55 8b ec 81 ec } 18 | $g = { 55 8b ec e8 } 19 | $h = { 55 8b ec e9 } 20 | condition: 21 | any of them 22 | } 23 | -------------------------------------------------------------------------------- /data/yara/signatures/vmdetect.yar: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2010-2014 Cuckoo Sandbox Developers. 2 | // This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org 3 | // See the file 'docs/LICENSE' for copying permission. 4 | 5 | rule vmdetect 6 | { 7 | meta: 8 | author = "nex" 9 | description = "Possibly employs anti-virtualization techniques" 10 | 11 | strings: 12 | // Binary tricks 13 | $vmware = {56 4D 58 68} 14 | $virtualpc = {0F 3F 07 0B} 15 | $ssexy = {66 0F 70 ?? ?? 66 0F DB ?? ?? ?? ?? ?? 66 0F DB ?? ?? ?? ?? ?? 66 0F EF} 16 | $vmcheckdll = {45 C7 00 01} 17 | $redpill = {0F 01 0D 00 00 00 00 C3} 18 | 19 | // Random strings 20 | $vmware1 = "VMXh" 21 | $vmware2 = "Ven_VMware_" nocase 22 | $vmware3 = "Prod_VMware_Virtual_" nocase 23 | $vmware4 = "hgfs.sys" nocase 24 | $vmware5 = "mhgfs.sys" nocase 25 | $vmware6 = "prleth.sys" nocase 26 | $vmware7 = "prlfs.sys" nocase 27 | $vmware8 = "prlmouse.sys" nocase 28 | $vmware9 = "prlvideo.sys" nocase 29 | $vmware10 = "prl_pv32.sys" nocase 30 | $vmware11 = "vpc-s3.sys" nocase 31 | $vmware12 = "vmsrvc.sys" nocase 32 | $vmware13 = "vmx86.sys" nocase 33 | $vmware14 = "vmnet.sys" nocase 34 | $vmware15 = "vmicheartbeat" nocase 35 | $vmware16 = "vmicvss" nocase 36 | $vmware17 = "vmicshutdown" nocase 37 | $vmware18 = "vmicexchange" nocase 38 | $vmware19 = "vmdebug" nocase 39 | $vmware20 = "vmmouse" nocase 40 | $vmware21 = "vmtools" nocase 41 | $vmware22 = "VMMEMCTL" nocase 42 | $vmware23 = "vmx86" nocase 43 | $vmware24 = "vmware" nocase 44 | $virtualpc1 = "vpcbus" nocase 45 | $virtualpc2 = "vpc-s3" nocase 46 | $virtualpc3 = "vpcuhub" nocase 47 | $virtualpc4 = "msvmmouf" nocase 48 | $xen1 = "xenevtchn" nocase 49 | $xen2 = "xennet" nocase 50 | $xen3 = "xennet6" nocase 51 | $xen4 = "xensvc" nocase 52 | $xen5 = "xenvdb" nocase 53 | $xen6 = "XenVMM" nocase 54 | $virtualbox1 = "VBoxHook.dll" nocase 55 | $virtualbox2 = "VBoxService" nocase 56 | $virtualbox3 = "VBoxTray" nocase 57 | $virtualbox4 = "VBoxMouse" nocase 58 | $virtualbox5 = "VBoxGuest" nocase 59 | $virtualbox6 = "VBoxSF" nocase 60 | $virtualbox7 = "VBoxGuestAdditions" nocase 61 | $virtualbox8 = "VBOX HARDDISK" nocase 62 | 63 | // MAC addresses 64 | $vmware_mac_1a = "00-05-69" 65 | $vmware_mac_1b = "00:05:69" 66 | $vmware_mac_1c = "000569" 67 | $vmware_mac_2a = "00-50-56" 68 | $vmware_mac_2b = "00:50:56" 69 | $vmware_mac_2c = "005056" 70 | $vmware_mac_3a = "00-0C-29" nocase 71 | $vmware_mac_3b = "00:0C:29" nocase 72 | $vmware_mac_3c = "000C29" nocase 73 | $vmware_mac_4a = "00-1C-14" nocase 74 | $vmware_mac_4b = "00:1C:14" nocase 75 | $vmware_mac_4c = "001C14" nocase 76 | $virtualbox_mac_1a = "08-00-27" 77 | $virtualbox_mac_1b = "08:00:27" 78 | $virtualbox_mac_1c = "080027" 79 | 80 | condition: 81 | any of them 82 | } 83 | -------------------------------------------------------------------------------- /docs/AUTHORS: -------------------------------------------------------------------------------- 1 | AUTHORS 2 | 3 | Cuckoo is the result of the work and efforts of many people. Some main developers 4 | and some friends and users who kindly provided us with feedback and new features. 5 | You'll find contributions to the code mentioned in the specific source files. 6 | 7 | DEVELOPERS: 8 | Claudio "nex" Guarnieri Lead Developer @botherder 9 | Alessandro "jekil" Tanasi Developer @jekil 10 | Jurriaan "skier" Bremer Developer @skier_t 11 | Mark "rep" Schloesser Developer @repmovsb 12 | 13 | CONTRIBUTORS: 14 | $ git shortlog -s -n 15 | 814 Nex 16 | 611 jekil 17 | 187 rep 18 | 184 nex 19 | 125 Jurriaan Bremer 20 | 70 Ivan Kirillov 21 | 65 Thorsten Sick 22 | 24 Pietro Delsante 23 | 21 Alessandro Tanasi 24 | 19 Mark Schloesser 25 | 15 David Maciejak 26 | 12 Greg Back 27 | 9 Christopher Schmitt 28 | 9 Script Kiddie 29 | 7 Hugh Pearse 30 | 6 init99 31 | 4 Adam Pridgen 32 | 4 Ben Small 33 | 3 jamu 34 | 3 z0mbiehunt3r 35 | 2 Claudio Guarnieri 36 | 2 Richard Harman 37 | 2 Thomas Penteker 38 | 2 bcyrill 39 | 2 mak 40 | 2 mt00at 41 | 1 = 42 | 1 Allen Swackhamer 43 | 1 Ben Lyon 44 | 1 Stephen DiCato 45 | 1 bladeswords 46 | 1 chort 47 | 1 jvoisin 48 | 1 vacmf 49 | 50 | Thanks to the whole community and mailing list members who submitted bug 51 | reports and suggested new features. 52 | -------------------------------------------------------------------------------- /docs/README: -------------------------------------------------------------------------------- 1 | README 2 | 3 | The documentation for installing, using and customizing Cuckoo Sandbox is 4 | available under different forms and formats. 5 | 6 | Under "docs/book/" you can find the complete Cuckoo Sandbox Book in three 7 | different formats: 8 | * HTML 9 | * PDF 10 | * Text 11 | 12 | Under "docs/books/src" you'll find the Sphinx sources used to build the book. 13 | 14 | Under "epydoc/" you'll find the Python documentation of Cuckoo's libs and apis 15 | generated by Epydoc. This directory contains two sub-directories: "host" and 16 | "guest", containing references for Cuckoo's Host and Guest components 17 | respectively. 18 | -------------------------------------------------------------------------------- /docs/book/src/_images/logo/cuckoo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djteller/MemoryAnalysis/13554135ec4614e1fa2a051c1ba76525a92eac1a/docs/book/src/_images/logo/cuckoo.png -------------------------------------------------------------------------------- /docs/book/src/_images/schemas/architecture-main.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djteller/MemoryAnalysis/13554135ec4614e1fa2a051c1ba76525a92eac1a/docs/book/src/_images/schemas/architecture-main.png -------------------------------------------------------------------------------- /docs/book/src/_images/screenshots/shared_folders.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djteller/MemoryAnalysis/13554135ec4614e1fa2a051c1ba76525a92eac1a/docs/book/src/_images/screenshots/shared_folders.png -------------------------------------------------------------------------------- /docs/book/src/_images/screenshots/windows_security.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djteller/MemoryAnalysis/13554135ec4614e1fa2a051c1ba76525a92eac1a/docs/book/src/_images/screenshots/windows_security.png -------------------------------------------------------------------------------- /docs/book/src/customization/auxiliary.rst: -------------------------------------------------------------------------------- 1 | ================= 2 | Auxiliary Modules 3 | ================= 4 | 5 | **Auxiliary** modules define some procedures that need to be executed in parallel 6 | to every single analysis process. 7 | All auxiliary modules should be placed under the *modules/auxiliary/* directory. 8 | 9 | The skeleton of a module would look something like this: 10 | 11 | .. code-block:: python 12 | :linenos: 13 | 14 | from lib.cuckoo.common.abstracts import Auxiliary 15 | 16 | class MyAuxiliary(Auxiliary): 17 | 18 | def start(self): 19 | # Do something. 20 | 21 | def stop(self): 22 | # Stop the execution. 23 | 24 | The function ``start()`` will be executed before starting the analysis machine and effectively 25 | executing the submitted malicious file, while the ``stop()`` function will be launched at the 26 | very end of the analysis process, before launching the processing and reporting procedures. 27 | 28 | For example, an auxiliary module provided by default in Cuckoo is called *sniffer.py* and 29 | takes care of executing **tcpdump** in order to dump the generated network traffic. 30 | -------------------------------------------------------------------------------- /docs/book/src/customization/index.rst: -------------------------------------------------------------------------------- 1 | .. Customization chapter frontpage 2 | 3 | Customization 4 | ============= 5 | 6 | This chapter explains how to customize Cuckoo. 7 | Cuckoo is written in a modular architecture built to be as much customizable it can, 8 | to fit all user's needs. 9 | 10 | .. toctree:: 11 | 12 | auxiliary 13 | machinery 14 | packages 15 | processing 16 | signatures 17 | reporting 18 | -------------------------------------------------------------------------------- /docs/book/src/customization/reporting.rst: -------------------------------------------------------------------------------- 1 | ================= 2 | Reporting Modules 3 | ================= 4 | 5 | After the analysis raw results have been processed and abstracted by the 6 | processing modules and the global container is generated (ref. :doc:`processing`), 7 | it is passed over by Cuckoo to all the reporting modules available, which will 8 | make some use of it and will make it accessible and consumable in different 9 | formats. 10 | 11 | Getting Started 12 | =============== 13 | 14 | All reporting modules are and should be placed inside the directory *modules/reporting/*. 15 | 16 | Every module should also have a dedicated section in the file *conf/reporting.conf*: for 17 | example if you create a module *module/reporting/foobar.py* you will have to append 18 | the following section to *conf/reporting.conf*:: 19 | 20 | [foobar] 21 | enabled = on 22 | 23 | Every additional option you add to your section will be available to your reporting module 24 | in the ``self.options`` dictionary. 25 | 26 | Following is an example of a working JSON reporting module: 27 | 28 | .. code-block:: python 29 | :linenos: 30 | 31 | import os 32 | import json 33 | import codecs 34 | 35 | from lib.cuckoo.common.abstracts import Report 36 | from lib.cuckoo.common.exceptions import CuckooReportError 37 | 38 | class JsonDump(Report): 39 | """Saves analysis results in JSON format.""" 40 | 41 | def run(self, results): 42 | """Writes report. 43 | @param results: Cuckoo results dict. 44 | @raise CuckooReportError: if fails to write report. 45 | """ 46 | try: 47 | report = codecs.open(os.path.join(self.reports_path, "report.json"), "w", "utf-8") 48 | json.dump(results, report, sort_keys=False, indent=4) 49 | report.close() 50 | except (UnicodeError, TypeError, IOError) as e: 51 | raise CuckooReportError("Failed to generate JSON report: %s" % e) 52 | 53 | This code is very simple, it basically just receives the global container produced by the 54 | processing modules, converts it into JSON and writes it to a file. 55 | 56 | There are few requirements for writing a valid reporting module: 57 | 58 | * Declare your class inheriting ``Report``. 59 | * Have a ``run()`` function performing the main operations. 60 | * Try to catch most exceptions and raise ``CuckooReportError`` to notify the issue. 61 | 62 | All reporting modules have access to some attributes: 63 | 64 | * ``self.analysis_path``: path to the folder containing the raw analysis results (e.g. *storage/analyses/1/*) 65 | * ``self.reports_path``: path to the folder where the reports should be written (e.g. *storage/analyses/1/reports/*) 66 | * ``self.conf_path``: path to the *analysis.conf* file of the current analysis (e.g. *storage/analyses/1/analysis.conf*) 67 | * ``self.options``: a dictionary containing all the options specified in the report's configuration section in *conf/reporting.conf*. -------------------------------------------------------------------------------- /docs/book/src/development/development_notes.rst: -------------------------------------------------------------------------------- 1 | ================= 2 | Development Notes 3 | ================= 4 | 5 | Git branches 6 | ============ 7 | 8 | Cuckoo Sandbox source code is available in our `official git repository`_. 9 | You'll find multiple branches which are used for different stages of our 10 | development lifecycle. 11 | 12 | * **Development**: This is where our developers commit their ongoing work for the upcoming releases. As a development branch, this can be really unstable and sometimes even broken and not usable. Users are discouraged to adopt this branch, this is aimed only to developers or guys with a deep knowledge into our technologies. 13 | * **Testing**: When work on development branch is in a usable state and some new features or fixes are completed, the development branch in merged into testing. This is the branch where users can get a taste of the next release. If you want to be always up-to-date this branch is for you. 14 | * **Stable**: When unstable branch is widely tested and bugs free and if all planned features has been completed, a new stable version will be released and available here. 15 | 16 | .. _`official git repository`: http://github.com/cuckoobox/cuckoo 17 | .. _`Development`: http://github.com/cuckoobox/cuckoo/tree/development 18 | .. _`Testing`: http://github.com/cuckoobox/cuckoo/tree/testing 19 | .. _`Stable`: http://github.com/cuckoobox/cuckoo 20 | 21 | Release Versioning 22 | ================== 23 | 24 | Cuckoo releases are named using three numbers separated by dots, such as 1.2.3, where the first number is the release, the second number is the major version, the third number is the bugfix version. 25 | The testing stage from git ends with "-beta" and development stage with "-dev". 26 | 27 | .. warning:: 28 | 29 | If you are using a "beta" or "dev" stage, please consider that it's not 30 | meant to be an official release, therefore we don't guarantee its functioning 31 | and we don't generally provide support. 32 | If you think you encountered a bug there, make sure that the nature of the 33 | problem is not related to your own misconfiguration and collect all the details 34 | to be notified to our developers. Make sure to specify which exact version you 35 | are using, eventually with your current git commit id. 36 | 37 | Ticketing system 38 | ================ 39 | 40 | To submit bug reports or feature requests, please use GitHub's `Issue`_ tracking system. 41 | 42 | .. _`Issue`: https://github.com/cuckoobox/cuckoo/issues 43 | 44 | Contribute 45 | ========== 46 | 47 | To submit your patch just create a Pull Request from yuor GitHub fork. 48 | If you don't now how to create a Pull Request take a look to `GitHub help`_. 49 | 50 | .. _`GitHub help`: https://help.github.com/articles/using-pull-requests/ -------------------------------------------------------------------------------- /docs/book/src/development/index.rst: -------------------------------------------------------------------------------- 1 | .. Development chapter frontpage 2 | 3 | Development 4 | =========== 5 | 6 | This chapter explains how to write Cuckoo's code and how to contribute. 7 | 8 | .. toctree:: 9 | 10 | development_notes 11 | code_style 12 | -------------------------------------------------------------------------------- /docs/book/src/index.rst: -------------------------------------------------------------------------------- 1 | 2 | .. _index: 3 | 4 | =================== 5 | Cuckoo Sandbox Book 6 | =================== 7 | 8 | Cuckoo Sandbox is an *Open Source* software for automating analysis of suspicious files. 9 | To do so it makes use of custom components that monitor the behavior of the malicious 10 | processes while running in an isolated environment. 11 | 12 | This guide will explain how to set up Cuckoo, use it and customize it. 13 | 14 | Having troubles? 15 | ================ 16 | 17 | If you're having troubles you might want to check out the :doc:`FAQ ` 18 | it might already have the answers to your questions. 19 | 20 | .. toctree:: 21 | 22 | faq/index 23 | 24 | Otherwise you can ask the developers and/or other Cuckoo users, see 25 | :doc:`Join the discussion `. 26 | 27 | Contents 28 | ======== 29 | 30 | .. toctree:: 31 | 32 | introduction/index 33 | installation/index 34 | usage/index 35 | customization/index 36 | development/index 37 | finalremarks/index 38 | -------------------------------------------------------------------------------- /docs/book/src/installation/guest/agent.rst: -------------------------------------------------------------------------------- 1 | ================= 2 | Install the Agent 3 | ================= 4 | 5 | From release 0.4 Cuckoo adopts a custom agent that runs inside the Guest and 6 | that handles the communication and the exchange of data with the Host. 7 | This agent is designed to be cross-platform, therefore you should be able 8 | to use it on Windows as well as on Linux and OS X. 9 | In order to make Cuckoo work properly, you'll have to install and start this 10 | agent. 11 | 12 | It's very simple. 13 | 14 | In the *agent/* directory you will find and *agent.py* file, just copy it 15 | to the Guest operating system (in whatever way you want, perhaps a temporary 16 | shared folder or by downloading it from a Host webserver) and run it. 17 | This will launch the XMLRPC server which will be listening for connections. 18 | 19 | On Windows simply launching the script will also spawn a Python window, if 20 | you want to hide it you can rename the file from *agent.py* to **agent.pyw** 21 | which will prevent the window from spawning. 22 | 23 | If you want the script to be launched at Windows' boot, placing the file in 24 | the `Startup` folder will make it. 25 | -------------------------------------------------------------------------------- /docs/book/src/installation/guest/cloning.rst: -------------------------------------------------------------------------------- 1 | =========================== 2 | Cloning the Virtual Machine 3 | =========================== 4 | 5 | In case you planned to use more than one virtual machine, there's no need to 6 | repeat all the steps done so far: you can clone it. In this way you'll have 7 | a copy of the original virtualized Windows with all requirements already 8 | installed. 9 | 10 | The new virtual machine will eventually bring along also the settings of the 11 | original one, which is not good. Now you need to proceed repeating the steps 12 | explained in :doc:`network`, :doc:`agent` and :doc:`saving` for this new machine. 13 | -------------------------------------------------------------------------------- /docs/book/src/installation/guest/creation.rst: -------------------------------------------------------------------------------- 1 | =============================== 2 | Creation of the Virtual Machine 3 | =============================== 4 | 5 | Once you have :doc:`properly installed <../host/requirements>` your virtualization 6 | software, you can proceed on creating all the virtual machines you need. 7 | 8 | Using and configuring your virtualization software is out of the scope of this 9 | guide, so please refer to the official documentation. 10 | 11 | .. note:: 12 | 13 | You can find some hints and considerations on how to design and create 14 | your virtualized environment in the :doc:`../../introduction/sandboxing` 15 | chapter. 16 | 17 | .. note:: 18 | 19 | For analysis purposes you are recommended to use Windows XP Service Pack 20 | 3, but Cuckoo Sandbox also proved to work with Windows 7 with User 21 | Access Control disabled. 22 | 23 | .. note:: 24 | 25 | KVM Users - Be sure to choose a hard drive image format that supports snapshots. 26 | See :doc:`../../Installation/Preparing the Guest/Saving the Virtual Machine/KVM` 27 | for more information. 28 | 29 | When creating the virtual machine, Cuckoo doesn't require any specific 30 | configuration. You can choose the options that best fit your needs. 31 | -------------------------------------------------------------------------------- /docs/book/src/installation/guest/index.rst: -------------------------------------------------------------------------------- 1 | =================== 2 | Preparing the Guest 3 | =================== 4 | 5 | At this point you should have configured Cuckoo host component and you 6 | should have designed and defined the number and the names of the virtual 7 | machines you are going to use for malware execution. 8 | 9 | Now it's time to create such machines and to configure them properly. 10 | 11 | .. toctree:: 12 | 13 | creation 14 | requirements 15 | network 16 | agent 17 | saving 18 | cloning 19 | 20 | -------------------------------------------------------------------------------- /docs/book/src/installation/guest/network.rst: -------------------------------------------------------------------------------- 1 | ===================== 2 | Network Configuration 3 | ===================== 4 | 5 | Now it's the time to setup the network configuration for your virtual machine. 6 | 7 | Windows Settings 8 | ================ 9 | 10 | Before configuring the underlying networking of the virtual machine, you might 11 | want to trick some settings inside Windows itself. 12 | 13 | One of the most important things to do is **disabling** *Windows Firewall* and the 14 | *Automatic Updates*. The reason behind this is that they can affect the behavior 15 | of the malware under normal circumstances and that they can pollute the network 16 | analysis performed by Cuckoo, by dropping connections or including unrelevant 17 | requests. 18 | 19 | You can do so from Windows' Control Panel as shown in the picture: 20 | 21 | .. image:: ../../_images/screenshots/windows_security.png 22 | :align: center 23 | 24 | Virtual Networking 25 | ================== 26 | 27 | Now you need to decide how to make your virtual machine able to access Internet 28 | or your local network. 29 | 30 | While in previous releases Cuckoo used shared folders to exchange data between 31 | the Host and Guests, from release 0.4 it adopts a custom agent that works 32 | over the network using a simple XMLRPC protocol. 33 | 34 | In order to make it work properly you'll have to configure your machine's 35 | network so that the Host and the Guest can communicate. 36 | Test network trying to ping a guest is a good practice, to be sure about 37 | virtual network setup. 38 | Use only static address for your guest, as today Cuckoo doesn't support DHCP and 39 | using it will break your setup. 40 | 41 | This stage is very much up to your own requirements and to the 42 | characteristics of your virtualization software. 43 | 44 | .. warning:: Virtual networking errors! 45 | Virtual networking is a vital component for Cuckoo, you must be really 46 | sure to get connectivity between host and guest. 47 | Most of the issues reported by users are related to a wrong setup of 48 | their networking. 49 | You you aren't sure about that check your virtualization software 50 | documentation and test connectivity with ping and telnet. 51 | 52 | The recommended setup is using a Host-Only networking layout with proper 53 | forwarding and filtering configuration done with ``iptables`` on the Host. 54 | 55 | For example, using VirtualBox, you can enable Internet access to the virtual 56 | machines using the following ``iptables`` rules (assuming that eth0 is your 57 | outgoing interface, vboxnet0 is your virtual interface and 192.168.56.0/24 is 58 | your subnet address):: 59 | 60 | iptables -A FORWARD -o eth0 -i vboxnet0 -s 192.168.56.0/24 -m conntrack --ctstate NEW -j ACCEPT 61 | iptables -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT 62 | iptables -A POSTROUTING -t nat -j MASQUERADE 63 | 64 | And adding IP forward:: 65 | 66 | sysctl -w net.ipv4.ip_forward=1 67 | -------------------------------------------------------------------------------- /docs/book/src/installation/guest/requirements.rst: -------------------------------------------------------------------------------- 1 | ============ 2 | Requirements 3 | ============ 4 | 5 | In order to make Cuckoo run properly in your virtualized Windows system, you 6 | will have to install some required softwares and libraries. 7 | 8 | Install Python 9 | ============== 10 | 11 | Python is a strict requirement for the Cuckoo guest component (*analyzer*) in 12 | order to run properly. 13 | 14 | You can download the proper Windows installer from the `official website`_. 15 | Also in this case Python 2.7 is preferred. 16 | 17 | Some Python libraries are optional and provide some additional features to 18 | Cuckoo guest component. They include: 19 | 20 | * `Python Image Library`_: it's used for taking screenshots of Windows desktop during the analysis. 21 | 22 | They are not strictly required by Cuckoo to work properly, but you are encouraged 23 | to install them if you want to have access to all features available. Make sure 24 | to download and install the proper packages according to your Python version. 25 | 26 | .. _`official website`: http://www.python.org/getit/ 27 | .. _`Python Image Library`: http://www.pythonware.com/products/pil/ 28 | 29 | Additional Software 30 | =================== 31 | 32 | At this point you should have installed everything needed by Cuckoo to run 33 | properly. 34 | 35 | Depending on what kind of files you want to analyze and what kind of sandboxed 36 | Windows environment you want to run the malwares in, you might want to install 37 | additional software such as browsers, PDF readers, office suites etc. 38 | Remeber to disable the "auto update" or "check for updates" feature of 39 | any additional software. 40 | 41 | This is completely up to you and to how you, you might get some hints by reading 42 | the :doc:`../../introduction/sandboxing` chapter. 43 | -------------------------------------------------------------------------------- /docs/book/src/installation/host/index.rst: -------------------------------------------------------------------------------- 1 | ================== 2 | Preparing the Host 3 | ================== 4 | 5 | Even though it's reported to run on other operating systems too, Cuckoo is 6 | originally supposed to run on a *GNU/Linux* native system. 7 | For the purpose of this documentation, we chose **latest Ubuntu LTS** as 8 | reference system for the commands examples. 9 | 10 | .. toctree:: 11 | 12 | requirements 13 | installation 14 | configuration 15 | -------------------------------------------------------------------------------- /docs/book/src/installation/host/installation.rst: -------------------------------------------------------------------------------- 1 | ================= 2 | Installing Cuckoo 3 | ================= 4 | 5 | Proceed with download and installation. Read :doc:`../../introduction/what` to 6 | learn where you can obtain a copy of the sandbox. 7 | 8 | Create a user 9 | ============= 10 | 11 | You either can run Cuckoo from your own user or create a new one dedicated just 12 | to your sandbox setup. 13 | Make sure that the user that runs Cuckoo is the same user that you will 14 | use to create and run the virtual machines, otherwise Cuckoo won't be able to 15 | identify and launch them. 16 | 17 | Create a new user:: 18 | 19 | $ sudo adduser cuckoo 20 | 21 | If you're using VirtualBox, make sure the new user belongs to the "vboxusers" 22 | group (or the group you used to run VirtualBox):: 23 | 24 | $ sudo usermod -G vboxusers cuckoo 25 | 26 | If you're using KVM or any other libvirt based module, make sure the new user 27 | belongs to the "libvirtd" group (or the group your Linux distribution uses to 28 | run libvirt):: 29 | 30 | $ sudo usermod -G libvirtd cuckoo 31 | 32 | Install Cuckoo 33 | ============== 34 | 35 | Extract or checkout your copy of Cuckoo to a path of your choice and you're 36 | ready to go ;-). 37 | 38 | -------------------------------------------------------------------------------- /docs/book/src/installation/index.rst: -------------------------------------------------------------------------------- 1 | .. Installation chapter frontpage 2 | 3 | Installation 4 | ============ 5 | 6 | This chapter explains how to install Cuckoo. 7 | 8 | .. note:: 9 | 10 | This documentation refers to *Host* as the underlying operating systems on 11 | which you are running Cuckoo (generally being a GNU/Linux distribution) and 12 | to *Guest* as the Windows virtual machine used to run the isolated analysis. 13 | 14 | .. toctree:: 15 | 16 | host/index 17 | guest/index 18 | upgrade 19 | 20 | -------------------------------------------------------------------------------- /docs/book/src/installation/upgrade.rst: -------------------------------------------------------------------------------- 1 | =============================== 2 | Upgrade from a previous release 3 | =============================== 4 | 5 | Cuckoo Sandbox grows really fast and in every release new features are added and 6 | some others are fixed or removed. 7 | If not otherwise specified in the release documentation, the suggested way to 8 | upgrade your Cuckoo instance is to perform a fresh setup as described in 9 | :doc:`index`. 10 | 11 | The following steps are suggested: 12 | 13 | 1. Backup your installation. 14 | 2. Read the documentation shipped with the new release. 15 | 3. Make sure to have installed all required dependencies, otherwise install them. 16 | 4. Do a Cuckoo fresh installation of the Host components. 17 | 5. Reconfigure Cuckoo as explained in this book (copying old configuration files 18 | is not safe because options can change between releases). 19 | 6. If you are using an external database instead of default or you are using 20 | MongoDb reporting module is suggested to start all databases from scratch, due 21 | to possible schema changes between Cuckoo's releases. 22 | 7. Test it! 23 | 24 | If something goes wrong you probably failed some steps during the fresh 25 | installation or reconfiguration. Check again the procedure explained in this 26 | book. 27 | 28 | It's not recommended to rewrite an old Cuckoo installation with the latest 29 | release files, as it might raise some problems because: 30 | 31 | * You are overwriting Python source files (.py) but Python bytecode files (.pyc) 32 | are still in place. 33 | * There are configuration files changes across the two versions, check our 34 | CHANGELOG file for added or removed configuration options. 35 | * The part of Cuckoo which runs inside guests (agent.py) may change. 36 | * If you are using an external database like the reporting module for MongoDb a 37 | change in the data schema may screw your database. 38 | -------------------------------------------------------------------------------- /docs/book/src/introduction/index.rst: -------------------------------------------------------------------------------- 1 | .. Introduction chapter frontpage 2 | 3 | Introduction 4 | ============ 5 | 6 | This is an introductory chapter to Cuckoo Sandbox. 7 | It explains some basic malware analysis concepts, what's Cuckoo and how it can fit 8 | in malware analysis. 9 | 10 | .. toctree:: 11 | 12 | sandboxing 13 | what 14 | license 15 | 16 | -------------------------------------------------------------------------------- /docs/book/src/introduction/license.rst: -------------------------------------------------------------------------------- 1 | ======= 2 | License 3 | ======= 4 | 5 | Cuckoo Sandbox license is shipped with Cuckoo and contained in "LICENSE" file 6 | inside "docs" folder. 7 | 8 | ========== 9 | Disclaimer 10 | ========== 11 | 12 | Cuckoo is distributed as it is, in the hope that it will be useful, but without 13 | any warranty neither the implied merchantability or fitness for a particular 14 | purpose. 15 | 16 | Whatever you do with this tool is uniquely your own responsibility. 17 | 18 | -------------------------------------------------------------------------------- /docs/book/src/usage/index.rst: -------------------------------------------------------------------------------- 1 | .. Usage chapter frontpage 2 | 3 | Usage 4 | ===== 5 | 6 | This chapter explains how to use Cuckoo. 7 | 8 | .. toctree:: 9 | 10 | start 11 | submit 12 | web 13 | api 14 | packages 15 | results 16 | utilities 17 | -------------------------------------------------------------------------------- /docs/book/src/usage/results.rst: -------------------------------------------------------------------------------- 1 | ================ 2 | Analysis Results 3 | ================ 4 | 5 | Once an analysis is completed, several files are stored in a dedicated directory. 6 | All the analysis are stored under the directory *storage/analyses/* inside a 7 | subdirectory named with the incremental numerical ID which represents the analysis 8 | task inside the database. 9 | 10 | Following is an example of an analysis directory structure:: 11 | 12 | . 13 | |-- analysis.conf 14 | |-- analysis.log 15 | |-- binary 16 | |-- dump.pcap 17 | |-- memory.dmp 18 | |-- files 19 | | |-- 1234567890 20 | | `-- dropped.exe 21 | |-- logs 22 | | |-- 1232.raw 23 | | |-- 1540.raw 24 | | `-- 1118.raw 25 | |-- reports 26 | | |-- report.html 27 | | |-- report.json 28 | | |-- report.maec-40.xml 29 | | `-- report.metadata.xml 30 | `-- shots 31 | |-- 0001.jpg 32 | |-- 0002.jpg 33 | |-- 0003.jpg 34 | `-- 0004.jpg 35 | 36 | analysis.conf 37 | ============= 38 | 39 | This is a configuration file automatically generated by Cuckoo to instruct 40 | its analyzer some details about the current analysis. It's generally of no 41 | interest for the end-user, as it's exclusively used internally by the 42 | sandbox. 43 | 44 | analysis.log 45 | ============ 46 | 47 | This is a log file generated by the analyzer and that contains a trace of 48 | the analysis execution inside the guest environment. It will report the 49 | creation of processes, files and eventual error occurred during the 50 | execution. 51 | 52 | dump.pcap 53 | ========= 54 | 55 | This is the network dump generated by tcpdump or any other corresponding 56 | network sniffer. 57 | 58 | memory.dmp 59 | ========== 60 | 61 | In case you enabled it, this file contains the full memory dump of the analysis 62 | machine. 63 | 64 | files/ 65 | ====== 66 | 67 | This directory contains all the files the malware operated on and that Cuckoo 68 | was able to dump. 69 | 70 | logs/ 71 | ===== 72 | 73 | This directory contains all the raw logs generated by Cuckoo's process monitoring. 74 | 75 | reports/ 76 | ======== 77 | 78 | This directory contains all the reports generated by Cuckoo as explained in the 79 | :doc:`../installation/host/configuration` chapter. 80 | 81 | shots/ 82 | ====== 83 | 84 | This directory contains all the screenshots of the guest's desktop taken during 85 | the malware execution. -------------------------------------------------------------------------------- /docs/book/src/usage/start.rst: -------------------------------------------------------------------------------- 1 | =============== 2 | Starting Cuckoo 3 | =============== 4 | 5 | To start Cuckoo use the command:: 6 | 7 | $ python cuckoo.py 8 | 9 | Make sure to run it inside Cuckoo's root directory. 10 | 11 | You will get an output similar to this:: 12 | 13 | eeee e e eeee e e eeeee eeeee 14 | 8 8 8 8 8 8 8 8 8 88 8 88 15 | 8e 8e 8 8e 8eee8e 8 8 8 8 16 | 88 88 8 88 88 8 8 8 8 8 17 | 88e8 88ee8 88e8 88 8 8eee8 8eee8 18 | 19 | Cuckoo Sandbox 1.0 20 | www.cuckoosandbox.org 21 | Copyright (c) 2010-2014 22 | 23 | Checking for updates... 24 | Good! You have the latest version available. 25 | 26 | 2013-04-07 15:57:17,459 [lib.cuckoo.core.scheduler] INFO: Using "virtualbox" machine manager 27 | 2013-04-07 15:57:17,861 [lib.cuckoo.core.scheduler] INFO: Loaded 1 machine/s 28 | 2013-04-07 15:57:17,862 [lib.cuckoo.core.scheduler] INFO: Waiting for analysis tasks... 29 | 30 | Note that Cuckoo checks for updates on a remote API located at *api.cuckoosandbox.org*. 31 | You can avoid this by disabling the ``version_check`` option in the configuration file. 32 | 33 | Now Cuckoo is ready to run and it's waiting for submissions. 34 | 35 | ``cuckoo.py`` accepts some command line options as shown by the help:: 36 | 37 | usage: cuckoo.py [-h] [-q] [-d] [-v] [-a] 38 | 39 | optional arguments: 40 | -h, --help show this help message and exit 41 | -q, --quiet Display only error messages 42 | -d, --debug Display debug messages 43 | -v, --version show program's version number and exit 44 | -a, --artwork Show artwork 45 | 46 | Most importantly ``--debug`` and ``--quiet`` respectively increase and decrease the logging 47 | verbosity. 48 | -------------------------------------------------------------------------------- /docs/book/src/usage/utilities.rst: -------------------------------------------------------------------------------- 1 | ========= 2 | Utilities 3 | ========= 4 | 5 | Cuckoo comes with a set of pre-built utilities to automatize several common 6 | tasks. 7 | You can find them in "utils" folder. 8 | 9 | Cleanup utility 10 | =============== 11 | 12 | If you want to delete all history, analysis, data and begin again from the first 13 | task you need clean.sh utility. 14 | 15 | .. note:: 16 | 17 | Running clean.sh will delete: analysis results, binaries, SQLite database (if used) and logs. 18 | 19 | To clean your setup, run:: 20 | 21 | $ ./utils/clean.sh 22 | 23 | This utility is designed to be used with Cuckoo (including API and web interface) 24 | not running. 25 | 26 | If you are using a custom database (MySQL, PostgreSQL or SQLite in custom 27 | location) clean.sh doesn't clean it, you have to take care of that. 28 | 29 | Submission Utility 30 | ================== 31 | 32 | Submits sample to analysis. This tool is already described in :doc:`submit`. 33 | 34 | Web Utility 35 | =========== 36 | 37 | Cuckoo's web interface. This tool is already described in :doc:`submit`. 38 | 39 | Processing Utility 40 | ================== 41 | 42 | Run the results processing engine and optionally the reporting engine (run 43 | all reports) on an already available analysis folder, in order to not re-run 44 | the analysis if you want to re-generate the reports for it. 45 | This is used mainly in debugging and developing Cuckoo. 46 | For example if you want run again the report engine for analysis number 1:: 47 | 48 | $ ./utils/process.py 1 49 | 50 | If you want to re-generate the reports:: 51 | 52 | $ ./utils/process.py --report 1 53 | 54 | Community Download Utility 55 | ========================== 56 | 57 | This utility downloads signatures from `Cuckoo Community Repository`_ and installs 58 | specific additional modules in your local setup and for example update id with 59 | all the latest available signatures. 60 | Following are the usage options:: 61 | 62 | $ ./utils/community.py 63 | 64 | usage: community.py [-h] [-a] [-s] [-p] [-m] [-r] [-f] [-w] 65 | 66 | optional arguments: 67 | -h, --help show this help message and exit 68 | -a, --all Download everything 69 | -s, --signatures Download Cuckoo signatures 70 | -p, --processing Download processing modules 71 | -m, --machinemanagers 72 | Download machine managers 73 | -r, --reporting Download reporting modules 74 | -f, --force Install files without confirmation 75 | -w, --rewrite Rewrite existing files 76 | 77 | *Example*: install all available signatures:: 78 | 79 | $ ./utils/community.py --signatures --force 80 | 81 | .. _`Cuckoo Community Repository`: https://github.com/cuckoobox/community 82 | -------------------------------------------------------------------------------- /external/CPU.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djteller/MemoryAnalysis/13554135ec4614e1fa2a051c1ba76525a92eac1a/external/CPU.exe -------------------------------------------------------------------------------- /lib/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2010-2014 Cuckoo Sandbox Developers. 2 | # This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org 3 | # See the file 'docs/LICENSE' for copying permission. 4 | -------------------------------------------------------------------------------- /lib/cuckoo/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2010-2014 Cuckoo Sandbox Developers. 2 | # This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org 3 | # See the file 'docs/LICENSE' for copying permission. 4 | -------------------------------------------------------------------------------- /lib/cuckoo/common/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2010-2014 Cuckoo Sandbox Developers. 2 | # This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org 3 | # See the file 'docs/LICENSE' for copying permission. 4 | -------------------------------------------------------------------------------- /lib/cuckoo/common/colors.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2010-2014 Cuckoo Sandbox Developers. 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 | import sys 7 | 8 | def color(text, color_code): 9 | """Colorize text. 10 | @param text: text. 11 | @param color_code: color. 12 | @return: colorized text. 13 | """ 14 | # $TERM under Windows: 15 | # cmd.exe -> "" (what would you expect..?) 16 | # cygwin -> "cygwin" (should support colors, but doesn't work somehow) 17 | # mintty -> "xterm" (supports colors) 18 | if sys.platform == "win32" and os.getenv("TERM") != "xterm": 19 | return text 20 | return "\x1b[%dm%s\x1b[0m" % (color_code, text) 21 | 22 | def black(text): 23 | return color(text, 30) 24 | 25 | def red(text): 26 | return color(text, 31) 27 | 28 | def green(text): 29 | return color(text, 32) 30 | 31 | def yellow(text): 32 | return color(text, 33) 33 | 34 | def blue(text): 35 | return color(text, 34) 36 | 37 | def magenta(text): 38 | return color(text, 35) 39 | 40 | def cyan(text): 41 | return color(text, 36) 42 | 43 | def white(text): 44 | return color(text, 37) 45 | 46 | def bold(text): 47 | return color(text, 1) 48 | -------------------------------------------------------------------------------- /lib/cuckoo/common/config.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2010-2014 Cuckoo Sandbox Developers. 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 | import ConfigParser 7 | 8 | from lib.cuckoo.common.constants import CUCKOO_ROOT 9 | from lib.cuckoo.common.exceptions import CuckooOperationalError 10 | from lib.cuckoo.common.objects import Dictionary 11 | 12 | class Config: 13 | """Configuration file parser.""" 14 | 15 | def __init__(self, cfg=os.path.join(CUCKOO_ROOT, "conf", "cuckoo.conf")): 16 | """@param cfg: configuration file path.""" 17 | config = ConfigParser.ConfigParser() 18 | config.read(cfg) 19 | 20 | for section in config.sections(): 21 | setattr(self, section, Dictionary()) 22 | for name, raw_value in config.items(section): 23 | try: 24 | value = config.getboolean(section, name) 25 | except ValueError: 26 | try: 27 | value = config.getint(section, name) 28 | except ValueError: 29 | value = config.get(section, name) 30 | 31 | setattr(getattr(self, section), name, value) 32 | 33 | def get(self, section): 34 | """Get option. 35 | @param section: section to fetch. 36 | @raise CuckooOperationalError: if section not found. 37 | @return: option value. 38 | """ 39 | try: 40 | return getattr(self, section) 41 | except AttributeError as e: 42 | raise CuckooOperationalError("Option %s is not found in " 43 | "configuration, error: %s" % 44 | (section, e)) 45 | -------------------------------------------------------------------------------- /lib/cuckoo/common/defines.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2010-2014 Cuckoo Sandbox Developers. 2 | # This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org 3 | # See the file 'docs/LICENSE' for copying permission. 4 | 5 | REG_NONE = 0 6 | REG_SZ = 1 7 | REG_EXPAND_SZ = 2 8 | REG_BINARY = 3 9 | REG_DWORD_LITTLE_ENDIAN = 4 10 | REG_DWORD = 4 11 | REG_DWORD_BIG_ENDIAN = 5 12 | -------------------------------------------------------------------------------- /lib/cuckoo/common/exceptions.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2010-2014 Cuckoo Sandbox Developers. 2 | # This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org 3 | # See the file 'docs/LICENSE' for copying permission. 4 | 5 | class CuckooCriticalError(Exception): 6 | """Cuckoo struggle in a critical error.""" 7 | pass 8 | 9 | class CuckooStartupError(CuckooCriticalError): 10 | """Error starting up Cuckoo.""" 11 | pass 12 | 13 | class CuckooDatabaseError(CuckooCriticalError): 14 | """Cuckoo database error.""" 15 | pass 16 | 17 | class CuckooDependencyError(CuckooCriticalError): 18 | """Missing dependency error.""" 19 | pass 20 | 21 | class CuckooOperationalError(Exception): 22 | """Cuckoo operation error.""" 23 | pass 24 | 25 | class CuckooMachineError(CuckooOperationalError): 26 | """Error managing analysis machine.""" 27 | pass 28 | 29 | class CuckooAnalysisError(CuckooOperationalError): 30 | """Error during analysis.""" 31 | pass 32 | 33 | class CuckooProcessingError(CuckooOperationalError): 34 | """Error in processor module.""" 35 | pass 36 | 37 | class CuckooReportError(CuckooOperationalError): 38 | """Error in reporting module.""" 39 | pass 40 | 41 | class CuckooGuestError(CuckooOperationalError): 42 | """Cuckoo guest agent error.""" 43 | pass 44 | 45 | class CuckooResultError(CuckooOperationalError): 46 | """Cuckoo result server error.""" 47 | pass 48 | -------------------------------------------------------------------------------- /lib/cuckoo/core/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2010-2014 Cuckoo Sandbox Developers. 2 | # This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org 3 | # See the file 'docs/LICENSE' for copying permission. 4 | -------------------------------------------------------------------------------- /lib/maec/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2010-2014 Cuckoo Sandbox Developers. 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-2014 Cuckoo Sandbox Developers. 2 | # This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org 3 | # See the file 'docs/LICENSE' for copying permission. 4 | -------------------------------------------------------------------------------- /modules/auxiliary/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2010-2014 Cuckoo Sandbox Developers. 2 | # This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org 3 | # See the file 'docs/LICENSE' for copying permission. 4 | -------------------------------------------------------------------------------- /modules/machinery/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2010-2014 Cuckoo Sandbox Developers. 2 | # This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org 3 | # See the file 'docs/LICENSE' for copying permission. 4 | -------------------------------------------------------------------------------- /modules/machinery/esx.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2010-2014 Cuckoo Sandbox Developers. 2 | # Copyright (C) 2013 Christopher Schmitt 3 | # This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org 4 | # See the file 'docs/LICENSE' for copying permission. 5 | 6 | import logging 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 | def _initialize_check(self): 16 | """Runs all checks when a machine manager is initialized. 17 | @raise CuckooMachineError: if configuration is invalid 18 | """ 19 | if not self.options.esx.dsn: 20 | raise CuckooMachineError("ESX(i) DSN is missing, please add it to the config file") 21 | if not self.options.esx.username: 22 | raise CuckooMachineError("ESX(i) username is missing, please add it to the config file") 23 | if not self.options.esx.password: 24 | raise CuckooMachineError("ESX(i) password is missing, please add it to the config file") 25 | 26 | self.dsn = self.options.esx.dsn 27 | 28 | super(ESX, self)._initialize_check() 29 | 30 | def _auth_callback(self, credentials, user_data): 31 | for credential in credentials: 32 | if credential[0] == libvirt.VIR_CRED_AUTHNAME: 33 | credential[4] = self.options.esx.username 34 | elif credential[0] == libvirt.VIR_CRED_NOECHOPROMPT: 35 | credential[4] = self.options.esx.password 36 | else: 37 | raise CuckooCriticalError("ESX machinery did not recieve an object to inject a username or password into") 38 | 39 | return 0 40 | 41 | def _connect(self): 42 | try: 43 | self.auth = [[libvirt.VIR_CRED_AUTHNAME, libvirt.VIR_CRED_NOECHOPROMPT], self._auth_callback, None] 44 | return libvirt.openAuth(self.dsn, self.auth, 0) 45 | except libvirt.libvirtError as libvex: 46 | raise CuckooCriticalError("libvirt returned an exception on connection: %s" % libvex) 47 | -------------------------------------------------------------------------------- /modules/machinery/kvm.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2010-2014 Cuckoo Sandbox Developers. 2 | # This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org 3 | # See the file 'docs/LICENSE' for copying permission. 4 | 5 | from lib.cuckoo.common.abstracts import LibVirtMachinery 6 | 7 | class KVM(LibVirtMachinery): 8 | """Virtualization layer for KVM based on python-libvirt.""" 9 | 10 | # Set KVM connection string. 11 | dsn = "qemu:///system" 12 | -------------------------------------------------------------------------------- /modules/processing/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2010-2014 Cuckoo Sandbox Developers. 2 | # This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org 3 | # See the file 'docs/LICENSE' for copying permission. 4 | -------------------------------------------------------------------------------- /modules/processing/analysisinfo.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2010-2014 Cuckoo Sandbox Developers. 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 logging 7 | from datetime import datetime 8 | 9 | from lib.cuckoo.common.abstracts import Processing 10 | from lib.cuckoo.common.constants import CUCKOO_VERSION 11 | 12 | log = logging.getLogger(__name__) 13 | 14 | 15 | class AnalysisInfo(Processing): 16 | """General information about analysis session.""" 17 | 18 | def run(self): 19 | """Run information gathering. 20 | @return: information dict. 21 | """ 22 | self.key = "info" 23 | 24 | try: 25 | started = time.strptime(self.task["started_on"], 26 | "%Y-%m-%d %H:%M:%S") 27 | started = datetime.fromtimestamp(time.mktime(started)) 28 | 29 | ended = time.strptime(self.task["completed_on"], 30 | "%Y-%m-%d %H:%M:%S") 31 | ended = datetime.fromtimestamp(time.mktime(ended)) 32 | except: 33 | log.critical("Failed to get start/end time from Task.") 34 | # just set it to default timeout 35 | duration = -1 36 | else: 37 | duration = (ended - started).seconds 38 | 39 | info = { 40 | "version": CUCKOO_VERSION, 41 | "started": self.task["started_on"], 42 | "ended": self.task.get("completed_on", "none"), 43 | "duration": duration, 44 | "id": int(self.task["id"]), 45 | "category": self.task["category"], 46 | "custom": self.task["custom"] 47 | } 48 | 49 | return info 50 | -------------------------------------------------------------------------------- /modules/processing/debug.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2010-2014 Cuckoo Sandbox Developers. 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 | import codecs 7 | 8 | from lib.cuckoo.common.abstracts import Processing 9 | from lib.cuckoo.common.exceptions import CuckooProcessingError 10 | from lib.cuckoo.core.database import Database 11 | 12 | class Debug(Processing): 13 | """Analysis debug information.""" 14 | 15 | def run(self): 16 | """Run debug analysis. 17 | @return: debug information dict. 18 | """ 19 | self.key = "debug" 20 | debug = {"log": "", "errors": []} 21 | 22 | if os.path.exists(self.log_path): 23 | try: 24 | debug["log"] = codecs.open(self.log_path, "rb", "utf-8").read() 25 | except ValueError as e: 26 | raise CuckooProcessingError("Error decoding %s: %s" % 27 | (self.log_path, e)) 28 | except (IOError, OSError) as e: 29 | raise CuckooProcessingError("Error opening %s: %s" % 30 | (self.log_path, e)) 31 | 32 | for error in Database().view_errors(int(self.task["id"])): 33 | debug["errors"].append(error.message) 34 | 35 | return debug 36 | -------------------------------------------------------------------------------- /modules/processing/dropped.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2010-2014 Cuckoo Sandbox Developers. 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 | 7 | from lib.cuckoo.common.abstracts import Processing 8 | from lib.cuckoo.common.objects import File 9 | 10 | class Dropped(Processing): 11 | """Dropped files analysis.""" 12 | 13 | def run(self): 14 | """Run analysis. 15 | @return: list of dropped files with related information. 16 | """ 17 | self.key = "dropped" 18 | dropped_files = [] 19 | 20 | for dir_name, dir_names, file_names in os.walk(self.dropped_path): 21 | for file_name in file_names: 22 | file_path = os.path.join(dir_name, file_name) 23 | file_info = File(file_path=file_path).get_all() 24 | dropped_files.append(file_info) 25 | 26 | return dropped_files 27 | -------------------------------------------------------------------------------- /modules/processing/strings.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2010-2014 Cuckoo Sandbox Developers. 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.path 6 | import re 7 | 8 | from lib.cuckoo.common.abstracts import Processing 9 | from lib.cuckoo.common.exceptions import CuckooProcessingError 10 | 11 | class Strings(Processing): 12 | """Extract strings from analyzed file.""" 13 | 14 | def run(self): 15 | """Run extract of printable strings. 16 | @return: list of printable strings. 17 | """ 18 | self.key = "strings" 19 | strings = [] 20 | 21 | if self.task["category"] == "file": 22 | if not os.path.exists(self.file_path): 23 | raise CuckooProcessingError("Sample file doesn't exist: \"%s\"" % self.file_path) 24 | 25 | try: 26 | data = open(self.file_path, "r").read() 27 | except (IOError, OSError) as e: 28 | raise CuckooProcessingError("Error opening file %s" % e) 29 | strings = re.findall("[\x1f-\x7e]{6,}", data) 30 | 31 | return strings 32 | -------------------------------------------------------------------------------- /modules/processing/targetinfo.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2010-2014 Cuckoo Sandbox Developers. 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.path 6 | 7 | from lib.cuckoo.common.abstracts import Processing 8 | from lib.cuckoo.common.objects import File 9 | 10 | class TargetInfo(Processing): 11 | """General information about a file.""" 12 | 13 | def run(self): 14 | """Run file information gathering. 15 | @return: information dict. 16 | """ 17 | self.key = "target" 18 | 19 | target_info = {"category": self.task["category"]} 20 | 21 | if self.task["category"] == "file": 22 | target_info["file"] = {} 23 | 24 | # let's try to get as much information as possible, i.e., the 25 | # filename if the file is not available anymore 26 | if os.path.exists(self.file_path): 27 | target_info["file"] = File(self.file_path).get_all() 28 | 29 | target_info["file"]["name"] = File(self.task["target"]).get_name() 30 | elif self.task["category"] == "url": 31 | target_info["url"] = self.task["target"] 32 | 33 | return target_info -------------------------------------------------------------------------------- /modules/processing/virustotal.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2010-2014 Cuckoo Sandbox Developers. 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 | import json 7 | import urllib 8 | import urllib2 9 | 10 | from lib.cuckoo.common.abstracts import Processing 11 | from lib.cuckoo.common.exceptions import CuckooProcessingError 12 | from lib.cuckoo.common.objects import File 13 | 14 | VIRUSTOTAL_FILE_URL = "https://www.virustotal.com/vtapi/v2/file/report" 15 | VIRUSTOTAL_URL_URL = "https://www.virustotal.com/vtapi/v2/url/report" 16 | 17 | class VirusTotal(Processing): 18 | """Gets antivirus signatures from VirusTotal.com""" 19 | 20 | def run(self): 21 | """Runs VirusTotal processing 22 | @return: full VirusTotal report. 23 | """ 24 | self.key = "virustotal" 25 | virustotal = [] 26 | 27 | key = self.options.get("key", None) 28 | if not key: 29 | raise CuckooProcessingError("VirusTotal API key not " 30 | "configured, skip") 31 | 32 | if self.task["category"] == "file": 33 | if not os.path.exists(self.file_path): 34 | raise CuckooProcessingError("File {0} not found, skipping it".format(self.file_path)) 35 | 36 | resource = File(self.file_path).get_md5() 37 | url = VIRUSTOTAL_FILE_URL 38 | elif self.task["category"] == "url": 39 | resource = self.task["target"] 40 | url = VIRUSTOTAL_URL_URL 41 | 42 | data = urllib.urlencode({"resource": resource, "apikey": key}) 43 | 44 | try: 45 | request = urllib2.Request(url, data) 46 | response = urllib2.urlopen(request) 47 | response_data = response.read() 48 | except urllib2.URLError as e: 49 | raise CuckooProcessingError("Unable to establish connection " 50 | "to VirusTotal: {0}".format(e)) 51 | except urllib2.HTTPError as e: 52 | raise CuckooProcessingError("Unable to perform HTTP request to " 53 | "VirusTotal " 54 | "(http code={0})".format(e.code)) 55 | 56 | try: 57 | virustotal = json.loads(response_data) 58 | except ValueError as e: 59 | raise CuckooProcessingError("Unable to convert response to " 60 | "JSON: {0}".format(e)) 61 | 62 | if "scans" in virustotal: 63 | items = virustotal["scans"].items() 64 | virustotal["scans"] = dict((engine.replace(".", "_"), signature) 65 | for engine, signature in items) 66 | 67 | return virustotal 68 | -------------------------------------------------------------------------------- /modules/reporting/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2010-2014 Cuckoo Sandbox Developers. 2 | # This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org 3 | # See the file 'docs/LICENSE' for copying permission. 4 | -------------------------------------------------------------------------------- /modules/reporting/hpfclient.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2010-2014 Cuckoo Sandbox Developers. 2 | # This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org 3 | # See the file 'docs/LICENSE' for copying permission. 4 | 5 | import json 6 | 7 | from lib.cuckoo.common.abstracts import Report 8 | from lib.cuckoo.common.exceptions import CuckooDependencyError 9 | from lib.cuckoo.common.exceptions import CuckooReportError 10 | 11 | try: 12 | import lib.hpfeeds as hpfeeds 13 | except: 14 | raise CuckooDependencyError("Unable to import HPFeeds library") 15 | 16 | class HPFClient(Report): 17 | """Publishes the results on an HPFeeds broker channel.""" 18 | 19 | def run(self, results): 20 | """Sends JSON report to HPFeeds channel. 21 | @param results: Cuckoo results dict. 22 | @raise CuckooReportError: if fails to write report. 23 | """ 24 | try: 25 | hpc = hpfeeds.HPC(self.options["host"], self.options["port"], self.options["ident"], self.options["secret"], timeout=60) 26 | hpc.publish(self.options["channel"], json.dumps(results, sort_keys=False, indent=4)) 27 | hpc.close() 28 | except hpfeeds.FeedException as e: 29 | raise CuckooReportError("Failed to publish on HPFeeds channel: %s" % e) -------------------------------------------------------------------------------- /modules/reporting/jsondump.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2010-2014 Cuckoo Sandbox Developers. 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 | import json 7 | import codecs 8 | 9 | from lib.cuckoo.common.abstracts import Report 10 | from lib.cuckoo.common.exceptions import CuckooReportError 11 | 12 | class JsonDump(Report): 13 | """Saves analysis results in JSON format.""" 14 | 15 | def run(self, results): 16 | """Writes report. 17 | @param results: Cuckoo results dict. 18 | @raise CuckooReportError: if fails to write report. 19 | """ 20 | try: 21 | path = os.path.join(self.reports_path, "report.json") 22 | report = codecs.open(path, "w", "utf-8") 23 | json.dump(results, report, sort_keys=False, indent=4) 24 | report.close() 25 | except (UnicodeError, TypeError, IOError) as e: 26 | raise CuckooReportError("Failed to generate JSON report: %s" % e) 27 | -------------------------------------------------------------------------------- /modules/reporting/reporthtml.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2010-2014 Cuckoo Sandbox Developers. 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 | import codecs 7 | import base64 8 | 9 | from lib.cuckoo.common.abstracts import Report 10 | from lib.cuckoo.common.constants import CUCKOO_ROOT 11 | from lib.cuckoo.common.exceptions import CuckooReportError 12 | from lib.cuckoo.common.objects import File 13 | 14 | try: 15 | from jinja2.environment import Environment 16 | from jinja2.loaders import FileSystemLoader 17 | HAVE_JINJA2 = True 18 | except ImportError: 19 | HAVE_JINJA2 = False 20 | 21 | class ReportHTML(Report): 22 | """Stores report in HTML format.""" 23 | 24 | def run(self, results): 25 | """Writes report. 26 | @param results: Cuckoo results dict. 27 | @raise CuckooReportError: if fails to write report. 28 | """ 29 | if not HAVE_JINJA2: 30 | raise CuckooReportError("Failed to generate HTML report: " 31 | "Jinja2 Python library is not installed") 32 | 33 | shots_path = os.path.join(self.analysis_path, "shots") 34 | if os.path.exists(shots_path): 35 | shots = [] 36 | counter = 1 37 | for shot_name in os.listdir(shots_path): 38 | if not shot_name.endswith(".jpg"): 39 | continue 40 | 41 | shot_path = os.path.join(shots_path, shot_name) 42 | 43 | if os.path.getsize(shot_path) == 0: 44 | continue 45 | 46 | shot = {} 47 | shot["id"] = os.path.splitext(File(shot_path).get_name())[0] 48 | shot["data"] = base64.b64encode(open(shot_path, "rb").read()) 49 | shots.append(shot) 50 | 51 | counter += 1 52 | 53 | shots.sort(key=lambda shot: shot["id"]) 54 | results["screenshots"] = shots 55 | else: 56 | results["screenshots"] = [] 57 | 58 | env = Environment(autoescape=True) 59 | env.loader = FileSystemLoader(os.path.join(CUCKOO_ROOT, 60 | "data", "html")) 61 | 62 | try: 63 | tpl = env.get_template("report.html") 64 | html = tpl.render({"results": results}) 65 | except Exception as e: 66 | raise CuckooReportError("Failed to generate HTML report: %s" % e) 67 | 68 | try: 69 | with codecs.open(os.path.join(self.reports_path, "report.html"), "w", encoding="utf-8") as report: 70 | report.write(html) 71 | except (TypeError, IOError) as e: 72 | raise CuckooReportError("Failed to write HTML report: %s" % e) 73 | 74 | return True 75 | -------------------------------------------------------------------------------- /modules/signatures/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2010-2014 Cuckoo Sandbox Developers. 2 | # This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org 3 | # See the file 'docs/LICENSE' for copying permission. 4 | -------------------------------------------------------------------------------- /modules/signatures/creates_exe.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2010-2014 Cuckoo Sandbox Developers. 2 | # This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org 3 | # See the file 'docs/LICENSE' for copying permission. 4 | 5 | from lib.cuckoo.common.abstracts import Signature 6 | 7 | class CreatesExe(Signature): 8 | name = "creates_exe" 9 | description = "Creates a Windows executable on the filesystem" 10 | severity = 2 11 | categories = ["generic"] 12 | authors = ["Cuckoo Developers"] 13 | minimum = "0.5" 14 | 15 | # This is a signature template. It should be used as a skeleton for 16 | # creating custom signatures, therefore is disabled by default. 17 | # It doesn't verify whether a .exe is actually being created, but 18 | # it matches files being opened with any access type, including 19 | # read and attributes lookup. 20 | enabled = False 21 | 22 | def run(self): 23 | match = self.check_file(pattern=".*\\.exe$", 24 | regex=True) 25 | if match: 26 | self.data.append({"file": match}) 27 | return True 28 | 29 | return False 30 | -------------------------------------------------------------------------------- /modules/signatures/generic_metrics.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2010-2014 Cuckoo Sandbox Developers. 2 | # This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org 3 | # See the file 'docs/LICENSE' for copying permission. 4 | 5 | from lib.cuckoo.common.abstracts import Signature 6 | 7 | class SystemMetrics(Signature): 8 | name = "generic_metrics" 9 | description = "Uses GetSystemMetrics" 10 | severity = 2 11 | categories = ["generic"] 12 | authors = ["Cuckoo Developers"] 13 | minimum = "1.0" 14 | 15 | # Evented signatures need to implement the "on_call" method 16 | evented = True 17 | 18 | # Evented signatures can specify filters that reduce the amount of 19 | # API calls that are streamed in. One can filter Process name, API 20 | # name/identifier and category. These should be sets for faster lookup. 21 | filter_processnames = set() 22 | filter_apinames = set(["GetSystemMetrics"]) 23 | filter_categories = set() 24 | 25 | # This is a signature template. It should be used as a skeleton for 26 | # creating custom signatures, therefore is disabled by default. 27 | # The on_call function is used in "evented" signatures. 28 | # These use a more efficient way of processing logged API calls. 29 | enabled = False 30 | 31 | def stop(self): 32 | # In the stop method one can implement any cleanup code and 33 | # decide one last time if this signature matches or not. 34 | # Return True in case it matches. 35 | return False 36 | 37 | # This method will be called for every logged API call by the loop 38 | # in the RunSignatures plugin. The return value determines the "state" 39 | # of this signature. True means the signature matched and False means 40 | # it can't match anymore. Both of which stop streaming in API calls. 41 | # Returning None keeps the signature active and will continue. 42 | def on_call(self, call, process): 43 | # This check would in reality not be needed as we already make use 44 | # of filter_apinames above. 45 | if call["api"] == "GetSystemMetrics": 46 | # Signature matched, return True. 47 | return True 48 | 49 | # continue 50 | return None 51 | -------------------------------------------------------------------------------- /tests/colors_tests.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2010-2014 Cuckoo Sandbox Developers. 2 | # This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org 3 | # See the file 'docs/LICENSE' for copying permission. 4 | 5 | from nose.tools import assert_equals 6 | 7 | from lib.cuckoo.common.colors import color 8 | 9 | 10 | def test_return_text(): 11 | """Test colorized text contains the input string.""" 12 | assert "foo" in color("foo", 11) -------------------------------------------------------------------------------- /tests/config_tests.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2010-2014 Cuckoo Sandbox Developers. 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 | import tempfile 7 | from nose.tools import assert_equals, raises 8 | 9 | from lib.cuckoo.common.config import Config 10 | from lib.cuckoo.common.exceptions import CuckooOperationalError 11 | 12 | 13 | class TestConfig: 14 | CONF_EXAMPLE = """ 15 | [cuckoo] 16 | debug = off 17 | analysis_timeout = 120 18 | critical_timeout = 600 19 | delete_original = off 20 | machine_manager = kvm 21 | use_sniffer = no 22 | tcpdump = /usr/sbin/tcpdump 23 | interface = vboxnet0 24 | """ 25 | 26 | def setUp(self): 27 | self.file = tempfile.mkstemp()[1] 28 | self._load_conf(self.CONF_EXAMPLE) 29 | self.c = Config(self.file) 30 | 31 | def _load_conf(self, conf): 32 | """Loads a configuration from a string. 33 | @param conf: configuration string. 34 | """ 35 | f = open(self.file, "w") 36 | f.write(conf) 37 | f.close() 38 | 39 | def test_get_option_exist(self): 40 | """Fetch an option of each type from default config file.""" 41 | assert_equals(self.c.get("cuckoo")["debug"], False) 42 | assert_equals(self.c.get("cuckoo")["tcpdump"], "/usr/sbin/tcpdump") 43 | assert_equals(self.c.get("cuckoo")["critical_timeout"], 600) 44 | 45 | def test_config_file_not_found(self): 46 | assert Config("foo") 47 | 48 | @raises(CuckooOperationalError) 49 | def test_get_option_not_found(self): 50 | self.c.get("foo") 51 | 52 | @raises(CuckooOperationalError) 53 | def test_get_option_not_found_in_file_not_found(self): 54 | self.c = Config("bar") 55 | self.c.get("foo") 56 | -------------------------------------------------------------------------------- /tests/processor_tests.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2010-2014 Cuckoo Sandbox Developers. 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 | import tempfile 7 | from nose.tools import assert_equals 8 | 9 | from lib.cuckoo.core.processor import Processor 10 | from lib.cuckoo.common.constants import CUCKOO_VERSION 11 | from lib.cuckoo.common.abstracts import Processing, Signature 12 | 13 | 14 | class TestProcessor: 15 | def setUp(self): 16 | self.tmp = tempfile.mkdtemp() 17 | self.p = Processor(self.tmp) 18 | 19 | def test_run_processing(self): 20 | res = self.p._run_processing(ProcessingMock) 21 | assert "foo" in res 22 | assert "bar" in res["foo"] 23 | 24 | def test_run_signature_alter_results(self): 25 | """@note: regression test.""" 26 | res = {"foo": "bar"} 27 | self.p._run_signature(SignatureMock, res) 28 | assert_equals(res["foo"], "bar") 29 | 30 | def test_signature_disabled(self): 31 | res = {"foo": "bar"} 32 | assert_equals(None, self.p._run_signature(SignatureDisabledMock, res)) 33 | 34 | def test_signature_wrong_version(self): 35 | res = {"foo": "bar"} 36 | assert_equals(None, self.p._run_signature(SignatureWrongVersionMock, res)) 37 | 38 | def tearDown(self): 39 | os.rmdir(self.tmp) 40 | 41 | class ProcessingMock(Processing): 42 | def run(self): 43 | self.key = "foo" 44 | foo = { 45 | "bar" : "taz" 46 | } 47 | return foo 48 | 49 | class SignatureMock(Signature): 50 | name = "mock" 51 | minimum = CUCKOO_VERSION.split("-")[0] 52 | maximum = CUCKOO_VERSION.split("-")[0] 53 | 54 | def run(self, results): 55 | if "foo" in results: 56 | return True 57 | else: 58 | return False 59 | 60 | class SignatureAlterMock(SignatureMock): 61 | def run(self, results): 62 | results = None 63 | 64 | class SignatureDisabledMock(SignatureMock): 65 | enabled = False 66 | 67 | class SignatureWrongVersionMock(SignatureMock): 68 | minimum = "0.0..-abc" 69 | maximum = "0.0..-abc" 70 | 71 | -------------------------------------------------------------------------------- /tests/reporter_tests.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2010-2014 Cuckoo Sandbox Developers. 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 | import tempfile 7 | from nose.tools import assert_equals 8 | 9 | from lib.cuckoo.core.reporter import Reporter 10 | from lib.cuckoo.common.abstracts import Report 11 | from lib.cuckoo.common.config import Config 12 | 13 | 14 | class TestReporter: 15 | CONFIG = """ 16 | [reporter_tests] 17 | enabled = on 18 | """ 19 | 20 | def setUp(self): 21 | self.tmp = tempfile.mkdtemp() 22 | self.cfg = tempfile.mkstemp()[1] 23 | f = open(self.cfg, "w") 24 | f.write(self.CONFIG) 25 | f.close() 26 | self.r = Reporter(self.tmp) 27 | self.r.cfg = Config(self.cfg) 28 | 29 | def test_run_report(self): 30 | results = {} 31 | self.r._run_report(ReportMock, results) 32 | 33 | def test_run_report_alter_results(self): 34 | """@note: Regression test.""" 35 | results = {"foo": "bar"} 36 | self.r._run_report(ReportAlterMock, results) 37 | assert_equals(results, {"foo": "bar"}) 38 | 39 | def tearDown(self): 40 | os.rmdir(os.path.join(self.tmp, "reports")) 41 | os.rmdir(self.tmp) 42 | os.remove(self.cfg) 43 | 44 | class ReportMock(Report): 45 | def run(self, data): 46 | return 47 | 48 | class ReportAlterMock(Report): 49 | """Corrupts results dict.""" 50 | def run(self, data): 51 | data['foo'] = 'notbar' 52 | return -------------------------------------------------------------------------------- /tests/sniffer_tests.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2010-2014 Cuckoo Sandbox Developers. 2 | # This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org 3 | # See the file 'docs/LICENSE' for copying permissi 4 | 5 | from nose.tools import assert_equals 6 | from lib.cuckoo.core.sniffer import Sniffer 7 | 8 | 9 | class TestSniffer: 10 | def test_tcpdump_path_(self): 11 | assert_equals(Sniffer("foo").tcpdump, "foo") 12 | 13 | def test_tcpdump_not_found(self): 14 | assert_equals(False, Sniffer("foo").start()) 15 | 16 | def test_interface_not_found(self): 17 | assert_equals(False, Sniffer("foo").start("ethfoo")) 18 | -------------------------------------------------------------------------------- /utils/clean.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Copyright (C) 2010-2014 Cuckoo Sandbox Developers. 3 | # This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org 4 | # See the file 'docs/LICENSE' for copying permission. 5 | 6 | # I'm sure this can be done easier, but I'm not very familiar with bash 7 | # scripting.. So, here we go. Also, this only works from "./cuckoo" and 8 | # "./cuckoo/utils" directory, but it's still better than before. 9 | if [[ $PWD/ = */utils/ ]]; then 10 | export PWD=${PWD:0:${#PWD}-6} 11 | fi 12 | 13 | rm -rf $PWD/db/ $PWD/log/ $PWD/storage/ 14 | find $PWD/ -name '*.pyc' -exec rm {} \; 15 | -------------------------------------------------------------------------------- /utils/process.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Copyright (C) 2010-2014 Cuckoo Sandbox Developers. 3 | # This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org 4 | # See the file 'docs/LICENSE' for copying permission. 5 | 6 | import os 7 | import sys 8 | import time 9 | import logging 10 | import argparse 11 | 12 | logging.basicConfig(level=logging.INFO) 13 | log = logging.getLogger() 14 | 15 | sys.path.append(os.path.join(os.path.abspath(os.path.dirname(__file__)), "..")) 16 | 17 | from lib.cuckoo.common.config import Config 18 | from lib.cuckoo.core.database import Database, TASK_REPORTED, TASK_COMPLETED 19 | from lib.cuckoo.core.database import TASK_FAILED_PROCESSING 20 | from lib.cuckoo.core.plugins import RunProcessing, RunSignatures, RunReporting 21 | from lib.cuckoo.core.startup import init_modules 22 | 23 | def do(aid, report=False): 24 | results = RunProcessing(task_id=aid).run() 25 | RunSignatures(results=results).run() 26 | 27 | if report: 28 | RunReporting(task_id=aid, results=results).run() 29 | Database().set_status(aid, TASK_REPORTED) 30 | 31 | def main(): 32 | parser = argparse.ArgumentParser() 33 | parser.add_argument("id", type=str, help="ID of the analysis to process") 34 | parser.add_argument("-d", "--debug", help="Display debug messages", action="store_true", required=False) 35 | parser.add_argument("-r", "--report", help="Re-generate report", action="store_true", required=False) 36 | args = parser.parse_args() 37 | 38 | if args.debug: 39 | log.setLevel(logging.DEBUG) 40 | 41 | init_modules() 42 | 43 | if args.id == "auto": 44 | cfg = Config() 45 | maxcount = cfg.cuckoo.max_analysis_count 46 | count = 0 47 | db = Database() 48 | while count < maxcount or not maxcount: 49 | tasks = db.list_tasks(status=TASK_COMPLETED, limit=1) 50 | 51 | for task in tasks: 52 | log.info("Processing analysis data for Task #%d", task.id) 53 | try: 54 | do(task.id, report=True) 55 | except: 56 | log.exception("Exception when processing a task.") 57 | db.set_status(task.id, TASK_FAILED_PROCESSING) 58 | else: 59 | log.info("Task #%d: reports generation completed", task.id) 60 | 61 | count += 1 62 | 63 | if not tasks: 64 | time.sleep(5) 65 | 66 | else: 67 | do(args.id, report=args.report) 68 | 69 | 70 | if __name__ == "__main__": 71 | main() 72 | -------------------------------------------------------------------------------- /utils/stats.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Copyright (C) 2010-2014 Cuckoo Sandbox Developers. 3 | # This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org 4 | # See the file 'docs/LICENSE' for copying permission. 5 | 6 | import os.path 7 | import sys 8 | import time 9 | 10 | sys.path.append(os.path.join(os.path.abspath(os.path.dirname(__file__)), "..")) 11 | 12 | from lib.cuckoo.core.database import Database, TASK_PENDING, TASK_RUNNING 13 | from lib.cuckoo.core.database import TASK_COMPLETED, TASK_RECOVERED 14 | from lib.cuckoo.core.database import TASK_REPORTED, TASK_FAILED_ANALYSIS 15 | from lib.cuckoo.core.database import TASK_FAILED_PROCESSING 16 | 17 | def timestamp(dt): 18 | """Returns the timestamp of a datetime object.""" 19 | return time.mktime(dt.timetuple()) 20 | 21 | def main(): 22 | db = Database() 23 | 24 | print("%d samples in db" % db.count_samples()) 25 | print("%d tasks in db" % db.count_tasks()) 26 | 27 | states = ( 28 | TASK_PENDING, TASK_RUNNING, 29 | TASK_COMPLETED, TASK_RECOVERED, TASK_REPORTED, 30 | TASK_FAILED_ANALYSIS, TASK_FAILED_PROCESSING, 31 | ) 32 | 33 | for state in states: 34 | print("%s %d tasks" % (state, db.count_tasks(state))) 35 | 36 | # Later on we might be interested in only calculating stats for all 37 | # tasks starting at a certain offset, because the Cuckoo daemon may 38 | # have been restarted at some point in time. 39 | offset = None 40 | 41 | # For the following stats we're only interested in completed tasks. 42 | tasks = db.list_tasks(offset=offset, status=TASK_COMPLETED) 43 | tasks += db.list_tasks(offset=offset, status=TASK_REPORTED) 44 | 45 | if tasks: 46 | # Get the time when the first task started. 47 | started = min(timestamp(task.started_on) for task in tasks) 48 | 49 | # Get the time when the last task completed. 50 | completed = max(timestamp(task.completed_on) for task in tasks) 51 | 52 | # Get the amount of tasks that actually completed. 53 | finished = len(tasks) 54 | 55 | hourly = 60 * 60 * finished / (completed - started) 56 | 57 | print("roughly %d tasks an hour" % int(hourly)) 58 | print("roughly %d tasks a day" % int(24 * hourly)) 59 | 60 | if __name__ == "__main__": 61 | main() 62 | -------------------------------------------------------------------------------- /web/analysis/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2010-2014 Cuckoo Sandbox Developers. 2 | # This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org 3 | # See the file 'docs/LICENSE' for copying permission. -------------------------------------------------------------------------------- /web/analysis/forms.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2010-2014 Cuckoo Sandbox Developers. 2 | # This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org 3 | # See the file 'docs/LICENSE' for copying permission. 4 | 5 | from django import forms 6 | 7 | from submission.models import Comment, Tag 8 | 9 | class CommentForm(forms.ModelForm): 10 | class Meta: 11 | model = Comment 12 | fields = ["message"] 13 | 14 | class TagForm(forms.ModelForm): 15 | class Meta: 16 | model = Tag 17 | fields = ["name"] 18 | -------------------------------------------------------------------------------- /web/analysis/urls.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2010-2014 Cuckoo Sandbox Developers. 2 | # This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org 3 | # See the file "docs/LICENSE" for copying permission. 4 | 5 | from django.conf.urls import patterns, url 6 | 7 | urlpatterns = patterns("", 8 | url(r"^$", "analysis.views.index"), 9 | url(r"^(?P\d+)/$", "analysis.views.report"), 10 | url(r"^chunk/(?P\d+)/(?P\d+)/(?P\d+)/$", "analysis.views.chunk"), 11 | url(r"^search/$", "analysis.views.search"), 12 | url(r"^pending/$", "analysis.views.pending"), 13 | ) 14 | -------------------------------------------------------------------------------- /web/dashboard/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djteller/MemoryAnalysis/13554135ec4614e1fa2a051c1ba76525a92eac1a/web/dashboard/__init__.py -------------------------------------------------------------------------------- /web/dashboard/urls.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2010-2014 Cuckoo Sandbox Developers. 2 | # This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org 3 | # See the file "docs/LICENSE" for copying permission. 4 | 5 | from django.conf.urls import patterns, url 6 | 7 | urlpatterns = patterns("", 8 | url(r"^$", "dashboard.views.index"), 9 | ) 10 | -------------------------------------------------------------------------------- /web/dashboard/views.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2010-2014 Cuckoo Sandbox Developers. 2 | # This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org 3 | # See the file 'docs/LICENSE' for copying permission. 4 | 5 | import sys 6 | import time 7 | 8 | from django.conf import settings 9 | from django.template import RequestContext 10 | from django.http import HttpResponse 11 | from django.shortcuts import render_to_response 12 | from django.views.decorators.http import require_safe 13 | 14 | sys.path.append(settings.CUCKOO_PATH) 15 | 16 | from lib.cuckoo.core.database import Database, TASK_PENDING, TASK_RUNNING 17 | from lib.cuckoo.core.database import TASK_COMPLETED, TASK_RECOVERED 18 | from lib.cuckoo.core.database import TASK_REPORTED, TASK_FAILED_ANALYSIS 19 | from lib.cuckoo.core.database import TASK_FAILED_PROCESSING 20 | 21 | def timestamp(dt): 22 | """Returns the timestamp of a datetime object.""" 23 | if not dt: return None 24 | return time.mktime(dt.timetuple()) 25 | 26 | @require_safe 27 | def index(request): 28 | db = Database() 29 | 30 | report = dict( 31 | total_samples=db.count_samples(), 32 | total_tasks=db.count_tasks(), 33 | states_count={}, 34 | estimate_hour=None, 35 | estimate_day=None 36 | ) 37 | 38 | states = ( 39 | TASK_PENDING, 40 | TASK_RUNNING, 41 | TASK_COMPLETED, 42 | TASK_RECOVERED, 43 | TASK_REPORTED, 44 | TASK_FAILED_ANALYSIS, 45 | TASK_FAILED_PROCESSING, 46 | ) 47 | 48 | for state in states: 49 | report["states_count"][state] = db.count_tasks(state) 50 | 51 | offset = None 52 | 53 | # For the following stats we're only interested in completed tasks. 54 | tasks = db.list_tasks(offset=offset, status=TASK_COMPLETED) 55 | tasks += db.list_tasks(offset=offset, status=TASK_REPORTED) 56 | 57 | if tasks: 58 | # Get the time when the first task started. 59 | started = min(timestamp(task.started_on) for task in tasks) 60 | 61 | # Get the time when the last task completed. 62 | completed = max(timestamp(task.completed_on) for task in tasks) 63 | 64 | # Get the amount of tasks that actually completed. 65 | finished = len(tasks) 66 | 67 | hourly = 60 * 60 * finished / (completed - started) 68 | 69 | report["estimate_hour"] = int(hourly) 70 | report["estimate_day"] = int(24 * hourly) 71 | 72 | return render_to_response("dashboard/index.html", 73 | {"report" : report}, 74 | context_instance=RequestContext(request)) 75 | -------------------------------------------------------------------------------- /web/manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Copyright (C) 2010-2014 Cuckoo Sandbox Developers. 3 | # This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org 4 | # See the file 'docs/LICENSE' for copying permission. 5 | 6 | import os 7 | import sys 8 | 9 | if __name__ == "__main__": 10 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "web.settings") 11 | 12 | from django.core.management import execute_from_command_line 13 | 14 | execute_from_command_line(sys.argv) 15 | -------------------------------------------------------------------------------- /web/static/css/style.css: -------------------------------------------------------------------------------- 1 | html { 2 | background: #1c1c1c; 3 | } 4 | body { 5 | padding-top: 60px; 6 | background: #ffffff url('/static/graphic/background.png') repeat-x; 7 | } 8 | @media (max-width: 979px) { 9 | body { 10 | padding-top: 0px; 11 | padding-bottom: 0px; 12 | } 13 | } 14 | footer { 15 | background: #292727; 16 | margin: 40px 0 0; 17 | padding: 20px 0 15px; 18 | width: 100%; 19 | color: #ccc; 20 | } 21 | footer a:link, footer a:visited { 22 | color: #ccc; 23 | text-decoration: none; 24 | } 25 | footer a:hover { 26 | color: #ccc; 27 | text-decoration: underline; 28 | } 29 | #footer-extra { 30 | background: #1c1c1c; 31 | padding: 10px 0; 32 | font-size: 11px; 33 | color: #999; 34 | } 35 | #footer-extra a:link, #footer-extra a:visited { 36 | color: #999; 37 | font-weight: bold; 38 | text-decoration: none; 39 | } 40 | #footer-extra a:hover { 41 | color: #ccc; 42 | text-decoration: underline; 43 | } 44 | .center { 45 | text-align: center; 46 | } 47 | .mono { 48 | font-family: monospace; 49 | } 50 | .content { 51 | background-color: white; 52 | padding: 40px; 53 | padding-top: 15px; 54 | -moz-border-radius-bottomleft: 15px; 55 | -moz-border-radius-bottomright: 15px; 56 | -webkit-border-bottom-left-radius: 15px; 57 | -webkit-border-bottom-right-radius: 15px; 58 | } 59 | .section-title { 60 | border-bottom: 1px solid #eee; 61 | margin-bottom: 15px; 62 | margin-top: 20px; 63 | padding-bottom: 3px; 64 | } 65 | span.block-title { 66 | font-size: 18px; 67 | font-weight: bold; 68 | } 69 | img.opaque { 70 | opacity: 0.3; 71 | filter: alpha(opacity=30); 72 | } 73 | img.opaque:hover { 74 | opacity: 1.0; 75 | filter: alpha(opacity=100); 76 | } 77 | .gray { 78 | color: #666; 79 | } 80 | .table-centered { 81 | margin: 0 auto !important; 82 | float: none !important; 83 | } 84 | a.tag-label { 85 | color: white; 86 | } 87 | 88 | .filesystem { 89 | background-color: #ffe3c5; 90 | } 91 | .registry { 92 | background-color: #ffc5c5; 93 | } 94 | .process { 95 | background-color: #c5e0ff; 96 | } 97 | .services { 98 | background-color: #ccc5ff; 99 | } 100 | .device { 101 | background-color: #ccc5ff; 102 | } 103 | .network { 104 | background-color: #d3ffc5; 105 | } 106 | .socket { 107 | background-color: #d3ffc5; 108 | } 109 | .synchronization { 110 | background-color: #f9c5ff; 111 | } 112 | 113 | .page-header { 114 | margin-bottom: 10px; 115 | } 116 | 117 | /* Fix the icon tab override */ 118 | .nav-tabs > .active > a > [class^="icon-"],.nav-tabs>.active>a>[class*=" icon-"] { background-image:url("../img/glyphicons-halflings.png") !important; } 119 | 120 | td { 121 | word-wrap: break-word; 122 | } 123 | 124 | .tab-content { 125 | margin-top: 25px; 126 | } -------------------------------------------------------------------------------- /web/static/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djteller/MemoryAnalysis/13554135ec4614e1fa2a051c1ba76525a92eac1a/web/static/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /web/static/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djteller/MemoryAnalysis/13554135ec4614e1fa2a051c1ba76525a92eac1a/web/static/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /web/static/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djteller/MemoryAnalysis/13554135ec4614e1fa2a051c1ba76525a92eac1a/web/static/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /web/static/graphic/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djteller/MemoryAnalysis/13554135ec4614e1fa2a051c1ba76525a92eac1a/web/static/graphic/background.png -------------------------------------------------------------------------------- /web/static/graphic/cuckoo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djteller/MemoryAnalysis/13554135ec4614e1fa2a051c1ba76525a92eac1a/web/static/graphic/cuckoo.png -------------------------------------------------------------------------------- /web/static/img/close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djteller/MemoryAnalysis/13554135ec4614e1fa2a051c1ba76525a92eac1a/web/static/img/close.png -------------------------------------------------------------------------------- /web/static/img/loading.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djteller/MemoryAnalysis/13554135ec4614e1fa2a051c1ba76525a92eac1a/web/static/img/loading.gif -------------------------------------------------------------------------------- /web/static/img/next.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djteller/MemoryAnalysis/13554135ec4614e1fa2a051c1ba76525a92eac1a/web/static/img/next.png -------------------------------------------------------------------------------- /web/static/img/prev.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djteller/MemoryAnalysis/13554135ec4614e1fa2a051c1ba76525a92eac1a/web/static/img/prev.png -------------------------------------------------------------------------------- /web/submission/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2010-2014 Cuckoo Sandbox Developers. 2 | # This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org 3 | # See the file 'docs/LICENSE' for copying permission. -------------------------------------------------------------------------------- /web/submission/urls.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2010-2014 Cuckoo Sandbox Developers. 2 | # This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org 3 | # See the file 'docs/LICENSE' for copying permission. 4 | 5 | from django.conf.urls import patterns, url 6 | 7 | urlpatterns = patterns("", 8 | url(r"^$", "submission.views.index"), 9 | ) 10 | -------------------------------------------------------------------------------- /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 | 16 | 17 | 22 | 29 | 30 | 40 | 41 | {% endfor %} 42 | 43 |
TimeAPIArgumentsStatusReturnRepeated
{{call.timestamp}}{{call.api}} 18 | {% for argument in call.arguments %} 19 | {{argument.name}}: {{argument.value}}
20 | {% endfor %} 21 |
23 | {% if call.status %} 24 | success 25 | {% else %} 26 | failed 27 | {% endif %} 28 | {{call.return}} 31 | {% if call.repeated > 0 %} 32 | {{call.repeated}} 33 | {% if call.repeated > 1 %} 34 | times 35 | {% else %} 36 | time 37 | {% endif %} 38 | {% endif %} 39 |
44 | -------------------------------------------------------------------------------- /web/templates/analysis/behavior/_tree.html: -------------------------------------------------------------------------------- 1 |
    2 | {% for process in analysis.behavior.processtree %} 3 | {% include "analysis/behavior/_tree_process.html" %} 4 | {% endfor %} 5 |
6 | -------------------------------------------------------------------------------- /web/templates/analysis/behavior/_tree_process.html: -------------------------------------------------------------------------------- 1 |
  • 2 | {{process.name}} {{process.pid}} 3 | {% if process.children %} 4 |
      5 | {% for child in process.children %} 6 | {% with process=child template_name="analysis/behavior/_tree_process.html" %} 7 | {% include template_name %} 8 | {% endwith %} 9 | {% endfor %} 10 |
    11 | {% endif %} 12 |
  • 13 | -------------------------------------------------------------------------------- /web/templates/analysis/behavior/index.html: -------------------------------------------------------------------------------- 1 | {% include "analysis/behavior/_tree.html" %} 2 | {% include "analysis/behavior/_processes.html" %} -------------------------------------------------------------------------------- /web/templates/analysis/dropped/index.html: -------------------------------------------------------------------------------- 1 | {% if analysis.dropped|length > 0 %} 2 | {% for file in analysis.dropped %} 3 |
    4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 13 | 14 | 15 | 17 | 18 | 19 | 21 | 22 | 23 | 25 | 26 | 27 | 29 | 30 | 31 | 33 | 34 | 35 | 37 | 38 | 39 | 50 | 51 | {% if file.object_id %} 52 | 53 | 54 | 55 | 56 | {% endif %} 57 |
    File name{{file.name}}
    File Size{{file.size}} bytes 12 |
    File Type{{file.type}} 16 |
    MD5{{file.md5}} 20 |
    SHA1{{file.sha1}} 24 |
    SHA256{{file.sha256}} 28 |
    CRC32{{file.crc32}} 32 |
    Ssdeep{{file.ssdeep}} 36 |
    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 |
    Download
    58 |
    59 | {% endfor %} 60 | {% else %} 61 |
    Sorry! No dropped files.
    62 | {% endif %} -------------------------------------------------------------------------------- /web/templates/analysis/memory/_malfind.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | {% for mal in analysis.memory.malfind.data %} 12 | 13 | 14 | 15 | 16 | 17 | 18 | {% endfor %} 19 | 20 |
    PIDProcess NameStartTag
    {{mal.process_id}}{{mal.process_name}}{{mal.vad_start}}{{mal.vad_tag}}
    21 | -------------------------------------------------------------------------------- /web/templates/analysis/memory/_modscan.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | {% for mod in analysis.memory.modscan.data %} 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | {% endfor %} 21 | 22 |
    Base AddressOffsetNameFileSize
    {{mod.kernel_module_base}}{{mod.kernel_module_offset}}{{mod.kernel_module_name}}{{mod.kernel_module_file}}{{mod.kernel_module_size}}
    23 | -------------------------------------------------------------------------------- /web/templates/analysis/memory/_pslist.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | {% for process in analysis.memory.pslist.data %} 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | {% endfor %} 27 | 28 |
    Parent PIDPIDNameCreate TimeExit Time# Threads# HandlesSession ID
    {{process.parent_id}}{{process.process_id}}{{process.process_name}}{{process.create_time}}{{process.exit_time}}{{process.num_threads}}{{process.num_handles}}{{process.session_id}}
    29 | -------------------------------------------------------------------------------- /web/templates/analysis/memory/_svcscan.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | {% for service in analysis.memory.svcscan.data %} 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | {% endfor %} 27 | 28 |
    NameDisplay NameBinary PathPIDTypeOrderOffsetState
    {{service.service_name}}{{service.service_display_name}}{{service.service_binary_path}}{{service.pricess_id}}{{service.service_type}}{{service.service_order}}{{service.service_offset}}{{service.service_state}}
    29 | -------------------------------------------------------------------------------- /web/templates/analysis/memory/index.html: -------------------------------------------------------------------------------- 1 |
    2 | 8 |
    9 |
    10 | {% include "analysis/memory/_pslist.html" %} 11 |
    12 |
    13 | {% include "analysis/memory/_svcscan.html" %} 14 |
    15 |
    16 | {% include "analysis/memory/_modscan.html" %} 17 |
    18 |
    19 | {% include "analysis/memory/_malfind.html" %} 20 |
    21 |
    22 |
    -------------------------------------------------------------------------------- /web/templates/analysis/network/_dns.html: -------------------------------------------------------------------------------- 1 |
    2 |

    Domains

    3 | {% if analysis.network.domains %} 4 | 5 | 6 | 7 | 8 | 9 | {% for domain in analysis.network.domains %} 10 | 11 | 12 | 13 | 14 | {% endfor %} 15 |
    DomainIP
    {{domain.domain}}{{domain.ip}}
    16 | {% else %} 17 |

    No domains contacted.

    18 | {% endif %} 19 |
    20 | -------------------------------------------------------------------------------- /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" %} 11 | 12 | {% endif %} 13 | 14 | {% endfor %} 15 |
    IP
    {{host}}
    16 | {% else %} 17 |

    No hosts contacted.

    18 | {% endif %} 19 |
    20 | -------------------------------------------------------------------------------- /web/templates/analysis/network/_http.html: -------------------------------------------------------------------------------- 1 |

    HTTP Requests

    2 | {% if analysis.network.http %} 3 | 4 | 5 | 6 | 7 | 8 | {% for request in analysis.network.http %} 9 | 10 | 11 | 12 | 13 | {% endfor %} 14 |
    URIData
    {{request.uri}}
    {{request.data}}
    15 | {% else %} 16 |

    No HTTP requests performed.

    17 | {% endif %} -------------------------------------------------------------------------------- /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 %} -------------------------------------------------------------------------------- /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/network/index.html: -------------------------------------------------------------------------------- 1 | {% if analysis.network.pcap_id %} 2 | 3 | {% endif %} 4 |
    5 | 12 |
    13 |
    {% include "analysis/network/_hosts.html" %}
    14 |
    {% include "analysis/network/_dns.html" %}
    15 |
    {% include "analysis/network/_http.html" %}
    16 |
    {% include "analysis/network/_icmp.html" %}
    17 |
    {% include "analysis/network/_irc.html" %}
    18 |
    19 |
    20 | -------------------------------------------------------------------------------- /web/templates/analysis/overview/_file.html: -------------------------------------------------------------------------------- 1 |
    2 |

    File Details

    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 | 40 | 41 | 42 | 43 | 54 | 55 | 56 | 57 | 58 | 59 |
    File Name{{analysis.target.file.name}}
    File Size{{analysis.target.file.size}} bytes
    File Type{{analysis.target.file.type}}
    MD5{{analysis.target.file.md5}}
    SHA1{{analysis.target.file.sha1}}
    SHA256{{analysis.target.file.sha256}}
    SHA512{{analysis.target.file.sha512}}
    CRC32{{analysis.target.file.crc32}}
    Ssdeep{{analysis.target.file.ssdeep}}
    Yara 44 | {% if analysis.target.file.yara %} 45 |
      46 | {% for sign in analysis.target.file.yara %} 47 |
    • {{sign.name}} - {{sign.meta.description}}
    • 48 | {% endfor %} 49 |
    50 | {% else %} 51 | None matched 52 | {% endif %} 53 |
    Download
    60 |
    61 |
    -------------------------------------------------------------------------------- /web/templates/analysis/overview/_info.html: -------------------------------------------------------------------------------- 1 |
    2 |
    3 |
    4 |

    Analysis

    5 |
    6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 |
    CategoryStartedCompletedDuration
    {{analysis.info.category|upper}}{{analysis.info.started}}{{analysis.info.ended}}{{analysis.info.duration}} seconds
    24 |
    25 | 26 | {% if analysis.debug.errors %} 27 |
      28 | {% for error in analysis.debug.errors %} 29 |
    • Error: {{error}}
    • 30 | {% endfor %} 31 |
    32 | {% endif %} 33 |
    -------------------------------------------------------------------------------- /web/templates/analysis/overview/_screenshots.html: -------------------------------------------------------------------------------- 1 |
    2 |

    Screenshots

    3 | {% if analysis.shots %} 4 |
    5 | {% for shot in analysis.shots %} 6 | 7 | {% endfor %} 8 |
    9 | {% else %} 10 | No screenshots available. 11 | {% endif %} 12 |
    -------------------------------------------------------------------------------- /web/templates/analysis/overview/_signatures.html: -------------------------------------------------------------------------------- 1 | 8 |
    9 |

    Signatures

    10 | {% if analysis.signatures %} 11 | {% for signature in analysis.signatures %} 12 | 13 | {% if signature.severity <= 1 %} 14 |
    15 | {% elif signature.severity == 2 %} 16 |
    17 | {% elif signature.severity >= 3 %} 18 |
    19 | {% endif %} 20 | {{signature.description}}
    21 |
    22 | {% for sign in signature.data %} 23 | {% for key, value in sign.items %} 24 |
    {{key}}: {{value}}
    25 | {% endfor %} 26 | {% endfor %} 27 |
    28 | {% endfor %} 29 | {% else %} 30 |

    No signatures

    31 | {% endif %} 32 |
    -------------------------------------------------------------------------------- /web/templates/analysis/overview/_summary.html: -------------------------------------------------------------------------------- 1 |
    2 |

    Summary

    3 |
    4 | 9 |
    10 |
    11 |
    12 | {% if analysis.behavior.summary.files %} 13 | {% for file in analysis.behavior.summary.files %} 14 | {{file}}
    15 | {% endfor %} 16 | {% endif %} 17 |
    18 |
    19 |
    20 |
    21 | {% if analysis.behavior.summary.keys %} 22 | {% for key in analysis.behavior.summary.keys %} 23 | {{key}}
    24 | {% endfor %} 25 | {% endif %} 26 |
    27 |
    28 |
    29 |
    30 | {% if analysis.behavior.summary.mutexes %} 31 | {% for mutex in analysis.behavior.summary.mutexes %} 32 | {{mutex}}
    33 | {% endfor %} 34 | {% endif %} 35 |
    36 |
    37 |
    38 |
    39 |
    40 | -------------------------------------------------------------------------------- /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 |
    -------------------------------------------------------------------------------- /web/templates/analysis/overview/index.html: -------------------------------------------------------------------------------- 1 | {% include "analysis/overview/_info.html" %} 2 |
    3 | {% if analysis.info.category == "file" %} 4 | {% include "analysis/overview/_file.html" %} 5 | {% elif analysis.info.category == "url" %} 6 | {% include "analysis/overview/_url.html" %} 7 | {% endif %} 8 |
    9 | {% include "analysis/overview/_signatures.html" %} 10 |
    11 | {% include "analysis/overview/_screenshots.html" %} 12 |
    13 |
    14 |
    {% include "analysis/network/_hosts.html" %}
    15 |
    {% include "analysis/network/_dns.html" %}
    16 |
    17 |
    18 | {% include "analysis/overview/_summary.html" %} 19 | -------------------------------------------------------------------------------- /web/templates/analysis/pending.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | {% block content %} 3 |

    4 | 5 |
    6 |
    7 |

    Pending Tasks

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

    4 | 12 |
    13 |
    14 | {% include "analysis/overview/index.html" %} 15 |
    16 |
    17 | {% include "analysis/static/index.html" %} 18 |
    19 | {% if analysis.behavior.processes %} 20 |
    21 | {% include "analysis/behavior/index.html" %} 22 |
    23 | {% endif %} 24 |
    25 | {% include "analysis/network/index.html" %} 26 |
    27 |
    28 | {% include "analysis/dropped/index.html" %} 29 |
    30 | {% if analysis.memory %} 31 |
    32 | {% include "analysis/memory/index.html" %} 33 |
    34 | {% endif %} 35 |
    36 | {% endblock %} 37 | -------------------------------------------------------------------------------- /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 | No antivirus signatures available. 37 | {% endif %} 38 |
    39 | -------------------------------------------------------------------------------- /web/templates/analysis/static/_strings.html: -------------------------------------------------------------------------------- 1 |
    2 |
    3 | {% for string in analysis.strings %} 4 |
    {{string}}
    5 | {% endfor %} 6 |
    7 |
    -------------------------------------------------------------------------------- /web/templates/analysis/static/index.html: -------------------------------------------------------------------------------- 1 |
    2 | 7 |
    8 |
    9 | {% if "PE32" in analysis.target.file.type %} 10 | {% include "analysis/static/_pe32.html" %} 11 | {% else %} 12 | No static analysis available. 13 | {% endif %} 14 |
    15 |
    16 | {% include "analysis/static/_strings.html" %} 17 |
    18 |
    19 | {% include "analysis/static/_antivirus.html" %} 20 |
    21 |
    22 |
    -------------------------------------------------------------------------------- /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/dashboard/index.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | {% block content %} 3 |

    4 | 5 |
    6 | Estimating {{report.estimate_hour}} analysis per hour, {{report.estimate_day}} per day. 7 |
    8 | 9 |
    10 |
    11 |
    12 |

    {{report.total_tasks}}

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

    {{report.total_samples}}

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

    States

    27 |
    28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | {% for state, count in report.states_count.items %} 37 | 38 | 39 | 40 | 41 | {% endfor %} 42 | 43 |
    StateCount
    {{state}}{{count}}
    44 |
    45 | {% endblock %} 46 | -------------------------------------------------------------------------------- /web/templates/error.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | {% block content %} 3 |

    4 |
    ERROR :-(
    {{error}}
    5 | {% endblock %} -------------------------------------------------------------------------------- /web/templates/footer.html: -------------------------------------------------------------------------------- 1 | 3 | 8 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /web/templates/header.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Cuckoo Sandbox 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
    19 | 38 |
    39 | -------------------------------------------------------------------------------- /web/templates/success.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | {% block content %} 3 |

    4 |
    Great! :-)
    {{message}}
    5 | {% endblock %} -------------------------------------------------------------------------------- /web/web/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2010-2014 Cuckoo Sandbox Developers. 2 | # This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org 3 | # See the file 'docs/LICENSE' for copying permission. 4 | 5 | import sys 6 | import os 7 | from django.conf import settings 8 | 9 | sys.path.append(settings.CUCKOO_PATH) 10 | 11 | from lib.cuckoo.common.constants import CUCKOO_ROOT 12 | from lib.cuckoo.common.config import Config 13 | 14 | cfg = Config(cfg=os.path.join(CUCKOO_ROOT, "conf", "reporting.conf")).mongodb 15 | 16 | # Checks if mongo reporting is enabled in Cuckoo. 17 | if not cfg.get("enabled"): 18 | raise Exception("Mongo reporting module is not enabled in cuckoo, aborting!") 19 | 20 | # Get connection options from reporting.conf. 21 | settings.MONGO_HOST = cfg.get("host", "127.0.0.1") 22 | settings.MONGO_PORT = cfg.get("port", 27017) -------------------------------------------------------------------------------- /web/web/headers.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2010-2014 Cuckoo Sandbox Developers. 2 | # This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org 3 | # See the file 'docs/LICENSE' for copying permission. 4 | 5 | import sys 6 | 7 | from django.conf import settings 8 | 9 | sys.path.append(settings.CUCKOO_PATH) 10 | 11 | from lib.cuckoo.common.constants import CUCKOO_VERSION 12 | 13 | class CuckooHeaders(object): 14 | """Set Cuckoo custom response headers.""" 15 | 16 | def process_response(self, request, response): 17 | response["Server"] = "Machete Server" 18 | response["X-Cuckoo-Version"] = CUCKOO_VERSION 19 | response["X-Content-Type-Options"] = "nosniff" 20 | response["X-Frame-Options"] = "DENY" 21 | response["X-XSS-Protection"] = "1; mode=block" 22 | response["Pragma"] = "no-cache" 23 | response["Cache-Control"] = "no-cache" 24 | response["Expires"] = "0" 25 | 26 | return response -------------------------------------------------------------------------------- /web/web/local_settings.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2010-2014 Cuckoo Sandbox Developers. 2 | # This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org 3 | # See the file 'docs/LICENSE' for copying permission. 4 | 5 | LOCAL_SETTINGS = True 6 | from settings import * 7 | 8 | # If you want to customize your cuckoo path set it here. 9 | # CUCKOO_PATH = "/where/cuckoo/is/placed/" 10 | 11 | # If you want to customize your cuckoo temporary upload path set it here. 12 | # CUCKOO_FILE_UPLOAD_TEMP_DIR = "/where/web/tmp/is/placed/" 13 | 14 | # Maximum upload size. 15 | MAX_UPLOAD_SIZE = 26214400 16 | 17 | # Override default secret key stored in secret_key.py 18 | # Make this unique, and don't share it with anybody. 19 | # SECRET_KEY = "YOUR_RANDOM_KEY" 20 | 21 | # Language code for this installation. All choices can be found here: 22 | # http://www.i18nguy.com/unicode/language-identifiers.html 23 | LANGUAGE_CODE = "en-us" 24 | 25 | ADMINS = ( 26 | # ("Your Name", "your_email@example.com"), 27 | ) 28 | 29 | MANAGERS = ADMINS 30 | 31 | # Allow verbose debug error message in case of application fault. 32 | # It's strongly suggested to set it to False if you are serving the 33 | # web application from a web server front-end (i.e. Apache). 34 | DEBUG = True 35 | 36 | # A list of strings representing the host/domain names that this Django site 37 | # can serve. 38 | # Values in this list can be fully qualified names (e.g. 'www.example.com'). 39 | # When DEBUG is True or when running tests, host validation is disabled; any 40 | # host will be accepted. Thus it's usually only necessary to set it in production. 41 | ALLOWED_HOSTS = ["*"] -------------------------------------------------------------------------------- /web/web/upload.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2010-2014 Cuckoo Sandbox Developers. 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 | 7 | from tempfile import mkdtemp 8 | from django.conf import settings 9 | from django.core.files.uploadedfile import TemporaryUploadedFile 10 | from django.core.files.uploadhandler import TemporaryFileUploadHandler 11 | 12 | class CuckooTemporaryUploadedFile(TemporaryUploadedFile): 13 | """Custom uploader to preserve file names. 14 | It creates a tmp directory with a random name and inside the original file is placed. 15 | """ 16 | 17 | def __init__(self, name, content_type, size, charset): 18 | path = settings.CUCKOO_FILE_UPLOAD_TEMP_DIR[0] 19 | if path: 20 | # Create temp directory if not exists. 21 | if not os.path.exists(path): 22 | os.mkdir(path) 23 | 24 | # Temp file handler. 25 | file = os.path.join(mkdtemp(dir=path), name) 26 | super(TemporaryUploadedFile, self).__init__(open(file, "wb"), name, content_type, size, charset) 27 | else: 28 | raise Exception("Missing CUCKOO_FILE_UPLOAD_TEMP_DIR in settings.py") 29 | 30 | class CuckooTemporaryFileUploadHandler(TemporaryFileUploadHandler): 31 | """Custom uploder to use CuckooTemporaryUploadedFile.""" 32 | 33 | def new_file(self, file_name, *args, **kwargs): 34 | super(CuckooTemporaryFileUploadHandler, self).new_file(file_name, *args, **kwargs) 35 | self.file = CuckooTemporaryUploadedFile(self.file_name, self.content_type, 0, self.charset) -------------------------------------------------------------------------------- /web/web/urls.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2010-2014 Cuckoo Sandbox Developers. 2 | # This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org 3 | # See the file 'docs/LICENSE' for copying permission. 4 | 5 | from django.conf.urls import patterns, include, url 6 | 7 | urlpatterns = patterns("", 8 | url(r"^$", "dashboard.views.index"), 9 | url(r"^analysis/", include("analysis.urls")), 10 | url(r"^submit/", include("submission.urls")), 11 | url(r"^file/(?P\w+)/(?P\w+)/$", "analysis.views.file"), 12 | url(r"^dashboard/", include("dashboard.urls")), 13 | ) -------------------------------------------------------------------------------- /web/web/wsgi.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2010-2014 Cuckoo Sandbox Developers. 2 | # This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org 3 | # See the file 'docs/LICENSE' for copying permission. 4 | 5 | """ 6 | WSGI config for web project. 7 | 8 | This module contains the WSGI application used by Django's development server 9 | and any production WSGI deployments. It should expose a module-level variable 10 | named ``application``. Django's ``runserver`` and ``runfcgi`` commands discover 11 | this application via the ``WSGI_APPLICATION`` setting. 12 | 13 | Usually you will have the standard Django WSGI application here, but it also 14 | might make sense to replace the whole Django WSGI application with a custom one 15 | that later delegates to the Django one. For example, you could introduce WSGI 16 | middleware here, or combine a Django application with an application of another 17 | framework. 18 | 19 | """ 20 | import os 21 | 22 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "web.settings") 23 | 24 | # This application object is used by any WSGI server configured to use this 25 | # file. This includes Django's development server, if the WSGI_APPLICATION 26 | # setting points here. 27 | from django.core.wsgi import get_wsgi_application 28 | application = get_wsgi_application() 29 | 30 | # Apply WSGI middleware here. 31 | # from helloworld.wsgi import HelloWorldApplication 32 | # application = HelloWorldApplication(application) 33 | --------------------------------------------------------------------------------