HTTP Interfaces¶
Viper has two HTTP Components that can optionally be enabled alongside the console access.
- REST based API interface
- Web interface
The first one can be used to easily integrate Viper with other tools, while the second one provides an user-friendly alternative to the traditional command-line interface.
Security Considerations¶
Beware that Viper does not provide any security mechanism to protect neither of the HTTP interfaces. Enabling either interface access to the Internet would severely expose the security of your system, as users are able not only to access and operate on your Viper repositories, but also execute commands on the hosting system.
Make sure you take all necessary precautions to implement authentication and encryption whenever necessary through the tools provided by your firewall and web server.
API¶
Viper provides a REST-based API interface through which you can operate on the repositories as well as execute almost all functions that you would normally get through the command-line interface.
To start the API:
user@system:~/$ viper-api
Bottle server starting up (using WSGIRefServer())...
Listening on http://127.0.0.1:8080/
Hit Ctrl-C to quit.
You can bind it on a different IP and port by providing additional options:
usage: viper-api [-h] [-H HOST] [-p PORT]
optional arguments:
-h, --help show this help message and exit
-H HOST, --host HOST Host to bind the API server on
-p PORT, --port PORT Port to bind the API server on
The API commands will provide JSON results. Following ou can find details on the commands available.
/test¶
GET /test
Test the API server.
Example request:
curl http://127.0.0.1:8080/testExample response:
{ "message": "test" }Parameters:
- None
Status codes:
200
- no errors
/file/add¶
POST /file/add
Submit a file to Viper.
Example request:
curl -F file=@FILE -F tags='foo,bar' -X POST http://127.0.0.1:8080/file/addExample response:
{ "message": "added" }Parameters:
tags
: comma separated list of tagsfile
: path to the file to submitStatus codes:
200
- no errors500
- something failed when adding the file
/file/add_url¶
POST /file/add_url
Submit a url to Viper.
Example request:
curl -F url='http://google.com' -F tags='foo,bar' -F tor='true' -X POST http://127.0.0.1:8080/file/add_urlExample response:
{ "message": "added" "sha256": "a28a9ca63e8460b03dff84b5645c6c2a30f48149c0e5b273525cf4b80fe8a8ca" }Parameters:
url
: url of the file to downloadtags
: comma separated list of tagstor
: if a value is set, tor will be used to download the fileStatus codes:
200
- no errors500
- something failed when adding the file
/file/get¶
GET /file/get/ (str: MD5 or SHA256 hash)
Retrieve a file from Viper.
Example request:
curl http://127.0.0.1:8080/file/get/9ce49435b67d531bbd966186920c90ecf0752e88b79af246886b077c8ec9b649Parameters:
hash
: MD5 or SHA256 hash of the file to retrieveStatus codes:
200
- no error400
- you did not provide a valid hash (MD5 or SHA256)404
- file not found
/file/delete¶
GET /file/delete/ (str: MD5 or SHA256 hash)
Delete file from Viper.
Example request:
Example response:
{ "message": "deleted" }Status codes:
200
- no error400
- invalid hash format404
- file not found500
- unable to delete file
/file/find¶
POST /file/find
Find a file in Viper default repository or project
Example request:
curl -F tag=rat http://127.0.0.1:8080/file/findExample response:
{ "default": [ { "sha1": "13da502ab0d75daca5e5075c60e81bfe3b7a637f", "name": "darkcomet.exe", "tags": [ "rat", "darkcomet" ], "sha512": "7e81e0c4f49f1884ebebdf6e53531e7836721c2ae41729cf5bc0340f3369e7d37fe4168a7434b2b0420b299f5c1d9a4f482f1bda8e66e40345757d97e5602b2d", "created_at": "2015-03-30 23:13:20.595238", "crc32": "2238B48E", "ssdeep": "12288:D9HFJ9rJxRX1uVVjoaWSoynxdO1FVBaOiRZTERfIhNkNCCLo9Ek5C/hlg:NZ1xuVVjfFoynPaVBUR8f+kN10EB/g", "sha256": "2d79fcc6b02a2e183a0cb30e0e25d103f42badda9fbf86bbee06f93aa3855aff", "type": "PE32 executable (GUI) Intel 80386, for MS Windows", "id": 10, "md5": "9f2520a3056543d49bb0f822d85ce5dd", "size": 774144 }, { "sha1": "dbcea714f43aa06a7f1c3d11cbfd67e4f8e0c23e", "name": "poisonivy3.exe", "tags": [ "rat", "poisonivy" ], "sha512": "4b2d61211b059400d5f8701908c6f4cb25a70a44882c67f887301dfc3e02d29b562032fc11333cca29f8bb9a31f0b4679760b0161a63cfc848da1e718dadcd58", "created_at": "2015-03-30 23:13:20.595238", "crc32": "BCD8287D", "ssdeep": "3072:lR+yF1aa8hCqTevS0IjhAPCoGm3vkazsW2mq:lR+KrWCqavSFhmCoGm3h0mq", "sha256": "15846af22582f06fde215a0e506fdf5f88d3262b3d62d1eabd6bdf00f91e0df7", "type": "PE32 executable (GUI) Intel 80386 (stripped to external PDB), for MS Windows", "id": 28, "md5": "23c3b61ecdff3d67479d70b5d4d91dea", "size": 143560 }, ... ] }Parameters:
md5
: search by MD5sha256
: search by SHA256ssdeep
: search by ssdeeptag
: search by tagname
: search by nameall
: retrieve all fileslatest
: retrieve only the most recently added files (specify 1 as the value)project
: a project name to search the file in (default is none, you can also specify “all” to search across all projects)Status codes:
200
- no error400
- invalid search term
/file/tags/add¶
POST /file/tags/add
Add one or more tags to one or more files
Example request:
curl -F tags=foo,bar -F md5=23c3b61ecdff3d67479d70b5d4d91dea http://127.0.0.1/file/tags/addExample response:
{ "message": "added" }Parameters:
tags
: comma-separated list of tagsmd5
: select by MD5sha256
: select by SHA256ssdeep
: select by ssdeeptag
: select by tagname
: select by nameall
: retrieve all fileslatest
: retrieve only the most recently added filesStatus codes:
200
- no error404
- file not found
/tags/list¶
GET /tags/list
Retrieve a list of all tags
Example request:
curl http://127.0.0.1:8080/tags/listExample response:
[ "rat", "darkcomet", "poisonivy", "njrat", "embedded_win_api", "nettraveler", "xtreme" ]Status codes:
200
- no error#
/file/notes/add¶
POST /file/notes/add
Add a note to a sample
Parameters:
sha256
: select by SHA256title
: title of the notebody
: body of the noteExample request:
curl http://127.0.0.1 -F sha256="2e766eabed666510a385544b79a5d344b48a2de2040c62fee9addb19c554ed4c" -F title="asd" -F body="bodddy" http://127.0.0.1:8080/file/notes/addExample response:
{ "message": "Note added" }Status codes:
200
- no error
/file/notes/view¶
POST /file/notes/view
Retrieve a list of all notes
Example request:
curl -F sha256="2e766eabed666510a385544b79a5d344b48a2de2040c62fee9addb19c554ed4c" http://127.0.0.1:8080/file/notes/viewExample response:
{ "message": { "1": { "body": "bodddy", "title": "asd" } } }Status codes:
200
- no error
/file/notes/update¶
POST /file/notes/update
Updates a note from a sample
Parameters:
sha256
: select by SHA256title
: title of the notebody
: body of the noteid
: id of the noteExample request:
curl http://127.0.0.1 -F sha256="2e766eabed666510a385544b79a5d344b48a2de2040c62fee9addb19c554ed4c" -F title="asd" -F id="1" -F body="bodddy" http://127.0.0.1:8080/file/notes/updateExample response:
{ "message": "Note updated" }Status codes:
200
- no error
/file/notes/delete¶
POST /file/notes/delete
Delete a note from a sample
Parameters:
sha256
: select by SHA256id
: id of the noteExample request:
curl http://127.0.0.1 -F sha256="2e766eabed666510a385544b79a5d344b48a2de2040c62fee9addb19c554ed4c" -F id="1" http://127.0.0.1:8080/file/notes/deleteExample response:
{ "message": "Note deleted" }Status codes:
200
- no error
/projects/list¶
GET /projects/list
Retrieve a list of all projects
Example request:
curl http://127.0.0.1:8080/projects/listExample response:
[ "project1", "project2", "project3" ]Status codes:
200
- no error404
- no projects found
/modules/run¶
POST /modules/run
Execute a command
Example request:
curl -F sha256=d5042d68b813d5c45c03fe6883f5b83ff079cb9c394ddcc9c84f58e0369c6cdf -F cmdline="pe compiletime" http://127.0.0.1:8080/modules/runExample response:
[{'data': 'Compile Time: \\x1b[1m1992-06-20 00:22:17\\x1b[0m', 'type': 'info'}]Parameters:
project
: project namesha256
: SHA256 hash of the file to execute the command oncmdline
: the full command line as you would normally pass to the CLIStatus codes:
200
- no error404
- invalid command line
Web Interface¶
Viper comes with a basic single threaded HTML Browser interface that can run alongside the command-line interface and API. Its main features are:
- Project Switching / Creation
- Multiple File Upload
- File Download
- Unpack Compressed uploads
- Full Search (including tag, name, mime, note, type)
- Hex Viewer
- Run Modules
- Enter Notes
- Add / Delete / Modify Yara rules
- Add / Delete / Modify Tags
Launch the web interface¶
To launch the web application move into the viper directory and run the web.py
script.
By default it launches a single threaded bottle web server on localhost:9090:
user@localhost:~/$ viper-web
Bottle v0.12.8 server starting up (using WSGIRefServer())...
Listening on http://localhost:9090/
Hit Ctrl-C to quit.
You can set the listening IP address and port with options -H and -p
user@localhost:~/$ viper-web -H 0.0.0.0 -p 8080
Bottle v0.12.8 server starting up (using WSGIRefServer())...
Listening on http://0.0.0.0:8080/
Hit Ctrl-C to quit.
Use viper in a (web) production environment¶
In production use, its often not recommended to use the default Bottle WSGIRefServer as it can be quite slow and requires manual start.
A dedicated webserver that serves pages on standard ports and with a standardized configuration is possible with viper, but requires some additional setup To make this work, we are using uwsgi and nginx as stack.
To use nginx as the webserver serving web.py,:
$ sudo apt-get remove apache2 #avoid conflicts
$ sudo apt-get install nginx-full uwsgi uwsgi-plugin-python
Move (or copy) the source to the web directory and make sure the permissions match
$ sudo mv viper-* /srv/www/viper
$ chown -R www-data:www-data /srv/www/viper
Change the VIPER_ROOT variable in web.py to reflect your installation.:
$ sudo vi /srv/www/viper/web.py
Modify the user section, and uncomment and change the following line to reflect your environment:
VIPER_ROOT ='/srv/www/viper'
Create a file /etc/uwsgi/apps-available/bottle.ini:
[uwsgi]
socket = /run/uwsgi/app/bottle/socket
chdir = /srv/www/viper/
master = true
plugins = python
file = web.py
uid = www-data
gid = www-data
Link the /etc/uwsgi/apps-available/bottle.ini file to apps-enabled:
$ sudo ln -s /etc/uwsgi/apps-available/bottle.ini /etc/uwsgi/apps-enabled/bottle.ini
Restart nginx and uwsgi:
$ sudo service nginx restart
$ sudo service uwsgi restart
Tail the uwsgi logfile to make sure everything works ok:
$ tail -f /var/log/uwsgi/app/bottle.log
And browse to the default port 80 interface of the webserver. You should be greeted with the viper webpage.
Setting up SSL and web-based authentication is out of scope for this document, but infromation can be found in the nginx manual and in one of the many tutorials on the web.