Skip to content

Commit

Permalink
Dev - Ease of use release - 0.0.2 (#3)
Browse files Browse the repository at this point in the history
* Updated README.md with new usage examples.

* Added new examples for changes to virustotal.py

* Bumped version. Changes to address issue #2

* Added Changelog.

* Bumped version. Added keywords.
  • Loading branch information
Dextroz committed Apr 15, 2019
1 parent c871c89 commit 521af78
Show file tree
Hide file tree
Showing 4 changed files with 133 additions and 50 deletions.
80 changes: 62 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,33 +25,66 @@ Or

## Example Usage
```python
from virustotal_python import Virustotal
from virustotal import Virustotal
from pprint import pprint

vtotal = Virustotal("Insert API Key Here.")

# NOTE: Check virustotal.py for docstrings containing full parameter descriptions.

# Send a file to Virustotal for analysis.
resp = vtotal.file_scan("./test.py") # PATH to file for querying.
resp = vtotal.file_scan("./test.py") # PATH to file for querying.

# Resend a file to Virustotal for analysis.
# Contains the resource (SHA256) HASH of the file above.
resp = vtotal.file_rescan("75efd85cf6f8a962fe016787a7f57206ea9263086ee496fc62e3fc56734d4b53")
# Also accepts a CSV list (MAX 25 items)
resp = vtotal.file_rescan("HASH,HASH,HASH,HASH,etc.")

# Retrieve scan report(s) for a given file from Virustotal.
resp = vtotal.file_report("75efd85cf6f8a962fe016787a7f57206ea9263086ee496fc62e3fc56734d4b53")
# Or accepts a CSV list with a combination of scan_ids and HASHs.
resp = vtotal.file_report("scan_id,HASH,scan_id,HASH")
# A list containing the resource (SHA256) HASH of the file above.
resp = vtotal.file_rescan(
["75efd85cf6f8a962fe016787a7f57206ea9263086ee496fc62e3fc56734d4b53"]
)
# A list containing md5/sha1/sha256 hashes. Can be a combination of any of the three allowed hashes (MAX 25 items).
# NOTE: The second hash here is flagged as malicious by multiple engines.
resp = vtotal.file_rescan(
[
"75efd85cf6f8a962fe016787a7f57206ea9263086ee496fc62e3fc56734d4b53",
"9f101483662fc071b7c10f81c64bb34491ca4a877191d464ff46fd94c7247115",
]
)

# Retrieve scan report(s) for given file(s) from Virustotal.
# A list containing the resource (SHA256) HASH of a known malicious file.
resp = vtotal.file_report(
["9f101483662fc071b7c10f81c64bb34491ca4a877191d464ff46fd94c7247115"]
)
# A list of resource(s). Can be `md5/sha1/sha256 hashes` and/or combination of hashes and scan_ids (MAX 4 per standard request rate).
# The first is a scan_id, the second is a SHA256 HASH.
resp = vtotal.file_report(
[
"75efd85cf6f8a962fe016787a7f57206ea9263086ee496fc62e3fc56734d4b53-1555351539",
"9f101483662fc071b7c10f81c64bb34491ca4a877191d464ff46fd94c7247115",
]
)

# Query url(s) to VirusTotal.
resp = vtotal.url_scan("ihaveaproblem.info") # Query a single url.
resp = vtotal.url_scan("ihaveaproblem.info\ngoogle.com\nwikipedia.com\ngithub.com") # Query multiple url(s) seperated by "\n" character.

# Retrieve report(s)
resp = vtotal.url_report("ihaveaproblem.info") # Query a single url.
resp = vtotal.url_report("ihaveaproblem.info\ngoogle.com\nwikipedia.com\ngithub.com", scan="1") # Get the report(s) for a url(s), scan_id(s).
# A list containing a url to be scanned by VirusTotal.
resp = vtotal.url_scan(["ihaveaproblem.info"]) # Query a single url.
# A list of url(s) to be scanned by VirusTotal (MAX 4 per standard request rate).
resp = vtotal.url_scan(
["ihaveaproblem.info", "google.com", "wikipedia.com", "github.com"]
)

# Retrieve url report(s)
# A list containing the url of the report to be retrieved.
resp = vtotal.url_report(["ihaveaproblem.info"]) # Query a single url.
# A list of the url(s) and/or scan_id(s) report(s) to be retrieved (MAX 4 per standard request rate).
# The first object in the list is a scan_id.
resp = vtotal.url_report(
[
"fd21590d9df715452c8c000e1b5aa909c7c5ea434c2ddcad3f4ccfe9b0ee224e-1555352750",
"google.com",
"wikipedia.com",
"github.com",
],
scan="1",
)

# Query an IP to Virustotal.
resp = vtotal.ipaddress_report("90.156.201.27")
Expand All @@ -60,7 +93,12 @@ resp = vtotal.ipaddress_report("90.156.201.27")
resp = vtotal.domain_report("027.ru")

# Put a comment onto a specific resource.
resp = vtotal.put_comment("ihaveaproblem.info", comment="This website is flagged by a few scanners as malicious! #watchout")
resp = vtotal.put_comment(
"9f101483662fc071b7c10f81c64bb34491ca4a877191d464ff46fd94c7247115",
comment="#watchout, this looks very malicious!",
)

pprint(resp)
```

```python
Expand All @@ -79,6 +117,12 @@ pprint(resp)
'status_code': 200}
```

## Changelog

* 0.0.2 - Changes to file_rescan(), file_report(), url_scan(), url_report() to improve ease of use of the wrapper. See issue [#2](https://github.com/Dextroz/virustotal-python/issues/2). Examples updated for changes.

* 0.0.1 - Inital release of virustotal-python. Covered all endpoints of the Virustotal public API.

## Authors -- Contributors

* **Dextroz** - *Author* - [Dextroz](https://github.com/Dextroz)
Expand Down
7 changes: 4 additions & 3 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

setup(
name="virustotal-python",
version="0.0.1",
version="0.0.2",
author="Dextroz",
author_email="[email protected]",
description="A light wrapper around the public VirusTotal API.",
Expand All @@ -16,6 +16,7 @@
classifiers=[
"License :: OSI Approved :: MIT License",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.7"
"Programming Language :: Python :: 3.7",
],
)
keywords="Light VirusTotal Wrapper Public API",
)
68 changes: 53 additions & 15 deletions virustotal_python/examples.py
Original file line number Diff line number Diff line change
@@ -1,30 +1,63 @@
from virustotal import Virustotal
from pprint import pprint

vtotal = Virustotal("Insert API Key Here.")

# NOTE: Check virustotal.py for docstrings containing full parameter descriptions.

# Send a file to Virustotal for analysis.
resp = vtotal.file_scan("./test.py") # PATH to file for querying.
resp = vtotal.file_scan("./test.py") # PATH to file for querying.

# Resend a file to Virustotal for analysis.
# Contains the resource (SHA256) HASH of the file above.
resp = vtotal.file_rescan("75efd85cf6f8a962fe016787a7f57206ea9263086ee496fc62e3fc56734d4b53")
# Also accepts a CSV list (MAX 25 items)
resp = vtotal.file_rescan("HASH,HASH,HASH,HASH,etc.")
# A list containing the resource (SHA256) HASH of the file above.
resp = vtotal.file_rescan(
["75efd85cf6f8a962fe016787a7f57206ea9263086ee496fc62e3fc56734d4b53"]
)
# A list containing md5/sha1/sha256 hashes. Can be a combination of any of the three allowed hashes (MAX 25 items).
# NOTE: The second hash here is flagged as malicious by multiple engines.
resp = vtotal.file_rescan(
[
"75efd85cf6f8a962fe016787a7f57206ea9263086ee496fc62e3fc56734d4b53",
"9f101483662fc071b7c10f81c64bb34491ca4a877191d464ff46fd94c7247115",
]
)

# Retrieve scan report(s) for a given file from Virustotal.
resp = vtotal.file_report("75efd85cf6f8a962fe016787a7f57206ea9263086ee496fc62e3fc56734d4b53")
# Or accepts a CSV list with a combination of scan_ids and HASHs.
resp = vtotal.file_report("scan_id,HASH,scan_id,HASH")
# Retrieve scan report(s) for given file(s) from Virustotal.
# A list containing the resource (SHA256) HASH of a known malicious file.
resp = vtotal.file_report(
["9f101483662fc071b7c10f81c64bb34491ca4a877191d464ff46fd94c7247115"]
)
# A list of resource(s). Can be `md5/sha1/sha256 hashes` and/or combination of hashes and scan_ids (MAX 4 per standard request rate).
# The first is a scan_id, the second is a SHA256 HASH.
resp = vtotal.file_report(
[
"75efd85cf6f8a962fe016787a7f57206ea9263086ee496fc62e3fc56734d4b53-1555351539",
"9f101483662fc071b7c10f81c64bb34491ca4a877191d464ff46fd94c7247115",
]
)

# Query url(s) to VirusTotal.
resp = vtotal.url_scan("ihaveaproblem.info") # Query a single url.
resp = vtotal.url_scan("ihaveaproblem.info\ngoogle.com\nwikipedia.com\ngithub.com") # Query multiple url(s) seperated by "\n" character.
# A list containing a url to be scanned by VirusTotal.
resp = vtotal.url_scan(["ihaveaproblem.info"]) # Query a single url.
# A list of url(s) to be scanned by VirusTotal (MAX 4 per standard request rate).
resp = vtotal.url_scan(
["ihaveaproblem.info", "google.com", "wikipedia.com", "github.com"]
)

# Retrieve report(s)
resp = vtotal.url_report("ihaveaproblem.info") # Query a single url.
resp = vtotal.url_report("ihaveaproblem.info\ngoogle.com\nwikipedia.com\ngithub.com", scan="1") # Get the report(s) for a url(s), scan_id(s).
# Retrieve url report(s)
# A list containing the url of the report to be retrieved.
resp = vtotal.url_report(["ihaveaproblem.info"]) # Query a single url.
# A list of the url(s) and/or scan_id(s) report(s) to be retrieved (MAX 4 per standard request rate).
# The first object in the list is a scan_id.
resp = vtotal.url_report(
[
"fd21590d9df715452c8c000e1b5aa909c7c5ea434c2ddcad3f4ccfe9b0ee224e-1555352750",
"google.com",
"wikipedia.com",
"github.com",
],
scan="1",
)

# Query an IP to Virustotal.
resp = vtotal.ipaddress_report("90.156.201.27")
Expand All @@ -33,4 +66,9 @@
resp = vtotal.domain_report("027.ru")

# Put a comment onto a specific resource.
resp = vtotal.put_comment("ihaveaproblem.info", comment="This website is flagged by a few scanners as malicious! #watchout")
resp = vtotal.put_comment(
"9f101483662fc071b7c10f81c64bb34491ca4a877191d464ff46fd94c7247115",
comment="#watchout, this looks very malicious!",
)

pprint(resp)
28 changes: 14 additions & 14 deletions virustotal_python/virustotal.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ class Virustotal(object):
def __init__(self, API_KEY=None):
self.API_KEY = API_KEY
self.BASEURL = "https://www.virustotal.com/vtapi/v2/"
self.VERSION = "0.0.1"
self.VERSION = "0.0.2"
self.headers = {
"Accept-Encoding": "gzip, deflate",
"User-Agent": f"gzip, virustotal-python {self.VERSION}",
Expand All @@ -55,46 +55,46 @@ def file_scan(self, file):
resp = self.make_request(f"{self.BASEURL}file/scan", params=params, files=files)
return resp

def file_rescan(self, resource):
def file_rescan(self, *resource: list):
"""
Resend a file to Virustotal for analysis. (https://www.virustotal.com/en/documentation/public-api/#rescanning-files)
:param resource: The resource of the specified file. Can be an `md5/sha1/sha256 hash` or CSV list made up of a combination of any of the three allowed hashes (MAX 25 items).
:param *resource: A list of resource(s) of a specified file(s). Can be `md5/sha1/sha256 hashes`. Can be a combination of any of the three allowed hashes (MAX 25 items).
:rtype: A dictionary containing the resp_code and JSON response.
"""
params = {"apikey": self.API_KEY, "resource": resource}
params = {"apikey": self.API_KEY, "resource": ",".join(*resource)}
resp = self.make_request(f"{self.BASEURL}file/rescan", params=params)
return resp

def file_report(self, resource):
def file_report(self, *resource: list):
"""
Retrieve scan report(s) for a given file from Virustotal. (https://www.virustotal.com/en/documentation/public-api/#getting-file-scans)
:param resource: The `md5/sha1/sha256 hash` of the file or CSV list made up of a combination of hashes and scan_ids (MAX 4 items).
:param *resource: A list of resource(s) of a specified file(s). Can be `md5/sha1/sha256 hashes` and/or combination of hashes and scan_ids (MAX 4 per standard request rate).
:rtype: A dictionary containing the resp_code and JSON response.
"""
params = {"apikey": self.API_KEY, "resource": resource}
params = {"apikey": self.API_KEY, "resource": ",".join(*resource)}
resp = self.make_request(
f"{self.BASEURL}file/report", params=params, method="GET"
)
return resp

def url_scan(self, url):
def url_scan(self, *url: list):
"""
Send url(s) to Virustotal. (https://www.virustotal.com/en/documentation/public-api/#scanning-urls)
:param url: The url(s) to be scanned. Also accepts a list of urls (MAX 4); urls must be separated by a new line character.
:param *url: A list of url(s) to be scanned. (MAX 4 per standard request rate).
:rtype: A dictionary containing the resp_code and JSON response.
"""
params = {"apikey": self.API_KEY, "url": url}
params = {"apikey": self.API_KEY, "url": "\n".join(*url)}
resp = self.make_request(f"{self.BASEURL}url/scan", params=params)
return resp

def url_report(self, resource, scan=None):
def url_report(self, *resource: list, scan=None):
"""
Retrieve scan report(s) for a given url(s) (https://www.virustotal.com/en/documentation/public-api/#getting-url-scans)
:param resource: The url(s) of the given report to be retrieved or scan_id or a CSV list made up of scan_ids or urls (MAX 4); the scan_ids or urls `must` be separated by a new line character.
:param scan: An optional parameter. When set to "1" will automatically submit the URL for analysis if no report is found for it in VirusTotal's database.
:param *resource: A list of the url(s) and/or scan_id(s) report(s) to be retrieved (MAX 4 per standard request rate).
:param scan: An optional parameter. When set to "1" it will automatically submit the URL for analysis if no report is found for it in VirusTotal's database.
:rtype: A dictionary containing the resp_code and JSON response.
"""
params = {"apikey": self.API_KEY, "resource": resource}
params = {"apikey": self.API_KEY, "resource": "\n".join(*resource)}
if scan is not None:
params["scan"] = scan
resp = self.make_request(f"{self.BASEURL}url/report", params=params)
Expand Down

0 comments on commit 521af78

Please sign in to comment.