def run(self, *args): try: args = self.parser.parse_args(args) except SystemExit: return self.log("info", "Commands") rows = [] commands = load_commands() for command_name, command_item in commands.items(): rows.append([command_name, command_item["description"]]) rows.append(["exit, quit", "Exit Viper"]) rows = sorted(rows, key=lambda entry: entry[0]) self.log("table", dict(header=["Command", "Description"], rows=rows)) if len(__modules__) == 0: self.log("info", "No modules installed.") else: self.log("info", "Modules") rows = [] for module_name, module_item in __modules__.items(): rows.append([module_name, module_item["description"], ", ".join(c for c in module_item["categories"])]) rows = sorted(rows, key=lambda entry: entry[0]) self.log("table", dict(header=["Command", "Description", "Categories"], rows=rows))
def run(self, *args): try: args = self.parser.parse_args(args) except SystemExit: return self.log('info', "Commands") rows = [] commands = load_commands() for command_name, command_item in commands.items(): rows.append([command_name, command_item['description']]) rows.append(["exit, quit", "Exit Viper"]) rows = sorted(rows, key=lambda entry: entry[0]) self.log('table', dict(header=['Command', 'Description'], rows=rows)) self.log('info', "Modules") rows = [] for module_name, module_item in __modules__.items(): rows.append([module_name, module_item['description']]) rows = sorted(rows, key=lambda entry: entry[0]) self.log('table', dict(header=['Command', 'Description'], rows=rows))
def __init__(self): Database().__init__() # Map commands to their related functions. self.commands = load_commands()
class TestUseCases: cmd = load_commands() def teardown_method(self): __sessions__.close() @pytest.mark.usefixtures("cleandir") @pytest.mark.parametrize("filename, name", [ ("chromeinstall-8u31.exe", "chromeinstall-8u31.exe"), ("string_handling/with blank.txt", "with blank.txt"), ]) def test_store(self, capsys, filename, name): # use cleandir fixture operate on clean ./ local dir copyfile(os.path.join(FIXTURE_DIR, filename), os.path.join(".", os.path.basename(filename))) self.cmd['open']['obj']('-f', os.path.join(".", os.path.basename(filename))) self.cmd['store']['obj']() if sys.version_info <= (3, 0): in_fct = 'builtins.raw_input' else: in_fct = 'builtins.input' with mock.patch(in_fct, return_value='y'): self.cmd['delete']['obj']() out, err = capsys.readouterr() lines = out.split("\n") assert re.search(r".*Session opened on.*", lines[0]) assert not re.search(r".*Unable to store file.*", out) assert re.search(r".*{}.*".format(name), lines[1]) assert re.search(r".*Running command.*", lines[5]) assert re.search(r".*Deleted opened file.*", lines[7]) @pytest.mark.skipif(sys.version_info >= (3, 0), reason="requires python2") @pytest.mark.xfail(raises=Python2UnsupportedUnicode) @pytest.mark.usefixtures("cleandir") @pytest.mark.parametrize("filename, name", [ ("string_handling/dümmy.txt", "dümmy.txt") ]) def test_store_unicode_py2(self, capsys, filename, name): # use cleandir fixture operate on clean ./ local dir copyfile(os.path.join(FIXTURE_DIR, filename), os.path.join(".", os.path.basename(filename))) self.cmd['open']['obj']('-f', os.path.join(".", os.path.basename(filename))) self.cmd['store']['obj']() if sys.version_info <= (3, 0): in_fct = 'builtins.raw_input' else: in_fct = 'builtins.input' with mock.patch(in_fct, return_value='y'): self.cmd['delete']['obj']() out, err = capsys.readouterr() lines = out.split("\n") assert re.search(r".*Session opened on.*", lines[0]) assert not re.search(r".*Unable to store file.*", out) assert re.search(r".*{}.*".format(name), lines[1]) assert re.search(r".*Running command.*", lines[5]) assert re.search(r".*Deleted opened file.*", lines[7]) @pytest.mark.skipif(sys.version_info < (3, 3), reason="requires at least python3.3") @pytest.mark.usefixtures("cleandir") @pytest.mark.parametrize("filename, name", [ ("string_handling/dümmy.txt", "dümmy.txt") ]) def test_store_unicode_py3(self, capsys, filename, name): # use cleandir fixture operate on clean ./ local dir copyfile(os.path.join(FIXTURE_DIR, filename), os.path.join(".", os.path.basename(filename))) self.cmd['open']['obj']('-f', os.path.join(".", os.path.basename(filename))) self.cmd['store']['obj']() if sys.version_info <= (3, 0): in_fct = 'builtins.raw_input' else: in_fct = 'builtins.input' with mock.patch(in_fct, return_value='y'): self.cmd['delete']['obj']() out, err = capsys.readouterr() lines = out.split("\n") assert re.search(r".*Session opened on.*", lines[0]) assert not re.search(r".*Unable to store file.*", out) assert re.search(r".*{}.*".format(name), lines[1]) assert re.search(r".*Running command.*", lines[5]) assert re.search(r".*Deleted opened file.*", lines[7]) @pytest.mark.skipif(sys.version_info >= (3, 0), reason="requires python2") @pytest.mark.xfail(raises=Python2UnsupportedUnicode) @pytest.mark.parametrize("filename", ["chromeinstall-8u31.exe"]) def test_store_all_py2(self, capsys, filename): self.cmd['open']['obj']('-f', os.path.join(FIXTURE_DIR, filename)) self.cmd['store']['obj']() self.cmd['store']['obj']('-f', FIXTURE_DIR) out, err = capsys.readouterr() lines = out.split("\n") assert re.search(r".*Session opened on.*", lines[0]) assert re.search(r".*appears to be already stored.*", out) assert re.search(r".*Skip, file \"chromeinstall-8u31.exe\" appears to be already stored.*", out) @pytest.mark.skipif(sys.version_info < (3, 3), reason="requires at least python3.3") @pytest.mark.parametrize("filename", ["chromeinstall-8u31.exe"]) def test_store_all_py3(self, capsys, filename): self.cmd['open']['obj']('-f', os.path.join(FIXTURE_DIR, filename)) self.cmd['store']['obj']() self.cmd['store']['obj']('-f', FIXTURE_DIR) out, err = capsys.readouterr() lines = out.split("\n") assert re.search(r".*Session opened on.*", lines[0]) assert re.search(r".*appears to be already stored.*", out) assert re.search(r".*Skip, file \"chromeinstall-8u31.exe\" appears to be already stored.*", out) @pytest.mark.parametrize("filename", ["chromeinstall-8u31.exe"]) def test_open(self, capsys, filename): with open(os.path.join(FIXTURE_DIR, filename), 'rb') as f: hashfile = sha256(f.read()).hexdigest() self.cmd['open']['obj'](hashfile) self.cmd['info']['obj']() self.cmd['close']['obj']() out, err = capsys.readouterr() lines = out.split("\n") assert re.search(r".*Session opened on.*", lines[0]) assert re.search(r".*| SHA1 | 56c5b6cd34fa9532b5a873d6bdd4380cfd102218.*", lines[11]) @pytest.mark.parametrize("filename", ["chromeinstall-8u31.exe"]) def test_find(self, capsys, filename): with open(os.path.join(FIXTURE_DIR, filename), 'rb') as f: data = f.read() hashfile_sha = sha256(data).hexdigest() self.cmd['find']['obj']('all') self.cmd['find']['obj']('sha256', hashfile_sha) self.cmd['open']['obj']('-l', '1') self.cmd['close']['obj']() self.cmd['tags']['obj']('-a', 'blah') self.cmd['find']['obj']('-t') self.cmd['tags']['obj']('-d', 'blah') out, err = capsys.readouterr() assert re.search(r".*EICAR.com.*", out) assert re.search(r".*{0}.*".format(filename), out) assert re.search(r".*Tag.*|.*# Entries.*", out) def test_stats(self, capsys): self.cmd['stats']['obj']() out, err = capsys.readouterr() assert re.search(r".*Projects.*Name | Count.*", out)
def setup_class(cls): cmd = load_commands() cmd['open']['obj']('-f', os.path.join(FIXTURE_DIR, "chromeinstall-8u31.exe")) cmd['store']['obj']()
class TestCommands: cmd = load_commands() def setup_class(cls): cmd = load_commands() cmd['open']['obj']('-f', os.path.join(FIXTURE_DIR, "chromeinstall-8u31.exe")) cmd['store']['obj']() def teardown_method(self): self.cmd['close']['obj']() def test_help(self, capsys): self.cmd['help']['obj']() self.cmd['clear']['obj']() out, err = capsys.readouterr() assert re.search(r".* Commands.*", out) assert re.search(r".* Modules.*", out) def test_notes(self, capsys): self.cmd['notes']['obj']('-h') out, err = capsys.readouterr() assert re.search(r"usage: notes \[-h\] .*", out) self.cmd['notes']['obj']('-l') out, err = capsys.readouterr() assert re.search(".*No notes available for this file or.*", out) def test_open(self, capsys): self.cmd['open']['obj']('-h') self.cmd['open']['obj']('-u', 'https://github.com/viper-framework/viper-test-files/raw/master/test_files/cmd.exe') out, err = capsys.readouterr() assert re.search(r"usage: open \[-h\] .*", out) assert re.search(".*Session opened on /tmp/.*", out) def test_open_tor(self, capsys): self.cmd['open']['obj']('-h') self.cmd['open']['obj']('-t', '-u', 'https://github.com/viper-framework/viper-test-files/raw/master/test_files/cmd.exe') out, err = capsys.readouterr() assert re.search(r"usage: open \[-h\] .*", out) assert re.search(".*Session opened on /tmp/.*", out) def test_notes_existing(self, capsys): self.cmd['open']['obj']('-f', os.path.join(FIXTURE_DIR, "chromeinstall-8u31.exe")) Database().add_note(__sessions__.current.file.sha256, 'Note test', 'This is the content') self.cmd['notes']['obj']('-l') self.cmd['notes']['obj']('-v', '1') self.cmd['notes']['obj']('-d', '1') out, err = capsys.readouterr() assert re.search(".*1 | Note test.*", out) assert re.search(".*This is the content.*", out) def test_analysis(self, capsys): self.cmd['open']['obj']('-f', os.path.join(FIXTURE_DIR, "chromeinstall-8u31.exe")) self.cmd['analysis']['obj']('-h') self.cmd['analysis']['obj']('-l') self.cmd['analysis']['obj']('-v', '1') out, err = capsys.readouterr() assert re.search(r"usage: analysis \[-h\] .*", out) assert re.search(".*Saved On.*", out) assert re.search(".*Cmd Line.*", out) def test_store(self, capsys): self.cmd['store']['obj']('-h') out, err = capsys.readouterr() assert re.search(r"usage: store \[-h\] .*", out) def test_delete(self, capsys): self.cmd['delete']['obj']('-h') out, err = capsys.readouterr() assert re.search(r"usage: delete \[-h\] .*", out) def test_find(self, capsys): self.cmd['find']['obj']('-h') out, err = capsys.readouterr() assert re.search(r"usage: find \[-h\] .*", out) self.cmd['find']['obj']('all') out, err = capsys.readouterr() assert re.search(".*chromeinstall-8u31.exe.*", out) def test_tags(self, capsys): self.cmd['tags']['obj']('-h') out, err = capsys.readouterr() assert re.search(r"usage: tags \[-h\] .*", out) def test_tags_use(self, capsys): self.cmd['open']['obj']('-f', os.path.join(FIXTURE_DIR, "chromeinstall-8u31.exe")) self.cmd['tags']['obj']('-a', 'mytag') self.cmd['tags']['obj']('-d', 'mytag') out, err = capsys.readouterr() lines = out.split('\n') assert re.search(".*Tags added to the currently opened file.*", lines[1]) assert re.search(".*Refreshing session to update attributes....*", lines[2]) def test_sessions(self, capsys): self.cmd['sessions']['obj']('-h') out, err = capsys.readouterr() assert re.search(r"usage: sessions \[-h\] .*", out) self.cmd['sessions']['obj']('-l') out, err = capsys.readouterr() assert re.search(".*Opened Sessions.*", out) def test_projects(self, capsys): self.cmd['projects']['obj']('-h') out, err = capsys.readouterr() assert re.search(r"usage: projects \[-h\] .*", out) p = Project() p.open("project_switch_test1") self.cmd['projects']['obj']('-l') out, err = capsys.readouterr() assert re.search(".*Projects Available.*", out) assert re.search(".*project_switch_test1.*", out) assert not re.search(".*not_there.*", out) self.cmd['projects']['obj']('-s', 'project_switch_test1') out, err = capsys.readouterr() lines = out.split('\n') assert re.search(".*Switched to project.*", lines[0]) # return to default p.open("default") def test_export(self, capsys): self.cmd['export']['obj']('-h') out, err = capsys.readouterr() assert re.search(r"usage: export \[-h\] .*", out) def test_stats(self, capsys): self.cmd['stats']['obj']('-h') out, err = capsys.readouterr() assert re.search(r"usage: stats \[-h\] .*", out) def test_parent(self, capsys): self.cmd['parent']['obj']('-h') out, err = capsys.readouterr() assert re.search(r"usage: parent \[-h\] .*", out) def test_rename(self, capsys): self.cmd['find']['obj']("all") out, err = capsys.readouterr() assert out == "" self.cmd['open']['obj']('-f', os.path.join(FIXTURE_DIR, "chromeinstall-8u31.exe")) self.cmd['store']['obj']() _, _ = capsys.readouterr() if sys.version_info <= (3, 0): in_fct = 'builtins.raw_input' else: in_fct = 'builtins.input' with mock.patch(in_fct, return_value='chromeinstall-8u31.exe.new'): self.cmd['rename']['obj']() out, err = capsys.readouterr() lines = out.split('\n') assert re.search(r".*Current name is.*1mchromeinstall-8u31.exe.*", lines[0]) assert re.search(r".*Refreshing session to update attributes.*", lines[1]) def test_copy(self, capsys): self.cmd['projects']['obj']('-s', 'copy_test_dst') out, err = capsys.readouterr() lines = out.split('\n') assert re.search(r".*Switched to project.*", lines[0]) self.cmd['find']['obj']('all') out, err = capsys.readouterr() assert out == "" self.cmd['projects']['obj']('-s', 'copy_test_src') out, err = capsys.readouterr() lines = out.split('\n') assert re.search(r".*Switched to project.*", lines[0]) self.cmd['find']['obj']('all') out, err = capsys.readouterr() assert out == "" self.cmd['open']['obj']('-f', os.path.join(FIXTURE_DIR, "chromeinstall-8u31.exe")) self.cmd['store']['obj']() out, err = capsys.readouterr() lines = out.split('\n') assert re.search(r".*Session opened on.*", lines[0]) assert re.search(r".*Stored file.*", lines[1]) self.cmd['find']['obj']('all') out, err = capsys.readouterr() assert re.search(r".*\| 1 \| chromeinstall-8u31.exe.*", out) assert not re.search(r".*\| 2 \|.*", out) self.cmd['copy']['obj']('-d', 'copy_test_dst') out, err = capsys.readouterr() lines = out.split('\n') assert re.search(r".*Copied:.*", lines[0]) assert re.search(r".*Deleted:.*", lines[1]) assert re.search(r".*Successfully copied sample.*", lines[2]) self.cmd['find']['obj']('all') out, err = capsys.readouterr() assert out == "" assert not re.search(r".*\| 1 \| chromeinstall-8u31.exe.*", out) assert not re.search(r".*\| 2 \|.*", out) self.cmd['projects']['obj']('-s', 'copy_test_dst') out, err = capsys.readouterr() assert re.search(r".*Switched to project.*", out) self.cmd['find']['obj']('all') out, err = capsys.readouterr() assert re.search(r".*\| 1 \| chromeinstall-8u31.exe.*", out) assert not re.search(r".*\| 2 \|.*", out)
class ViperAPIv3Test(TestCase): cmd = load_commands() def setUp(self): self.factory = APIRequestFactory() self.client = APIClient() self.user = User.objects.create_user('testuser', email='*****@*****.**', password='******') self.user.save() token = Token.objects.create(user=self.user) token.save() def setup_method(self, method): """setUp by adding clean file""" # create api_test self.cmd['projects']['obj']('-s', 'api_test') self.cmd['open']['obj']('-f', os.path.join(FIXTURE_DIR, "chromeinstall-8u31.exe")) self.cmd['store']['obj']() def teardown_method(self, method): """clean all files""" self.cmd['projects']['obj']('-s', 'api_test') self.cmd['close']['obj']() if sys.version_info <= (3, 0): in_fct = 'builtins.raw_input' else: in_fct = 'builtins.input' with mock.patch(in_fct, return_value='y'): self.cmd['delete']['obj']('-a') def _require_login(self): self.client.login(username='******', password='******') def test_api_root(self): # Issue a GET request and check response code response = self.client.get("/api/v3/") self.assertEqual(response.status_code, 200) # Check that the response content self.assertEqual(response.json()['project'], "http://testserver/api/v3/project/") self.assertJSONEqual(force_text(response.content), {"project": "http://testserver/api/v3/project/"}) # TODO 2017-08-25 (frennkie) can't get this to run on Travis # def test_project_list_add(self): # self._require_login() # # self.maxDiff = None # # # check list # response = self.client.get("/api/v3/project/") # self.assertEqual(response.status_code, 200) # # # Check that the response content # self.assertIsInstance(response.json()['results'], list) # self.assertEqual(len(response.json()['results']), 5) # # expected_json = { # "count": 5, # "next": None, # "previous": None, # "results": [ # { # "url": "http://testserver/api/v3/project/api_test/", # "data": # {"name": "api_test"} # }, # { # 'url': 'http://testserver/api/v3/project/project_switch_test1/', # 'data': # {'name': 'project_switch_test1'}, # }, # { # 'url': 'http://testserver/api/v3/project/copy_test_src/', # 'data': # {'name': 'copy_test_src'}, # }, # { # 'url': 'http://testserver/api/v3/project/copy_test_dst/', # 'data': # {'name': 'copy_test_dst'}, # }, # { # "url": "http://testserver/api/v3/project/default/", # "data": # {"name": "default"} # } # ] # } # # self.assertJSONEqual(force_text(response.content), expected_json) # # # now add # response = self.client.post("/api/v3/project/", {"name": "api_test2"}) # self.assertEqual(response.status_code, 201) # # # Check that the response content # self.assertIsInstance(response.json()['data'], dict) # # expected_json = { # "data": { # "name": "api_test2" # }, # "url": "http://testserver/api/v3/project/api_test2/", # "links": { # "tags": "http://testserver/api/v3/project/api_test2/tag/", # "malware": "http://testserver/api/v3/project/api_test2/malware/", # "analysis": "http://testserver/api/v3/project/api_test2/analysis/", # "notes": "http://testserver/api/v3/project/api_test2/note/" # } # } # # self.assertJSONEqual(force_text(response.content), expected_json) # # response = self.client.get("/api/v3/project/") # self.assertEqual(len(response.json()['results']), 6) def test_default_project_detail(self): self._require_login() response = self.client.get("/api/v3/project/default/") self.assertEqual(response.status_code, 200) # Check that the response content self.assertIsInstance(response.json()['data'], dict) expected_json = { "data": { "name": "default" }, "url": "http://testserver/api/v3/project/default/", "links": { "tags": "http://testserver/api/v3/project/default/tag/", "malware": "http://testserver/api/v3/project/default/malware/", "analysis": "http://testserver/api/v3/project/default/analysis/", "notes": "http://testserver/api/v3/project/default/note/", "web": "http://testserver/project/default/" } } self.assertJSONEqual(force_text(response.content), expected_json) def test_project_detail(self): self._require_login() response = self.client.get("/api/v3/project/api_test/") self.assertEqual(response.status_code, 200) expected_json = { "data": { "name": "api_test" }, "url": "http://testserver/api/v3/project/api_test/", "links": { "tags": "http://testserver/api/v3/project/api_test/tag/", "malware": "http://testserver/api/v3/project/api_test/malware/", "analysis": "http://testserver/api/v3/project/api_test/analysis/", "notes": "http://testserver/api/v3/project/api_test/note/", "web": "http://testserver/project/api_test/" } } self.assertJSONEqual(force_text(response.content), expected_json) # Analysis: List all Analysis instances def test_analysis_list(self): self._require_login() response = self.client.get("/api/v3/project/api_test/analysis/") self.assertEqual(response.status_code, 200) self.assertIsInstance(response.json()['results'], list) self.assertEqual(len(response.json()['results']), 0) # self.assertEqual(response.json()['results'][0]['data']['cmd_line'], 'yara scan -t') # self.assertEqual(response.json()['results'][1]['data']['cmd_line'], 'triage') # Analysis: Retrieve an Analysis instance # def test_analysis_detail(self): # self._require_login() # # response = self.client.get("/api/v3/project/api_test/analysis/1/") # self.assertEqual(response.status_code, 200) # # self.assertEqual(response.json()['results']['data']['cmd_line'], 'yara scan -t') # Malware: List all Malware instances def test_malware_list(self): self._require_login() response = self.client.get("/api/v3/project/api_test/malware/") self.assertEqual(response.status_code, 200) self.assertIsInstance(response.json()['results'], list) self.assertEqual(len(response.json()['results']), 1) self.assertEqual( response.json()['results'][0]['data']['sha256'], '583a2d05ff0d4864f525a6cdd3bfbd549616d9e1d84e96fe145794ba0519d752') # Note: List all Note instances def test_note_list(self): self._require_login() response = self.client.get("/api/v3/project/api_test/note/") self.assertEqual(response.status_code, 200) self.assertIsInstance(response.json()['results'], list) self.assertEqual(len(response.json()['results']), 0) # Tag: List all Tag instances in project def test_tag_list(self): self._require_login() self.maxDiff = None response = self.client.get("/api/v3/project/api_test/tag/") self.assertEqual(response.status_code, 200) self.assertIsInstance(response.json()['results'], list) self.assertEqual(len(response.json()['results']), 0) # Tag: Add a new Tag to a Malware instance def test_malware_tag_add_remove(self): self._require_login() self.maxDiff = None response = self.client.get( "/api/v3/project/api_test/malware/583a2d05ff0d4864f525a6cdd3bfbd549616d9e1d84e96fe145794ba0519d752/tag/" ) self.assertEqual(response.status_code, 200) self.assertIsInstance(response.json()['results'], list) self.assertEqual(len(response.json()['results']), 0) response = self.client.post( "/api/v3/project/api_test/malware/583a2d05ff0d4864f525a6cdd3bfbd549616d9e1d84e96fe145794ba0519d752/tag/", {"tag": "foobar"}) self.assertEqual(response.status_code, 201) expected_json = { "data": { "id": 1, "tag": "foobar" }, "url": "http://testserver/api/v3/project/api_test/tag/1/" } self.assertJSONEqual(force_text(response.content), expected_json) response = self.client.delete( "/api/v3/project/api_test/malware/583a2d05ff0d4864f525a6cdd3bfbd549616d9e1d84e96fe145794ba0519d752/tag/1/" ) self.assertEqual(response.status_code, 204)