8
8
import datetime
9
9
import requests
10
10
import time
11
+ from urllib import parse
11
12
from warnings import warn
12
13
13
14
from ReversingLabs .SDK .helper import ADVANCED_SEARCH_SORTING_CRITERIA , DEFAULT_USER_AGENT , RESPONSE_CODE_ERROR_MAP , \
@@ -58,6 +59,13 @@ class A1000(object):
58
59
__ADVANCED_SEARCH_ENDPOINT = "/api/samples/search/"
59
60
__ADVANCED_SEARCH_ENDPOINT_V2 = "/api/samples/v2/search/"
60
61
__LIST_CONTAINERS_ENDPOINT = "/api/samples/containers/"
62
+ __URL_REPORT_ENDPOINT = "/api/network-threat-intel/url/"
63
+ __DOMAIN_REPORT_ENDPOINT = "/api/network-threat-intel/domain/{domain}/"
64
+ __IP_REPORT_ENDPOINT = "/api/network-threat-intel/ip/{ip}/report/"
65
+ __IP_TO_DOMAIN_ENDPOINT = "/api/network-threat-intel/ip/{ip}/resolutions/"
66
+ __URLS_FROM_IP_ENDPOINT = "/api/network-threat-intel/ip/{ip}/urls/"
67
+ __FILES_FROM_IP_ENDPOINT = "/api/network-threat-intel/ip/{ip}/downloaded_files/"
68
+
61
69
62
70
# Used by the deprecated get_results method
63
71
__FIELDS = ("id" , "sha1" , "sha256" , "sha512" , "md5" , "category" , "file_type" , "file_subtype" , "identification_name" ,
@@ -1780,7 +1788,7 @@ def start_or_stop_yara_cloud_retro_scan(self, operation, ruleset_name):
1780
1788
:param ruleset_name: name of the YARA ruleset that the Cloud Retro scan should be run on
1781
1789
:type ruleset_name: str
1782
1790
:return: response
1783
- :rtype: requests.Response::
1791
+ :rtype: requests.Response
1784
1792
"""
1785
1793
if operation not in ("START" , "STOP" , "CLEAR" ):
1786
1794
raise WrongInputError ("operation parameter must be either 'START', 'STOP' or 'CLEAR'" )
@@ -1805,7 +1813,7 @@ def get_yara_cloud_retro_scan_status(self, ruleset_name):
1805
1813
:param ruleset_name: name of the YARA ruleset for which to check for the Cloud Retro scan status
1806
1814
:type ruleset_name: str
1807
1815
:return: response
1808
- :rtype: requests.Response::
1816
+ :rtype: requests.Response
1809
1817
"""
1810
1818
if not isinstance (ruleset_name , str ):
1811
1819
raise WrongInputError ("ruleset_name parameter must be a string" )
@@ -2049,7 +2057,7 @@ def list_containers_for_hashes(self, sample_hashes):
2049
2057
or MD5)
2050
2058
:type sample_hashes list[str]
2051
2059
:return: response
2052
- :rtype: requests.Response::
2060
+ :rtype: requests.Response
2053
2061
"""
2054
2062
if not isinstance (sample_hashes , list ):
2055
2063
raise WrongInputError ("sample_hashes parameter must be a list of strings." )
@@ -2069,6 +2077,131 @@ def list_containers_for_hashes(self, sample_hashes):
2069
2077
2070
2078
return response
2071
2079
2080
+ def network_url_report (self , requested_url ):
2081
+ """Accepts a URL string and returns a report about the requested URL.
2082
+ :param requested_url: URL for analysis
2083
+ :type requested_url: str
2084
+ :return: response
2085
+ :rtype: requests.Response
2086
+ """
2087
+
2088
+ if not isinstance (requested_url , str ):
2089
+ raise WrongInputError ("url parameter must be string." )
2090
+
2091
+ encoded_url = parse .quote_plus (requested_url )
2092
+
2093
+ endpoint = "{endpoint}?url={url}" .format (
2094
+ endpoint = self .__URL_REPORT_ENDPOINT ,
2095
+ url = encoded_url
2096
+ )
2097
+
2098
+ url = self ._url .format (endpoint = endpoint )
2099
+
2100
+ response = self .__get_request (url = url )
2101
+
2102
+ self .__raise_on_error (response )
2103
+
2104
+ return response
2105
+
2106
+ def network_domain_report (self , domain ):
2107
+ """Accepts a domain string and returns a report about the requested domain.
2108
+ :param domain: domain for analysis
2109
+ :type domain: str
2110
+ :return: response
2111
+ :rtype: requests.Response
2112
+ """
2113
+ if not isinstance (domain , str ):
2114
+ raise WrongInputError ("domain parameter must be string." )
2115
+
2116
+ endpoint = self .__DOMAIN_REPORT_ENDPOINT .format (domain = domain )
2117
+
2118
+ url = self ._url .format (endpoint = endpoint )
2119
+
2120
+ response = self .__get_request (url = url )
2121
+
2122
+ self .__raise_on_error (response )
2123
+
2124
+ return response
2125
+
2126
+ def network_ip_addr_report (self , ip_addr ):
2127
+ """Accepts an IP address string and returns a report about the requested IP address.
2128
+ :param ip_addr: IP address for analysis
2129
+ :type ip_addr: str
2130
+ :return: response
2131
+ :rtype: requests.Response
2132
+ """
2133
+ response = self .__ip_addr_endpoints (
2134
+ ip_addr = ip_addr ,
2135
+ specific_endpoint = self .__IP_REPORT_ENDPOINT
2136
+ )
2137
+
2138
+ return response
2139
+
2140
+ def network_ip_to_domain (self , ip_addr ):
2141
+ """Accepts an IP address string and returns a list of IP-to-domain mappings.
2142
+ :param ip_addr: requested IP address
2143
+ :type ip_addr: str
2144
+ :return: response
2145
+ :rtype: requests.Response
2146
+ """
2147
+ response = self .__ip_addr_endpoints (
2148
+ ip_addr = ip_addr ,
2149
+ specific_endpoint = self .__IP_TO_DOMAIN_ENDPOINT
2150
+ )
2151
+
2152
+ return response
2153
+
2154
+ def network_urls_from_ip (self , ip_addr ):
2155
+ """Accepts an IP address string and returns a list of URLs hosted on the requested IP address.
2156
+ :param ip_addr: requested IP address
2157
+ :type ip_addr: str
2158
+ :return: response
2159
+ :rtype: requests.Response
2160
+ """
2161
+ response = self .__ip_addr_endpoints (
2162
+ ip_addr = ip_addr ,
2163
+ specific_endpoint = self .__URLS_FROM_IP_ENDPOINT
2164
+ )
2165
+
2166
+ return response
2167
+
2168
+ def network_files_from_ip (self , ip_addr ):
2169
+ """Accepts an IP address string and returns a list of hashes and
2170
+ classifications for files found on the requested IP address.
2171
+ :param ip_addr: requested IP address
2172
+ :type ip_addr: str
2173
+ :return: response
2174
+ :rtype: requests.Response
2175
+ """
2176
+ response = self .__ip_addr_endpoints (
2177
+ ip_addr = ip_addr ,
2178
+ specific_endpoint = self .__FILES_FROM_IP_ENDPOINT
2179
+ )
2180
+
2181
+ return response
2182
+
2183
+ def __ip_addr_endpoints (self , ip_addr , specific_endpoint ):
2184
+ """Private method for all IP related endpoints from the Network Threat Intelligence API.
2185
+ :param ip_addr: requested IP address
2186
+ :type ip_addr: str
2187
+ :param specific_endpoint: requested endpoint string
2188
+ :type specific_endpoint: str
2189
+ :return: response
2190
+ :rtype: requests.Response
2191
+ """
2192
+ if not isinstance (ip_addr , str ):
2193
+ raise WrongInputError ("ip_addr parameter must be string." )
2194
+
2195
+ endpoint = specific_endpoint .format (ip = ip_addr )
2196
+
2197
+ url = self ._url .format (endpoint = endpoint )
2198
+
2199
+ response = self .__get_request (url = url )
2200
+
2201
+ self .__raise_on_error (response )
2202
+
2203
+ return response
2204
+
2072
2205
def __get_token (self , username , password ):
2073
2206
"""Returns an obtained token using the provided username and password.
2074
2207
:return: token string
@@ -2237,9 +2370,6 @@ def __create_post_payload(custom_filename=None, file_url=None, crawler=None, ar
2237
2370
if threat_name :
2238
2371
data ['threat_name' ] = threat_name
2239
2372
2240
- if len (data ) == 0 :
2241
- data = None
2242
-
2243
2373
if name :
2244
2374
data ['name' ] = name
2245
2375
@@ -2252,6 +2382,9 @@ def __create_post_payload(custom_filename=None, file_url=None, crawler=None, ar
2252
2382
if ticloud :
2253
2383
data ['ticloud' ] = ticloud
2254
2384
2385
+ if not data :
2386
+ return None
2387
+
2255
2388
return data
2256
2389
2257
2390
def __analysis_is_finished (self , sample_hashes ):
0 commit comments