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

every vuln chain #81

Merged
merged 23 commits into from
Mar 27, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
6fed643
[Style] Cleanup def chains and save a little
KevinHock Feb 28, 2018
7df6529
[blackbox stuff] wrote get_vulnerability_chains, cleaned up def-use code
KevinHock Mar 2, 2018
71ad9a1
Merge branch 'master' into every_vuln_chain
KevinHock Mar 2, 2018
e075e93
[cleanup] remove if after merging in master that had the RHS vars fix
KevinHock Mar 2, 2018
12ab2e1
[blackbox stuff]Add interactive UI mode option, cleanup __main__ a bit
KevinHock Mar 3, 2018
57878c9
[nothing significant] changing gears to tox branch
KevinHock Mar 3, 2018
2dcd579
[gotta go to work] made blackbox mapping file option, refactored all …
KevinHock Mar 5, 2018
7aa580b
[cleanup] Moved trigger_definitions to vulnerability_definitions to h…
KevinHock Mar 6, 2018
e510739
[blackbox stuff] start to check and save the mapping, still need to f…
KevinHock Mar 6, 2018
1c80a0f
Merge branch 'master' into every_vuln_chain
KevinHock Mar 9, 2018
b2bc719
Some huge vulnerabilities.py changes and cleanup, including a vuln_fa…
KevinHock Mar 15, 2018
e5d0b2c
Disinfected all but 3 tests, Scrubbed ugly special case code for Vars…
KevinHock Mar 16, 2018
a5be8be
Mop up reasoning for .args comment, Scour passing in an empty list wh…
KevinHock Mar 16, 2018
84a25f2
Get path_traversal_sanitised_2 to work, remove a bad connect in save_…
KevinHock Mar 22, 2018
7643fbc
Merge branch 'master' into every_vuln_chain
KevinHock Mar 23, 2018
cfbefef
Made node types for If and Try statements statements, moved some Labe…
KevinHock Mar 23, 2018
0dead7c
Delete intra_cfg, same as in master
KevinHock Mar 23, 2018
1d11a05
[DRY] Remove all 'line_number=node.lineno' for node def sites
KevinHock Mar 23, 2018
6bb2a68
[DRY] Remove more 'line_number=node.lineno' from node def sites
KevinHock Mar 23, 2018
3df4c28
Added a comment to ConnectToExitNode
KevinHock Mar 24, 2018
8ee2e8a
Add period at the end of docstring comment
KevinHock Mar 26, 2018
d70133d
[refactor] namedtuples changed field lists to tuples
KevinHock Mar 27, 2018
4447c75
re-Add period at the end of docstring comment
KevinHock Mar 27, 2018
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
25 changes: 25 additions & 0 deletions example/vulnerable_code/ensure_saved_scope.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import os
from flask import Flask, request, send_file

app = Flask(__name__)

def outer(outer_arg, other_arg):
outer_ret_val = outer_arg + 'hey' + other_arg
return outer_ret_val

def inner():
return 'boom'

@app.route('/')
def cat_picture():
image_name = request.args.get('image_name')
if not image_name:
image_name = 'foo'
return 404
foo = outer(inner(), image_name) # Nested call after if caused the problem
send_file(image_name)
return 'idk'


if __name__ == '__main__':
app.run(debug=True)
19 changes: 19 additions & 0 deletions example/vulnerable_code/multi_chain.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import subprocess
from flask import Flask, render_template, request


app = Flask(__name__)


@app.route('/multi_chain', methods=['POST'])
def multi_chain():
suggestion = request.form['suggestion']
x = fast_eddie(suggestion, 'the')
y = x + 'foo'
z = minnesota_fats(suggestion, 'sting')
ben = graham(y, z)

subprocess.call(ben, shell=True)

return render_template('multi_chain.html')

2 changes: 1 addition & 1 deletion example/vulnerable_code/path_traversal.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ def cat_picture():
if not image_name:
image_name = 'foo'
return 404
foo = outer(inner(), image_name) # Nested call after if caused the problem
foo = outer(inner(), image_name) # Nested call after if caused the problem
send_file(foo)
return 'idk'

Expand Down
2 changes: 1 addition & 1 deletion example/vulnerable_code/path_traversal_sanitised_2.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
def cat_picture():
image_name = request.args.get('image_name')

if not '..' in image_name:
if '..' in image_name:
return 404
return send_file(os.path.join(os.getcwd(), image_name))

Expand Down
89 changes: 60 additions & 29 deletions pyt/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,13 @@
from datetime import date
from pprint import pprint

from .argument_helpers import valid_date
from .argument_helpers import (
default_blackbox_mapping_file,
default_trigger_word_file,
valid_date,
VulnerabilityFiles,
UImode
)
from .ast_helper import generate_ast
from .draw import draw_cfgs, draw_lattices
from .constraint_table import initialize_constraint_table, print_table
Expand Down Expand Up @@ -72,10 +78,22 @@ def parse_args(args):
print_group.add_argument('-vp', '--verbose-print',
help='Verbose printing of -p.', action='store_true')
print_group.add_argument('-trim', '--trim-reassigned-in',
help='Trims the reassigned list to the vulnerability chain.', action='store_true')
help='Trims the reassigned list to the vulnerability chain.',
action='store_true',
default=False)
print_group.add_argument('-i', '--interactive',
help='Will ask you about each vulnerability chain and blackbox nodes.',
action='store_true',
default=False)

parser.add_argument('-t', '--trigger-word-file',
help='Input trigger word file.', type=str)
help='Input trigger word file.',
type=str,
default=default_trigger_word_file)
parser.add_argument('-b', '--blackbox-mapping-file',
help='Input blackbox mapping file.',
type=str,
default=default_blackbox_mapping_file)
parser.add_argument('-py2', '--python-2',
help='[WARNING, EXPERIMENTAL] Turns on Python 2 mode,' +
' needed when target file(s) are written in Python 2.', action='store_true')
Expand Down Expand Up @@ -150,11 +168,13 @@ def parse_args(args):

search_parser.add_argument('-sd', '--start-date',
help='Start date for repo search. '
'Criteria used is Created Date.', type=valid_date)
'Criteria used is Created Date.',
type=valid_date,
default=date(2010, 1, 1))
return parser.parse_args(args)


def analyse_repo(github_repo, analysis_type):
def analyse_repo(github_repo, analysis_type, ui_mode):
cfg_list = list()
directory = os.path.dirname(github_repo.path)
project_modules = get_modules(directory)
Expand All @@ -170,42 +190,54 @@ def analyse_repo(github_repo, analysis_type):

initialize_constraint_table(cfg_list)
analyse(cfg_list, analysis_type=analysis_type)
vulnerability_log = find_vulnerabilities(cfg_list, analysis_type)
vulnerability_log = find_vulnerabilities(
cfg_list,
analysis_type,
ui_mode,
VulnerabilityFiles(
args.blackbox_mapping_file,
args.trigger_word_file
)
)
return vulnerability_log


def main(command_line_args=sys.argv[1:]):
args = parse_args(command_line_args)

analysis = None
analysis = ReachingDefinitionsTaintAnalysis
if args.liveness:
analysis = LivenessAnalysis
elif args.reaching:
analysis = ReachingDefinitionsAnalysis
elif args.reaching_taint:
analysis = ReachingDefinitionsTaintAnalysis
else:
analysis = ReachingDefinitionsTaintAnalysis

ui_mode = UImode.NORMAL
if args.interactive:
ui_mode = UImode.INTERACTIVE
elif args.trim_reassigned_in:
ui_mode = UImode.TRIM

cfg_list = list()
if args.git_repos:
repos = get_repos(args.git_repos)
for repo in repos:
repo.clone()
vulnerability_log = analyse_repo(repo, analysis)
vulnerability_log = analyse_repo(repo, analysis, ui_mode)
vulnerability_log.print_report()
if not vulnerability_log.vulnerabilities:
repo.clean_up()
exit()

if args.which == 'search':
set_github_api_token()
if args.start_date:
scan_github(args.search_string, args.start_date,
analysis, analyse_repo, args.csv_path)
else:
scan_github(args.search_string, date(2010, 1, 1),
analysis, analyse_repo, args.csv_path)
scan_github(
args.search_string,
args.start_date,
analysis,
analyse_repo,
args.csv_path,
ui_mode
)
exit()

path = os.path.normpath(args.filepath)
Expand All @@ -221,6 +253,7 @@ def main(command_line_args=sys.argv[1:]):
tree = generate_ast(path, python_2=args.python_2)

cfg_list = list()

interprocedural_cfg = interprocedural(
tree,
project_modules,
Expand All @@ -243,17 +276,15 @@ def main(command_line_args=sys.argv[1:]):

analyse(cfg_list, analysis_type=analysis)

vulnerability_log = None
if args.trigger_word_file:
vulnerability_log = find_vulnerabilities(cfg_list,
analysis,
args.trim_reassigned_in,
args.trigger_word_file)
else:
vulnerability_log = find_vulnerabilities(cfg_list,
analysis,
args.trim_reassigned_in)

vulnerability_log = find_vulnerabilities(
cfg_list,
analysis,
ui_mode,
VulnerabilityFiles(
args.blackbox_mapping_file,
args.trigger_word_file
)
)
vulnerability_log.print_report()

if args.draw_cfg:
Expand Down
32 changes: 32 additions & 0 deletions pyt/argument_helpers.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,22 @@
import os
from argparse import ArgumentTypeError
from collections import namedtuple
from datetime import datetime
from enum import Enum


default_blackbox_mapping_file = os.path.join(
os.path.dirname(__file__),
'vulnerability_definitions',
'blackbox_mapping.json'
)


default_trigger_word_file = os.path.join(
os.path.dirname(__file__),
'vulnerability_definitions',
'flask_trigger_words.pyt'
)


def valid_date(s):
Expand All @@ -9,3 +26,18 @@ def valid_date(s):
except ValueError:
msg = "Not a valid date: '{0}'. Format: {1}".format(s, date_format)
raise ArgumentTypeError(msg)


class UImode(Enum):
INTERACTIVE = 0
NORMAL = 1
TRIM = 2


VulnerabilityFiles = namedtuple(
'VulnerabilityFiles',
(
'blackbox_mapping',
'triggers'
)
)
Loading