Skip to content

Commit da59666

Browse files
committed
Add support for checking limits and do some various improvements
1 parent e5c8d30 commit da59666

File tree

9 files changed

+180
-12
lines changed

9 files changed

+180
-12
lines changed

cli/arguments_builders/default_cli_arguments.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,33 +13,53 @@ def __init__(self, parser: ArgumentParser):
1313
def add_sha256_arg(self, help='Sample sha256 hash'):
1414
self.parser.add_argument('sha256', type=str, help=help)
1515

16+
return self
17+
1618
def add_hash_arg(self, help='Md5, sha1 or sha256 hash'):
1719
self.parser.add_argument('hash', type=str, help=help)
1820

21+
return self
22+
1923
def add_scan_type_arg(self):
2024
self.parser.add_argument('scan-type', type=str, help='Type of scan (please use \'{}\' action to fetch all available scanners)'.format(ACTION_SCAN_STATE))
2125

26+
return self
27+
2228
def add_url_arg(self, help):
2329
self.parser.add_argument('url', type=str, help=help)
2430

31+
return self
32+
2533
def add_id_arg(self, help='Id in one of format: \'jobId\' or \'sha256:environmentId\''):
2634
self.parser.add_argument('id', type=str, help=help)
2735

36+
return self
37+
2838
def add_feed_days_arg(self):
2939
self.parser.add_argument('days', type=int, help='Number of days')
3040

41+
return self
42+
3143
def add_key_uid_arg(self):
3244
self.parser.add_argument('uid', type=str, help='Any string to allow find this key later')
3345

46+
return self
47+
3448
def add_file_with_hash_list_arg(self, allowed_hashes):
3549
self.parser.add_argument('hashes-file', type=argparse.FileType('r'), help='Path to file containing list of sample hashes separated by new line (allowed: {})'.format(', '.join(allowed_hashes)))
3650

51+
return self
52+
3753
def add_file_with_ids_arg(self, allowed_ids):
3854
self.parser.add_argument('mixed-ids-file', type=argparse.FileType('r'), help='Path to file containing list of ids (allowed: {}'.format(', '.join(allowed_ids)))
3955

56+
return self
57+
4058
def add_report_file_type_opt_arg(self):
4159
self.parser.add_argument('type', type=str, choices=['bin', 'json', 'pdf', 'crt', 'maec', 'stix', 'misp', 'misp-json', 'openioc', 'html', 'pcap', 'memory', 'xml'], help='Type of requested content')
4260

61+
return self
62+
4363
def add_submit_files_arg(self):
4464
def validate_path(path):
4565
files = [path]
@@ -62,6 +82,8 @@ def validate_path(path):
6282

6383
self.parser.add_argument('file', type=validate_path, help='File to submit (when directory given, all files from it will be submitted - non recursively)')
6484

85+
return self
86+
6587
def add_file_output_path_opt(self):
6688
self.parser.add_argument('--output', '-o', type=str, default='output', help='File output path')
6789

@@ -72,16 +94,26 @@ def add_env_id_arg(self, required: bool = False):
7294
else:
7395
self.parser.add_argument('environment-id', type=int, help=environment_id_help)
7496

97+
return self
98+
7599
def add_report_file_type_opt(self):
76100
self.parser.add_argument('--type', '-t', type=str, choices=['bin', 'json', 'pdf', 'crt', 'maec', 'misp', 'misp-json', 'openioc', 'html', 'pcap', 'memory', 'xml'], help='File type to return')
77101

102+
return self
103+
78104
def add_verbose_arg(self):
79105
self.parser.add_argument('--verbose', '-v', help="Run command in verbose mode", action='store_true')
80106

107+
return self
108+
81109
def add_help_opt(self):
82110
self.parser.add_argument('--help', '-h', action='help', default=argparse.SUPPRESS, help='Show this help message and exit.')
83111

112+
return self
113+
84114
def add_quiet_opt(self):
85115
self.parser.add_argument('--quiet', '-q', action='store_true', default=False, help='Suppress all prompts and warnings')
86116

117+
return self
118+
87119

cli/arguments_builders/demo_bulk_cli_arguments.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,19 @@ class DemoBulkCliArguments(DefaultCliArguments):
66
def add_report_demo_bulk_modify_hash_opt(self):
77
self.parser.add_argument('--modify-hash', '-mh', action='store_true', default=False, help='When set, will add null byte at the end of sample file')
88

9+
return self
10+
911
def add_report_demo_bulk_av_min_opt(self):
1012
self.parser.add_argument('--av-min', '-an', type=int, default=5, help='The minimum required AV detect')
1113

14+
return self
15+
1216
def add_report_demo_bulk_av_max_opt(self):
1317
self.parser.add_argument('--av-max', '-ax', type=int, default=15, help='The maximum required AV detect')
1418

19+
return self
20+
1521
def add_report_demo_bulk_look_back_size_opt(self):
1622
self.parser.add_argument('--look-back-size', '-lbs', type=int, default=400, help='Number of samples which will be fetched and filtered. Once you will get error message about problem with finding all samples, please increase that value')
23+
24+
return self

cli/arguments_builders/search_cli_arguments.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,21 +7,33 @@ class SearchCliArguments(DefaultCliArguments):
77
def add_search_term_filename_opt(self):
88
self.parser.add_argument('--filename', type=str, help='Filename e.g. invoice.exe')
99

10+
return self
11+
1012
def add_search_term_filetype_opt(self):
1113
self.parser.add_argument('--filetype', type=str, help='Filetype e.g. docx')
1214

15+
return self
16+
1317
def add_search_term_filetype_desc_opt(self):
1418
self.parser.add_argument('--filetype-desc', type=str, help='Filetype description e.g. PE32 executable')
1519

20+
return self
21+
1622
def add_search_term_env_id_opt(self):
1723
self.parser.add_argument('--env-id', type=int, help='Environment Id')
1824

25+
return self
26+
1927
def add_search_term_country_opt(self):
2028
self.parser.add_argument('--country', type=str, help='Country (3 digit ISO) e.g. swe')
2129

30+
return self
31+
2232
def add_search_term_verdict_opt(self):
2333
self.parser.add_argument('--verdict', type=int, help='Verdict', choices={1: 'whitelisted', 2: 'no verdict', 3: 'no specific threat', 4: 'suspicious', 5: 'malicious'})
2434

35+
return self
36+
2537
def add_search_term_av_detect_opt(self):
2638
def type_av_detect(value):
2739
if value.find('-'):
@@ -38,41 +50,69 @@ def type_av_detect(value):
3850

3951
self.parser.add_argument('--av-detect', type=type_av_detect, help='AV Multiscan range e.g. 50-70 (min 0, max 100)')
4052

53+
return self
54+
4155
def add_search_term_vx_family_opt(self):
4256
self.parser.add_argument('--vx-family', type=str, help='AV Family Substring e.g. nemucod')
4357

58+
return self
59+
4460
def add_search_term_tag_opt(self):
4561
self.parser.add_argument('--tag', type=str, help='Hashtag e.g. ransomware')
4662

63+
return self
64+
4765
def add_search_term_date_from_opt(self):
4866
self.parser.add_argument('--date-to', type=str, help='Date from in format: ‘Y-m-d H:i’ e.g. 2018-09-28 15:30') # TODO - add some date validator here
4967

68+
return self
69+
5070
def add_search_term_date_to_opt(self):
5171
self.parser.add_argument('--date-from', type=str, help='Date to in format: ‘Y-m-d H:i’ e.g. 2018-09-28 15:30')
5272

73+
return self
74+
5375
def add_search_term_port_opt(self):
5476
self.parser.add_argument('--port', type=str, help='Port e.g. 8080')
5577

78+
return self
79+
5680
def add_search_term_host_opt(self):
5781
self.parser.add_argument('--host', type=str, help='Host e.g. 192.168.0.1')
5882

83+
return self
84+
5985
def add_search_term_domain_opt(self):
6086
self.parser.add_argument('--domain', type=str, help='Domain e.g. checkip.dyndns.org')
6187

88+
return self
89+
6290
def add_search_term_url_opt(self):
6391
self.parser.add_argument('--url', type=str, help='HTTP Request Substring e.g. example')
6492

93+
return self
94+
6595
def add_search_term_similar_to_opt(self):
6696
self.parser.add_argument('--similar-to', type=str, help='Similar Samples e.g. <sha266>')
6797

98+
return self
99+
68100
def add_search_term_context_opt(self):
69101
self.parser.add_argument('--context', type=str, help='Sample Context e.g. <sha266>')
70102

103+
return self
104+
71105
def add_search_term_imp_hash_opt(self):
72106
self.parser.add_argument('--imphash', type=str)
73107

108+
return self
109+
74110
def add_search_term_ssdeep_opt(self):
75111
self.parser.add_argument('--ssdeep', type=str)
76112

113+
return self
114+
77115
def add_search_term_authentihash_opt(self):
78116
self.parser.add_argument('--authentihash', type=str)
117+
118+
return self

cli/arguments_builders/submission_cli_arguments.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,59 +7,99 @@ class SubmissionCliArguments(DefaultCliArguments):
77
def add_submission_submit_name_opt(self):
88
self.parser.add_argument('--submit-name', '-sn', type=str, help='Optional \'submission name\' field that will be used for file type detection and analysis')
99

10+
return self
11+
1012
def add_submission_comment_opt(self):
1113
self.parser.add_argument('--comment', '-co', type=str, help='Add comment (e.g. #hashtag) to sample')
1214

15+
return self
16+
1317
def add_submission_no_share_third_party_opt(self):
1418
self.parser.add_argument('--no-share-third-party', '-nstp', help='When set to \'1\', the sample is never shared with any third party', type=int, choices=[1, 0], default=1)
1519

20+
return self
21+
1622
def add_submission_allow_community_access_opt(self):
1723
self.parser.add_argument('--allow-community-access', '-aca', choices=[1, 0], default=1, type=int, help='When set \'1\', the sample will be available for vetted users of the HA community or custom application server')
1824

25+
return self
26+
1927
def add_submission_no_hash_lookup(self):
2028
self.parser.add_argument('--no-hash-lookup', '-nhl', choices=[1, 0], type=int)
2129

30+
return self
31+
2232
def add_submission_action_script_opt(self):
2333
self.parser.add_argument('--action-script', '-ac', choices={1: 'default', 2: 'default_maxantievasion', 3: 'default_randomfiles', 4: 'default_randomtheme', 5: 'default_openie'}, type=int, help='Optional custom runtime action script')
2434

35+
return self
36+
2537
def add_submission_hybrid_analysis_opt(self):
2638
self.parser.add_argument('--hybrid-analysis', '-ha', choices=[1, 0], type=int, help='When set to \'0\', no memory dumps or memory dump analysis will take place')
2739

40+
return self
41+
2842
def add_submission_experimental_anti_evasion_opt(self):
2943
self.parser.add_argument('--experimental-anti-evasion', '-eae', choices=[1, 0], type=int, help='When set to \'1\', will set all experimental anti-evasion options of the Kernelmode Monitor')
3044

45+
return self
46+
3147
def add_submission_script_logging_opt(self):
3248
self.parser.add_argument('--script-logging', '-sl', choices=[1, 0], type=int, help='When set to \'1\', will set the in-depth script logging engine of the Kernelmode Monitor')
3349

50+
return self
51+
3452
def add_submission_input_sample_tampering_opt(self):
3553
self.parser.add_argument('--input-sample-tampering', '--ist', choices=[1, 0], type=int, help='When set to \'1\', will allow experimental anti-evasion options of the Kernelmode Monitor that tamper with the input sample')
3654

55+
return self
56+
3757
def add_submission_tor_enabled_analysis_opt(self):
3858
self.parser.add_argument('--tor-enabled-analysis', '-tea', choices=[1, 0], type=int, help='When set to \'1\', will route the network traffic for the analysis via TOR (if properly configured on the server)')
3959

60+
return self
61+
4062
def add_submission_offline_analysis_opt(self):
4163
self.parser.add_argument('--offline-analysis', '-oa', choices=[1, 0], type=int, help='When set to \'1\', will disable outbound network traffic for the guest VM (takes precedence over ‘tor-enabled-analysis’ if both are provided)')
4264

65+
return self
66+
4367
def add_submission_email_opt(self):
4468
self.parser.add_argument('--email', '-e', type=str, help='Optional E-Mail address that may be associated with the submission for notification')
4569

70+
return self
71+
4672
def add_submission_custom_date_time_opt(self):
4773
self.parser.add_argument('--custom-date-time', '-cdt', type=str, help='Optional custom date/time that can be set for the analysis system. Expected format: yyyy-MM-dd HH:mm')
4874

75+
return self
76+
4977
def add_submission_custom_cmd_line_opt(self):
5078
self.parser.add_argument('--custom-cmd-line', '-ccl', type=str, help='Optional commandline that should be passed to the analysis file')
5179

80+
return self
81+
5282
def add_submission_custom_run_time_opt(self):
5383
self.parser.add_argument('--custom-run-time', '-crt', type=int, help='Optional runtime duration (in seconds)',)
5484

85+
return self
86+
5587
def add_submission_client_opt(self):
5688
self.parser.add_argument('--client', '-cl', type=str, help='Optional ‘client’ field (see ‘vxClients’)')
5789

90+
return self
91+
5892
def add_submission_priority_opt(self):
5993
self.parser.add_argument('--priority', '-pr', type=ValuesInBetweenAction(), help='Optional priority value between 0 (default) and 100 (highest)')
6094

95+
return self
96+
6197
def add_submission_document_password_opt(self):
6298
self.parser.add_argument('--document-password', '-dp', type=str, help='Optional document password that will be used to fill-in Adobe/Office password prompts')
6399

100+
return self
101+
64102
def add_submission_environment_variable_opt(self):
65103
self.parser.add_argument('--environment-variable', '-ev', type=str, help='Optional system environment value. The value is provided in the format: name=value')
104+
105+
return self

cli/cli_msg_printer.py

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,27 @@ def print_error_info(e):
3838

3939
@staticmethod
4040
def print_usage_info(api_usage_limits, api_usage, is_api_limit_reached):
41-
print(Color.control('API Limits for used API Key'))
41+
print(Color.control('API query limits for used API Key'))
4242
print('Webservice API usage limits: {}'.format(api_usage_limits))
4343
print('Current API usage: {}'.format(json.dumps(api_usage)))
4444
print('Is limit reached: {}'.format(Color.success('No') if is_api_limit_reached is False else Color.error('Yes')))
4545

46+
@staticmethod
47+
def print_submission_limit_info(submission_limits_data):
48+
if submission_limits_data:
49+
print(Color.control('Submission limits for used API Key'))
50+
print('Webservice API usage limits: {}'.format(submission_limits_data['total']['quota']))
51+
print('Current API usage: {}'.format(json.dumps(submission_limits_data['total']['used'])))
52+
print('Is limit reached: {}'.format(Color.success('No') if submission_limits_data['total']['quota_reached'] is False else Color.error('Yes')))
53+
54+
@staticmethod
55+
def print_quick_scan_limit_info(quick_scan_limits_data):
56+
if quick_scan_limits_data:
57+
print(Color.control('Quick scan submission limits for used API Key'))
58+
print('Webservice API usage limits: {}'.format(quick_scan_limits_data['total']['quota']))
59+
print('Current API usage: {}'.format(json.dumps(quick_scan_limits_data['total']['used'])))
60+
print('Is limit reached: {}'.format(Color.success('No') if quick_scan_limits_data['total']['quota_reached'] is False else Color.error('Yes')))
61+
4662
@staticmethod
4763
def print_api_key_info(current_key_json):
4864
print(Color.control('Used API Key'))

constants.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@
5050
ACTION_SCAN_URL_FOR_ANALYSIS = 'scan_url_for_analysis'
5151
ACTION_SCAN_URL_TO_FILE = 'scan_url_to_file'
5252

53+
ACTION_CHECK_LIMITS = 'check_limits'
54+
5355
MINIMAL_SUPPORTED_INSTANCE_VERSION = '8.20'
5456

5557
ACTION_WITH_MULTIPLE_CALL_SUPPORT = [ACTION_SUBMIT_FILE, ACTION_SCAN_FILE]

tests/base_test.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ def do_run(*args):
3232

3333
def see_headers(self):
3434
assert 'Running \'VxWebService Python API Connector\'' in self.output
35-
assert 'API Limits for used API Key' in self.output
35+
assert 'API query limits for used API Key' in self.output
3636
assert 'Request was sent at' in self.output
3737
assert 'Received response at' in self.output
3838
assert 'Showing response' in self.output

tests/conftest.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,6 @@
33

44
os.environ['APP_ENV'] = 'test'
55
os.environ['TEST_CONFIG'] = json.dumps({
6-
'api_key': 'test_me_please',
6+
'api_key': '6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b',
77
'server': 'mock://my-webservice-instance'
88
})

0 commit comments

Comments
 (0)