Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge Develop #53

Merged
merged 8 commits into from
Nov 23, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 0 additions & 8 deletions extensions/pstviewer/pstviewer.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ class PSTViewer(Extension):
# Paths should be relative to the extensions folder
extension_type = 'filedetails'
extension_name = 'PSTViewer'
template_name = 'pstviewer/pstviewer.html'
#extra_js = 'hiveviewer/hiveviewer.js'

def recursive_walk_folders(self, node, path):
if node.get_display_name():
Expand All @@ -34,8 +32,6 @@ def recursive_walk_folders(self, node, path):
'creation_time': msg.creation_time
}

print msg_dict['subject']

if node.get_display_name() in self.email_dict:
self.email_dict[node.get_display_name()].append(msg_dict)
else:
Expand All @@ -46,7 +42,6 @@ def recursive_walk_folders(self, node, path):
for i in range(0, node.get_number_of_sub_folders()):
folder = node.get_sub_folder(i)
folder_name = folder.get_display_name()
print folder_name
self.recursive_walk_folders(node.get_sub_folder(i), node_path)

def run(self):
Expand All @@ -65,12 +60,9 @@ def run(self):

base_path = u""
root_node = self.pst.get_root_folder()

self.email_dict = {}

self.recursive_walk_folders(root_node, base_path)


# Store in DB Now
store_data = {'file_id': file_id, 'pst': self.email_dict}
db.create_datastore(store_data)
Expand Down
6 changes: 5 additions & 1 deletion extensions/virustotalsearch/template.html
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@

<div id="vt-out">
<h3>VirusTotal - {{ VirusTotalSearch.state }}</h3>
{{ VirusTotalSearch.state }}
{% if VirusTotalSearch.state == 'complete' %}
{% if VirusTotalSearch.vt_results %}
<table class="table table-striped table-bordered table-hover">
Expand Down Expand Up @@ -57,6 +56,11 @@ <h2>Analysis is Still processing on VirusTotal Please try again shortly</h2>
<h2>Not present in VT Would you like to upload?</h2>
<a href="#" onclick="ajaxHandler('VirusTotalSearch', {'file_id':'{{VirusTotalSearch.file_id}}', 'upload':'true', 'target_div':'vt-out', 'extension':true}, false ); return false" class="btn btn-info" role="button">Upload to VirusTotal</a>

{% elif VirusTotalSearch.state == 'error' %}
<h2>{{ VirusTotalSearch.vt_results }}</h2>
<a href="#" onclick="ajaxHandler('VirusTotalSearch', {'file_id':'{{VirusTotalSearch.file_id}}', 'upload':'true', 'target_div':'vt-out', 'extension':true}, false ); return false" class="btn btn-info" role="button">Upload to VirusTotal</a>


{% else %}
<a href="#" onclick="ajaxHandler('VirusTotalSearch', {'file_id':'{{VirusTotalSearch.file_id}}', 'target_div':'vt-out', 'extension':true}, false ); return false" class="btn btn-info" role="button">Search VirusTotal</a>
{% endif %}
Expand Down
107 changes: 53 additions & 54 deletions extensions/virustotalsearch/virustotalsearch.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
from web.common import Extension
from web.database import Database
try:
import virus_total_apis
from virus_total_apis import PublicApi
VT_LIB = True
# Version check needs to be higher than 1.0.9
vt_ver = virus_total_apis.__version__.split('.')
if int(vt_ver[1]) < 1:
VT_LIB = False
except ImportError:
VT_LIB = False
import virus_total_apis
from virus_total_apis import PublicApi

# Version check needs to be higher than 1.0.9
vt_ver = virus_total_apis.__version__.split('.')
if int(vt_ver[1]) < 1:
raise UserWarning('Incompatible VirusTotalAPI Version detected. Requires 1.0.9 or higher. Found {0}'.format(vt_ver))


class VirusTotalSearch(Extension):
Expand All @@ -19,66 +16,68 @@ class VirusTotalSearch(Extension):

def run(self):
db = Database()
#self.render_javascript = "function test(){ alert(1); }; test();"
self.render_javascript = ""
if not self.config['virustotal']['api_key'] or not VT_LIB:
self.render_type = 'error'
self.render_data = "Unable to use Virus Total. No Key or Library Missing. Check the Console for details"

if 'file_id' in self.request.POST:
# Get file object from DB
file_id = self.request.POST['file_id']
file_object = db.get_filebyid(file_id)
sha256 = file_object.sha256

# Init the API with key from config
vt = PublicApi(self.config['virustotal']['api_key'])

# If we upload
if 'upload' in self.request.POST:
response = vt.scan_file(file_object.read(), filename=file_object.filename, from_disk=False)
if response['results']['response_code'] == 1 and 'Scan request successfully queued' in response['results']['verbose_msg']:
print "File Uploaded and pending"
state = 'pending'
else:
print response
state = 'error'
vt_results = None

# Else just get the results
print self.config['virustotal']['api_key'], type(self.config['virustotal']['api_key'])
if self.config['virustotal']['api_key'] == 'None':
state = 'error'
vt_results = 'No API Key set in volutility.conf'
else:
print "a"
# Init the API with key from config
vt = PublicApi(self.config['virustotal']['api_key'])

# If we upload
if 'upload' in self.request.POST:
response = vt.scan_file(file_object.read(), filename=file_object.filename, from_disk=False)
if response['results']['response_code'] == 1 and 'Scan request successfully queued' in response['results']['verbose_msg']:
print "File Uploaded and pending"
state = 'pending'
else:
print response
state = 'error'
vt_results = None

# Else just get the results
else:

# get results from VT
response = vt.get_file_report(sha256)
# get results from VT
response = vt.get_file_report(sha256)

vt_results = {}
vt_results = {}

# Valid response
if response['response_code'] == 200:
print "Valid Response from server"
# Valid response
if response['response_code'] == 200:
print "Valid Response from server"

# Not present in data set prompt to uploads
if response['results']['response_code'] == 0:
state = 'missing'
# Not present in data set prompt to uploads
if response['results']['response_code'] == 0:
state = 'missing'


# Still Pending
elif response['results']['response_code'] == -2:
# Still Pending
state = 'pending'

# Results availiable
elif response['results']['response_code'] == 1:
vt_results['permalink'] = response['results']['permalink']
vt_results['total'] = response['results']['total']
vt_results['positives'] = response['results']['positives']
vt_results['scandate'] = response['results']['scan_date']
vt_results['scans'] = response['results']['scans']
# Store the results in datastore
state = 'complete'

store_data = {'file_id': file_id, 'vt': vt_results, 'state': state}
db.create_datastore(store_data)
elif response['results']['response_code'] == -2:
# Still Pending
state = 'pending'

# Results availiable
elif response['results']['response_code'] == 1:
vt_results['permalink'] = response['results']['permalink']
vt_results['total'] = response['results']['total']
vt_results['positives'] = response['results']['positives']
vt_results['scandate'] = response['results']['scan_date']
vt_results['scans'] = response['results']['scans']
# Store the results in datastore
state = 'complete'

store_data = {'file_id': file_id, 'vt': vt_results, 'state': state}
db.create_datastore(store_data)

self.render_type = 'file'
self.render_data = {'VirusTotalSearch': {'state': state, 'vt_results': vt_results, 'file_id': file_id}}
Expand Down
Empty file added extensions/volshell/__init__.py
Empty file.
16 changes: 16 additions & 0 deletions extensions/volshell/template.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{% load template_dict %}
<h3>Voll Shell</h3>
<a id="volshell" href="#" onclick="ajaxHandler('VolShell', {'file_id':'{{file_id}}', 'shell_input': 'ps()', 'extension':true}, true ); return false" class="btn btn-info" role="button">Start VolShell</a>

<form class="form-inline">
<div class="form-group">
<input type="text" class="form-control" id="shell_input" placeholder="hh()">
</div>
<a id="volshell" href="#" onclick="ajaxHandler('VolShell', {'file_id':'{{file_id}}', 'shell_input': $('#shell_input').val(), 'extension':true}, true ); return false" class="btn-sm btn-info" role="button">Send Command</a>

</form>


<div class="well">
<div id="volshell-out"></div>
</div>
17 changes: 17 additions & 0 deletions extensions/volshell/volshell.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
if (postOptions['reset']){
//clear the nodelist
// The shell has been reset so clear the output and restore the VolShell start button

}
// Remove the volstart button
$('#volstart').remove();
//console.log(html_data);

// Append results to the window
$('#volshell-out').append(html_data);

// Scroll to bottom
$('#volshell-out').scrollTop(1E10);


// End Reg
85 changes: 85 additions & 0 deletions extensions/volshell/volshell.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import os
import re
import string
import pexpect
from web.common import Extension
from web.database import Database
from Registry import Registry
v = {'volshell_id': None, 'volshell_object': None}

class VolShell(Extension):

# Paths should be relative to the extensions folder
extension_name = 'VolShell'
extension_type = 'toolbar'
extra_js = 'volshell/volshell.js'

def strip_ansi_codes(self, s):
return re.sub(r'(\x9B|\x1B\[)[0-?]*[ -\/]*[@-~]', '', s)

def run(self):
global v
print v
db = Database()
session_id = self.request.POST['session_id']
shell_input = self.request.POST['shell_input']

if shell_input == 'resetvolshellsession':
v = {'volshell_id': None, 'volshell_object': None}



session = db.get_session(session_id)
vol_shell_cmd = 'vol.py --profile={0} -f {1} volshell'.format(session['session_profile'],
session['session_path']
)



if v['volshell_id']:
print "a is a stored object"
voll_shell = v['volshell_object']
else:
print "a is a new object"
voll_shell = pexpect.spawn(vol_shell_cmd)
print "b"

voll_shell.expect('m.\[0m.\[J.\[0;38;5;28mIn')
v['volshell_id'] = session_id



voll_shell.sendline(shell_input)

print "c"

voll_shell.expect('m.\[0m.\[J.\[0;38;5;28mIn', timeout=60)

print "d"


v['volshell_object'] = voll_shell
#returndata = voll_shell.read()

print "e"

before_data = self.strip_ansi_codes(voll_shell.before)
after_data = self.strip_ansi_codes(voll_shell.after)


print "Before Data: ", before_data

print "After Data: ", after_data




# lets start by getting input and saving it





self.render_type = 'html'
self.render_data = '<pre>{0}</pre>'.format(str(before_data))
self.render_javascript = open(os.path.join('extensions', self.extra_js), 'rb').read()
2 changes: 1 addition & 1 deletion extensions/yarascanner/template.html
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,6 @@ <h3>Yara Scanner</h3>
</select>
</div>

<a href="#" onclick="ajaxHandler('YaraScanner', {'file_id':'{{file_id}}', 'target_div':'yara-out', 'rule_file': $('#rule_file').val(), 'extension':true}, false ); return false" class="btn btn-info" role="button">Yara Scan</a>
<a href="#" onclick="ajaxHandler('YaraScanner', {'file_id':'{{file_id}}', 'target_div':'yara-out', 'rule_file': $('#rule_file').val(), 'extension':true}, true ); return false" class="btn btn-info" role="button">Yara Scan</a>
{% endif %}
</div>
1 change: 1 addition & 0 deletions extra/docker/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ RUN apt-get remove -yq \
gettext \
pkg-config \
libtool
RUN sudo apt-get clean

# Setup and Run
USER volutility
Expand Down
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
pexpect
django
distorm3
geoip2
Expand Down
8 changes: 6 additions & 2 deletions volutility.conf.sample
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ mongo_uri = mongodb://localhost

[virustotal]
api_type = public
api_key =
api_key = None

[autorun]
#
Expand All @@ -21,4 +21,8 @@ disabled = cuckoosandbox
[cuckoo]
# set modified to True for brads fork
modified = False
host = http://192.168.1.200:8000
host = http://192.168.1.200:8000

[style]
theme = slate.min.css
spinner = cat_spinner.gif
1 change: 0 additions & 1 deletion web/database.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,6 @@ def create_plugin(self, plugin_data):
# Force session ID
plugin_data['session_id'] = ObjectId(plugin_data['session_id'])
plugin_id = self.vol_plugins.insert_one(plugin_data).inserted_id
print plugin_id
return plugin_id

def search_plugins(self, search_text, session_id=None, plugin_name=None):
Expand Down
1 change: 1 addition & 0 deletions web/modules.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ def load_extensions():
ext_name = extension_name.split('.')[-1]

if ext_name in disable_list:
logger.info("Disabled Extension: {0}".format(ext_name))
continue

# Try to import the module, otherwise skip.
Expand Down
11 changes: 11 additions & 0 deletions web/static/css/slate.min.css

Large diffs are not rendered by default.

11 changes: 11 additions & 0 deletions web/static/css/spacelab.min.css

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions web/static/css/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ padding: 0px
z-index: 9999; /* Sit on top */
left: 0;
top: 0;
background-color: rgb(0,0,0); /* Black fallback color */
background-color: rgba(0,0,0, 0.9); /* Black w/opacity */
background-color: rgb(255,255,255); /* Black fallback color */
background-color: rgba(255,255,255, 0.5); /* Black w/opacity */
overflow-x: hidden; /* Disable horizontal scroll */
transition: 0.5s; /* 0.5 second transition effect to slide in or slide down the overlay (height or width, depending on reveal) */
}
Expand Down
Binary file added web/static/img/basic_spinner.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
File renamed without changes
Loading