Skip to content
This repository has been archived by the owner on Jun 7, 2023. It is now read-only.

Commit

Permalink
add DjangoWhiteNoise for serving static files in non debug mode
Browse files Browse the repository at this point in the history
  • Loading branch information
frennkie committed Feb 6, 2018
1 parent c2b1c0d commit dc221e1
Show file tree
Hide file tree
Showing 16 changed files with 210 additions and 50 deletions.
1 change: 1 addition & 0 deletions MANIFEST.in
Expand Up @@ -5,6 +5,7 @@ include CHANGELOG
include requirements.txt
include requirements-*.txt
include viper.conf.sample
include settings_local.py.sample
recursive-include data/peid/ *.*
recursive-include data/yara/ *.*
recursive-include data/web/ *.*
Expand Down
93 changes: 87 additions & 6 deletions docs/source/known_issues/index.rst
Expand Up @@ -17,7 +17,7 @@ Problem importing certain modules
=================================

If you experience an issue like::

[!] Something wrong happened while importing the module modules.office: No module named oletools.olevba

You are likely missing dependencies.
Expand All @@ -38,7 +38,7 @@ update.py from 1.1 to 1.2 IOError 'data/web/'

If you are running a Viper version 1.1 und using update.py to update to 1.2 you might run into some error like::

python update.py
python update.py
[!] WARNING: If you proceed you will lose any changes you might have made to Viper.
Are you sure you want to proceed? [y/N] y
Traceback (most recent call last):
Expand All @@ -47,7 +47,7 @@ If you are running a Viper version 1.1 und using update.py to update to 1.2 you
File "update.py", line 66, in main
new_local = open(local_file_path, 'w')
IOError: [Errno 2] No such file or directory: 'data/web/'

That issue is known and already adressed in the new version of update.py (you might wanna pull that file manually

PreprocessError: data/yara/index.yara:0:Invalid file extension '.yara'.Can only include .yar
Expand All @@ -58,19 +58,100 @@ If you running yara or RAT module and receiving that issue::
...
PreprocessError: data/yara/index.yara:0:Invalid file extension '.yara'.Can only include .yar
...


It is most likely the versions of yara are not correct, try to run::

viper@viper:/home/viper# yara -version
yara 2.1

And check for the yara-python bindings::

viper@viper:/home/viper# pip freeze | grep yara
yara-python==2.1


If you have installed yara-python using pip it is likely you are running an older version of yara (see yara documentation for compiling howto)


Error Messages in log: ssl.SSLEOFError: EOF occurred in violation of protocol
=============================================================================

When running the built-in HTTPS server several error messages are logged, then the favicon is accessed.
This does no represent a problem and the favicon is loaded and display. So this is currently in status ``wontfix``.

Log::

2018-02-05 14:29:33 - django.server - INFO - basehttp.py:124 - "GET /favicon.ico HTTP/1.1" 301 0
Traceback (most recent call last):
File "/usr/lib/python3.4/wsgiref/handlers.py", line 138, in run
self.finish_response()
File "/usr/lib/python3.4/wsgiref/handlers.py", line 180, in finish_response
self.write(data)
File "/usr/lib/python3.4/wsgiref/handlers.py", line 279, in write
self._write(data)
File "/usr/lib/python3.4/wsgiref/handlers.py", line 453, in _write
self.stdout.write(data)
File "/usr/lib/python3.4/socket.py", line 394, in write
return self._sock.send(b)
File "/usr/lib/python3.4/ssl.py", line 702, in send
v = self._sslobj.write(data)
ssl.SSLEOFError: EOF occurred in violation of protocol (_ssl.c:1638)
2018-02-05 14:29:33 - django.server - ERROR - basehttp.py:124 - "GET /favicon.ico HTTP/1.1" 500 59
----------------------------------------
Exception happened during processing of request from ('192.168.92.66', 52014)
Traceback (most recent call last):
File "/usr/lib/python3.4/wsgiref/handlers.py", line 138, in run
self.finish_response()
File "/usr/lib/python3.4/wsgiref/handlers.py", line 180, in finish_response
self.write(data)
File "/usr/lib/python3.4/wsgiref/handlers.py", line 279, in write
self._write(data)
File "/usr/lib/python3.4/wsgiref/handlers.py", line 453, in _write
self.stdout.write(data)
File "/usr/lib/python3.4/socket.py", line 394, in write
return self._sock.send(b)
File "/usr/lib/python3.4/ssl.py", line 702, in send
v = self._sslobj.write(data)
ssl.SSLEOFError: EOF occurred in violation of protocol (_ssl.c:1638)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/usr/lib/python3.4/wsgiref/handlers.py", line 141, in run
self.handle_error()
File "/home/robbie/work/viper/venv/lib/python3.4/site-packages/django/core/servers/basehttp.py", line 86, in handle_error
super().handle_error()
File "/usr/lib/python3.4/wsgiref/handlers.py", line 368, in handle_error
self.finish_response()
File "/usr/lib/python3.4/wsgiref/handlers.py", line 180, in finish_response
self.write(data)
File "/usr/lib/python3.4/wsgiref/handlers.py", line 274, in write
self.send_headers()
File "/usr/lib/python3.4/wsgiref/handlers.py", line 331, in send_headers
if not self.origin_server or self.client_is_modern():
File "/usr/lib/python3.4/wsgiref/handlers.py", line 344, in client_is_modern
return self.environ['SERVER_PROTOCOL'].upper() != 'HTTP/0.9'
TypeError: 'NoneType' object is not subscriptable

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/usr/lib/python3.4/socketserver.py", line 305, in _handle_request_noblock
self.process_request(request, client_address)
File "/usr/lib/python3.4/socketserver.py", line 331, in process_request
self.finish_request(request, client_address)
File "/usr/lib/python3.4/socketserver.py", line 344, in finish_request
self.RequestHandlerClass(request, client_address, self)
File "/usr/lib/python3.4/socketserver.py", line 673, in __init__
self.handle()
File "/home/robbie/work/viper/venv/lib/python3.4/site-packages/django/core/servers/basehttp.py", line 154, in handle
handler.run(self.server.get_app())
File "/usr/lib/python3.4/wsgiref/handlers.py", line 144, in run
self.close()
File "/usr/lib/python3.4/wsgiref/simple_server.py", line 35, in close
self.status.split(' ',1)[0], self.bytes_sent
AttributeError: 'NoneType' object has no attribute 'split'
----------------------------------------
2018-02-05 14:29:33 - django.server - INFO - basehttp.py:124 - "GET /static/viperweb/images/favicon.png HTTP/1.1" 200 2041

13 changes: 13 additions & 0 deletions docs/source/usage/web.rst
Expand Up @@ -185,3 +185,16 @@ many generic descriptions how to run a Django application in e.g. Apache, Nginx

For Viper there is currently no finished step-by-step guide. Please feel free to send us a Pull
Request on Github.. :-D https://github.com/viper-framework/viper/pulls


FAQ
===

Q: What is the default username and password for the web interface?
A: The default Username is "admin" and the Password will be auto generated (or the value of ``admin_password`` in your ``viper.conf`` will be used)

Q: I didn't change (or write down) the auto generated password? How can I login?
A: The easiest way is to delete the Django database (``$storage_path/admin.db``) and restart ``viper-web``.

Q: Where can I find the API tokens?
A: You can view and edit tokens in the Django admin site: http://127.0.0.1:8080/admin/authtoken/token/
2 changes: 2 additions & 0 deletions requirements-web.txt
Expand Up @@ -2,10 +2,12 @@ Django
django-bootstrap-form
django-crispy-forms
django-extensions
django-favicon
django-filter
django-rest-swagger
django-sslserver
django-url-filter
djangorestframework
djangorestframework-queryfields
drf-nested-routers
whitenoise
8 changes: 8 additions & 0 deletions settings_local.py.sample
@@ -0,0 +1,8 @@
# -*- coding: utf-8 -*-
# This file is part of Viper - https://github.com/viper-framework/viper
# See the file 'LICENSE' for copying permission.
#
# settings_local.py

DEBUG = True
TIME_ZONE = 'Europe/Berlin'
2 changes: 1 addition & 1 deletion setup.cfg
Expand Up @@ -2,7 +2,7 @@
test=pytest

[tool:pytest]
addopts = -v --cov=viper --cov=web
addopts = -v --cov=viper
DJANGO_SETTINGS_MODULE = viper.web.settings

[bdist_wheel]
Expand Down
2 changes: 1 addition & 1 deletion tox.ini
Expand Up @@ -66,4 +66,4 @@ exclude =
.cache,
.eggs,
viper/modules/pymacho_helper,
viper/modules/pdftools,
viper/modules/pdftools
2 changes: 1 addition & 1 deletion viper-cli
Expand Up @@ -5,9 +5,9 @@

import argparse

from viper.core.ui import console
from viper.common.version import __version__
from viper.core.project import __project__
from viper.core.ui import console

parser = argparse.ArgumentParser()
parser.add_argument(
Expand Down
26 changes: 21 additions & 5 deletions viper-web
Expand Up @@ -21,6 +21,7 @@ os.environ.setdefault("DJANGO_SETTINGS_MODULE", "viper.web.settings")

import django # noqa
django.setup()
from django.conf import settings
from django.contrib.auth.models import User # noqa
from django.core.exceptions import ObjectDoesNotExist # noqa
from django.core.management import execute_from_command_line # noqa
Expand Down Expand Up @@ -126,13 +127,28 @@ if __name__ == '__main__':
Token.objects.create(user=admin)
# print_success("Created new API Auth Token for \"{}\": {}".format(admin_username, admin.auth_token.key))

# setup static files (if DEBUG=True served by Django; if DEBUG=False served by Whitenoise
execute_from_command_line(["manage.py", "collectstatic", "--no-input", "--verbosity", "0"])

# run Django built-in Web Server
print_info("Starting Web Server on {}:{}".format(web_host, web_port))
# log.info("Starting Web Server on {}:{}".format(web_host, web_port))

if web_tls:
execute_from_command_line(["manage.py", "runsslserver", "--noreload",
"--certificate", web_certificate, "--key", web_key,
"{}:{}".format(web_host, web_port)])
if settings.DEBUG:
print_warning("Running with DEBUG enabled - use this for debugging/development only!")
if web_tls:
execute_from_command_line(["manage.py", "runsslserver",
"--nostatic",
"--certificate", web_certificate, "--key", web_key,
"{}:{}".format(web_host, web_port)])
else:
execute_from_command_line(["manage.py", "runserver", "{}:{}".format(web_host, web_port)])

else:
execute_from_command_line(["manage.py", "runserver", "--noreload", "{}:{}".format(web_host, web_port)])
if web_tls:
execute_from_command_line(["manage.py", "runsslserver", "--noreload",
"--nostatic",
"--certificate", web_certificate, "--key", web_key,
"{}:{}".format(web_host, web_port)])
else:
execute_from_command_line(["manage.py", "runserver", "--noreload", "{}:{}".format(web_host, web_port)])
16 changes: 10 additions & 6 deletions viper/web/settings.py
Expand Up @@ -31,10 +31,10 @@


# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.11/howto/deployment/checklist/
# See https://docs.djangoproject.com/en/2.0/howto/deployment/checklist/

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
DEBUG = False

# ALLOWED_HOSTS = []
ALLOWED_HOSTS = ['*']
Expand All @@ -49,6 +49,7 @@
'django.contrib.messages',
'django.contrib.staticfiles',
'django_extensions',
'favicon',
'sslserver',
'rest_framework',
'rest_framework.authtoken',
Expand All @@ -59,6 +60,7 @@
)

MIDDLEWARE = [
'whitenoise.middleware.WhiteNoiseMiddleware',
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
Expand Down Expand Up @@ -113,7 +115,7 @@


# Database
# https://docs.djangoproject.com/en/1.11/ref/settings/#databases
# https://docs.djangoproject.com/en/2.0/ref/settings/
# We keep the database around so we can do admin stuff
# In the future use viper config file to set this.

Expand Down Expand Up @@ -182,7 +184,7 @@


# Internationalization
# https://docs.djangoproject.com/en/1.11/topics/i18n/
# https://docs.djangoproject.com/en/2.0/topics/i18n/

LANGUAGE_CODE = 'en-us'

Expand All @@ -196,12 +198,14 @@


# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.11/howto/static-files/
# https://docs.djangoproject.com/en/2.0/howto/static-files/

STATIC_URL = '/static/'

STATIC_ROOT = os.path.join(BASE_DIR, "static/")
STATIC_ROOT = os.path.join(__project__.base_path, "static/")

# Favicon https://pypi.python.org/pypi/django-favicon
FAVICON_PATH = STATIC_URL + 'viperweb/images/favicon.png'

# Import local settings from $storage_path/settings_local.py
try:
Expand Down
1 change: 1 addition & 0 deletions viper/web/urls.py
Expand Up @@ -12,6 +12,7 @@

urlpatterns = [
url(r'^', include('viper.web.viperweb.urls')),
url(r'^', include('favicon.urls')),
url(r'^admin/', admin.site.urls),
url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')),
url(r'^api/', include('viper.web.viperapi.urls')),
Expand Down
25 changes: 14 additions & 11 deletions viper/web/viperapi/serializers.py
Expand Up @@ -49,16 +49,18 @@ def to_representation(self, obj, recurse=True):
url = reverse("viperapi_v3:malware-detail",
kwargs={"project_name": self.context["project"], "sha256": obj.sha256},
request=self.context["request"])
links = list()
links.append(reverse("viperapi_v3:malware-analysis-list",
kwargs={"project_name": self.context["project"], "malware_sha256": obj.sha256},
request=self.context["request"]))
links.append(reverse("viperapi_v3:malware-note-list",
kwargs={"project_name": self.context["project"], "malware_sha256": obj.sha256},
request=self.context["request"]))
links.append(reverse("viperapi_v3:malware-tag-list",
kwargs={"project_name": self.context["project"], "malware_sha256": obj.sha256},
request=self.context["request"]))
links = dict()
links.update({"analysis": reverse("viperapi_v3:malware-analysis-list",
kwargs={"project_name": self.context["project"], "malware_sha256": obj.sha256},
request=self.context["request"])})
links.update({"notes": reverse("viperapi_v3:malware-note-list",
kwargs={"project_name": self.context["project"], "malware_sha256": obj.sha256},
request=self.context["request"])})
links.update({"tags": reverse("viperapi_v3:malware-tag-list",
kwargs={"project_name": self.context["project"], "malware_sha256": obj.sha256},
request=self.context["request"])})
links.update({"web": reverse("file-view", kwargs={"project": self.context["project"], "sha256": obj.sha256},
request=self.context["request"])})
ret.update({"links": links})
else:
detail_url_name = "viperapi_v3:{}-detail".format(obj.__class__.__table__)
Expand Down Expand Up @@ -141,7 +143,7 @@ def update(self, instance, validated_data):

return instance

def create(self, validated_data): # implementing update is required
def create(self, validated_data): # implementing create is required
pass


Expand Down Expand Up @@ -244,6 +246,7 @@ def to_representation(self, obj):
"malware": reverse("viperapi_v3:malware-list", kwargs={"project_name": obj}, request=self.context["request"]),
"notes": reverse("viperapi_v3:note-list", kwargs={"project_name": obj}, request=self.context["request"]),
"tags": reverse("viperapi_v3:tag-list", kwargs={"project_name": obj}, request=self.context["request"]),
"web": reverse("main-page-project", kwargs={"project": obj}, request=self.context["request"])
}
}

Expand Down
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit dc221e1

Please sign in to comment.