def test_tmp_permissions_false(): set_cwd(tempfile.mkdtemp()) dirpath = tempfile.mkdtemp() cuckoo_create(cfg={"cuckoo": { "cuckoo": { "tmppath": dirpath, } }}) os.chmod(dirpath, 0400) assert not ensure_tmpdir()
def test_tmp_permissions_false(): set_cwd(tempfile.mkdtemp()) dirpath = tempfile.mkdtemp() cuckoo_create(cfg={ "cuckoo": { "cuckoo": { "tmppath": dirpath, } } }) os.chmod(dirpath, 0400) assert not ensure_tmpdir()
def api(ctx, host, port, uwsgi, nginx): """Operate the Cuckoo REST API.""" username = ctx.parent.user or getuser() if uwsgi: print "[uwsgi]" print "plugins = python" if os.environ.get("VIRTUAL_ENV"): print "virtualenv =", os.environ["VIRTUAL_ENV"] print "module = cuckoo.apps.api" print "callable = app" print "uid =", username print "gid =", username print "env = CUCKOO_APP=api" print "env = CUCKOO_CWD=%s" % cwd() return if nginx: print "upstream _uwsgi_cuckoo_api {" print " server unix:/run/uwsgi/app/cuckoo-api/socket;" print "}" print print "server {" print " listen %s:%d;" % (host, port) print print " # REST API app" print " location / {" print " client_max_body_size 1G;" print " uwsgi_pass _uwsgi_cuckoo_api;" print " include uwsgi_params;" print " }" print "}" return init_console_logging(level=ctx.parent.level) Database().connect() if not ensure_tmpdir(): sys.exit(1) cuckoo_api(host, port, ctx.parent.level == logging.DEBUG)
def cuckoo_init(level, ctx, cfg=None): """Initialize Cuckoo configuration. @param quiet: enable quiet mode. """ logo() # It would appear this is the first time Cuckoo is being run (on this # Cuckoo Working Directory anyway). if not os.path.isdir(cwd()) or not os.listdir(cwd()): cuckoo_create(ctx.user, cfg) sys.exit(0) # Determine if this is a proper CWD. if not os.path.exists(cwd(".cwd")): sys.exit( "No proper Cuckoo Working Directory was identified, did you pass " "along the correct directory? For new installations please use a " "non-existant directory to build up the CWD! You can craft a CWD " "manually, but keep in mind that the CWD layout may change along " "with Cuckoo releases (and don't forget to fill out '$CWD/.cwd')!") init_console_logging(level) # Only one Cuckoo process should exist per CWD. Run this check before any # files are possibly modified. Note that we mkdir $CWD/pidfiles/ here as # its CWD migration rules only kick in after the pidfile check. mkdir(cwd("pidfiles")) pidfile = Pidfile("cuckoo") if pidfile.exists(): log.error(red("Cuckoo is already running. PID: %s"), pidfile.pid) sys.exit(1) pidfile.create() check_configs() check_version() ctx.log and init_logging(level) # Determine if any CWD updates are required and if so, do them. current = open(cwd(".cwd"), "rb").read().strip() latest = open(cwd(".cwd", private=True), "rb").read().strip() if current != latest: migrate_cwd() open(cwd(".cwd"), "wb").write(latest) # Ensure the user is able to create and read temporary files. if not ensure_tmpdir(): sys.exit(1) Database().connect() # Load additional Signatures. load_signatures() init_modules() init_tasks() init_yara() init_binaries() init_rooter() init_routing() signatures = 0 for sig in cuckoo.signatures: if not sig.enabled: continue signatures += 1 if not signatures: log.warning( "It appears that you haven't loaded any Cuckoo Signatures. " "Signatures are highly recommended and improve & enrich the " "information extracted during an analysis. They also make up " "for the analysis score that you see in the Web Interface - so, " "pretty important!") log.warning( "You'll be able to fetch all the latest Cuckoo Signaturs, Yara " "rules, and more goodies by running the following command:") log.info("$ %s", green(format_command("community")))
def cuckoo_init(level, ctx, cfg=None): """Initialize Cuckoo configuration. @param quiet: enable quiet mode. """ logo() # It would appear this is the first time Cuckoo is being run (on this # Cuckoo Working Directory anyway). if not os.path.isdir(cwd()) or not os.listdir(cwd()): cuckoo_create(ctx.user, cfg) sys.exit(0) # Determine if this is a proper CWD. if not os.path.exists(cwd(".cwd")): sys.exit( "No proper Cuckoo Working Directory was identified, did you pass " "along the correct directory? For new installations please use a " "non-existant directory to build up the CWD! You can craft a CWD " "manually, but keep in mind that the CWD layout may change along " "with Cuckoo releases (and don't forget to fill out '$CWD/.cwd')!" ) init_console_logging(level) # Only one Cuckoo process should exist per CWD. Run this check before any # files are possibly modified. Note that we mkdir $CWD/pidfiles/ here as # its CWD migration rules only kick in after the pidfile check. mkdir(cwd("pidfiles")) pidfile = Pidfile("cuckoo") if pidfile.exists(): log.error(red("Cuckoo is already running. PID: %s"), pidfile.pid) sys.exit(1) pidfile.create() check_configs() check_version() ctx.log and init_logging(level) # Determine if any CWD updates are required and if so, do them. current = open(cwd(".cwd"), "rb").read().strip() latest = open(cwd(".cwd", private=True), "rb").read().strip() if current != latest: migrate_cwd() open(cwd(".cwd"), "wb").write(latest) # Ensure the user is able to create and read temporary files. if not ensure_tmpdir(): sys.exit(1) Database().connect() # Load additional Signatures. load_signatures() init_modules() init_tasks() init_yara() init_binaries() init_rooter() init_routing() signatures = 0 for sig in cuckoo.signatures: if not sig.enabled: continue signatures += 1 if not signatures: log.warning( "It appears that you haven't loaded any Cuckoo Signatures. " "Signatures are highly recommended and improve & enrich the " "information extracted during an analysis. They also make up " "for the analysis score that you see in the Web Interface - so, " "pretty important!" ) log.warning( "You'll be able to fetch all the latest Cuckoo Signaturs, Yara " "rules, and more goodies by running the following command:" ) log.info("$ %s", green(format_command("community")))
def api_auth_required(error): return json_error( 401, "Authentication in the form of an " "'Authorization: Bearer <TOKEN>' header is required" ) @app.before_request def check_authentication(): token = config("cuckoo:cuckoo:api_token") if token: expect = "Bearer " + token auth = request.headers.get("Authorization") if not constant_time_compare(auth, expect): abort(401) def cuckoo_api(hostname, port, debug): if not config("cuckoo:cuckoo:api_token"): log.warning( "It is strongly recommended to enable API authentication to " "protect against unauthorized access and CSRF attacks." ) log.warning("Please check the API documentation for more information.") app.run(host=hostname, port=port, debug=debug) if os.environ.get("CUCKOO_APP") == "api": from cuckoo.core.startup import ensure_tmpdir, init_console_logging decide_cwd(exists=True) Database().connect() init_console_logging() ensure_tmpdir()
def web(ctx, args, host, port, uwsgi, nginx): """Operate the Cuckoo Web Interface. Use "--help" to get this help message and "help" to find Django's manage.py potential subcommands. """ username = ctx.parent.user or getuser() if uwsgi: print "[uwsgi]" print "plugins = python" if os.environ.get("VIRTUAL_ENV"): print "virtualenv =", os.environ["VIRTUAL_ENV"] print "module = cuckoo.web.web.wsgi" print "uid =", username print "gid =", username dirpath = os.path.join(cuckoo.__path__[0], "web", "static") print "static-map = /static=%s" % dirpath print "# If you're getting errors about the PYTHON_EGG_CACHE, then" print "# uncomment the following line and add some path that is" print "# writable from the defined user." print "# env = PYTHON_EGG_CACHE=" print "env = CUCKOO_APP=web" print "env = CUCKOO_CWD=%s" % cwd() return if nginx: print "upstream _uwsgi_cuckoo_web {" print " server unix:/run/uwsgi/app/cuckoo-web/socket;" print "}" print print "server {" print " listen %s:%d;" % (host, port) print print " # Cuckoo Web Interface" print " location / {" print " client_max_body_size 1G;" print " proxy_redirect off;" print " proxy_set_header X-Forwarded-Proto $scheme;" print " uwsgi_pass _uwsgi_cuckoo_web;" print " include uwsgi_params;" print " }" print "}" return # Switch to cuckoo/web and add the current path to sys.path as the Web # Interface is using local imports here and there. # TODO Rename local imports to either cuckoo.web.* or relative imports. sys.argv[0] = os.path.abspath(sys.argv[0]) os.chdir(os.path.join(cuckoo.__path__[0], "web")) sys.path.insert(0, ".") os.environ.setdefault("DJANGO_SETTINGS_MODULE", "cuckoo.web.web.settings") # The Django HTTP server also imports the WSGI module for some reason, so # ensure that WSGI is able to load. os.environ["CUCKOO_APP"] = "web" os.environ["CUCKOO_CWD"] = cwd() from django.core.management import execute_from_command_line init_console_logging(level=ctx.parent.level) Database().connect() if not ensure_tmpdir(): sys.exit(1) try: execute_from_command_line( ("cuckoo", "runserver", "%s:%d" % (host, port)) if not args else ("cuckoo",) + args ) except CuckooCriticalError as e: message = red("{0}: {1}".format(e.__class__.__name__, e)) if len(log.handlers): log.critical(message) else: sys.stderr.write("{0}\n".format(message)) sys.exit(1)