Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 66 additions & 9 deletions lib/utils/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
import sys
import tempfile
import time
import urllib2
from pprint import pformat

from lib.core.common import unArrayizeValue
from lib.core.convert import base64pickle
Expand All @@ -31,6 +33,7 @@
from lib.core.optiondict import optDict
from lib.core.settings import IS_WIN
from lib.core.subprocessng import Popen
from lib.parse.cmdline import cmdLineParser
from thirdparty.bottle.bottle import error as return_error
from thirdparty.bottle.bottle import get
from thirdparty.bottle.bottle import hook
Expand Down Expand Up @@ -640,18 +643,72 @@ def server(host="0.0.0.0", port=RESTAPI_SERVER_PORT):
run(host=host, port=port, quiet=True, debug=False)


def _cpost(url, data=None):
logger.debug("Calling " + url)
try:
if data is not None:
data = jsonize(data)
req = urllib2.Request(url, data, {'Content-Type': 'application/json'})
response = urllib2.urlopen(req)
text = dejsonize(response.read())
except:
logger.error("Failed to load and parse " + url)
raise
return text


def client(host=RESTAPI_SERVER_HOST, port=RESTAPI_SERVER_PORT):
"""
REST-JSON API client
"""
help_message = ("Available commands:\nhelp\nnew: start a new scan\n"
"use TASKID: run task commands for this task\n"
"data, log, status: task commands\nexit")
addr = "http://%s:%d" % (host, port)
logger.info("Starting REST-JSON API client to '%s'..." % addr)

# TODO: write a simple client with requests, for now use curl from command line
logger.error("Not yet implemented, use curl from command line instead for now, for example:")
print "\n\t$ taskid=$(curl http://%s:%d/task/new 2>1 | grep -o -I '[a-f0-9]\{16\}') && echo $taskid" % (host, port)
print ("\t$ curl -H \"Content-Type: application/json\" "
"-X POST -d '{\"url\": \"http://testphp.vulnweb.com/artists.php?artist=1\"}' "
"http://%s:%d/scan/$taskid/start") % (host, port)
print "\t$ curl http://%s:%d/scan/$taskid/data" % (host, port)
print "\t$ curl http://%s:%d/scan/$taskid/log\n" % (host, port)
logger.info(help_message)

taskid = ''
while True:
command = raw_input('>>> ').strip()
if command in ('data', 'log', 'status'):
if taskid == '':
logger.error("No task id in use")
continue
res = _cpost(addr + '/scan/' + taskid + '/' + command)
if not res['success']:
logger.error("Failed to execute command " + command)
logger.info(pformat(res, width=1))
elif command == 'new':
command = raw_input('Give sqlmap parameters e.g.: -u http://testphp.vulnweb.com/artists.php?artist=1 -o\n>>> ').strip()
# new task
res = _cpost(addr + '/task/new')
if not res['success']:
logger.error("Failed to create task")
continue
taskid = res['taskid']
logger.info('Task ID is ' + taskid)

# start scan
original_argv = sys.argv
sys.argv = [sys.argv[0]] + command.split()
try:
d = cmdLineParser().__dict__
except:
continue
d = {k: v for k, v in d.iteritems() if v is not None}
sys.argv = original_argv
res = _cpost(addr + '/scan/' + taskid + '/start', d)
if not res['success']:
logger.error("Failed to start scan")
continue
logger.info("Scanning started")
elif command[0:3] == 'use':
taskid = command.split()[1].strip()
logger.info("Task ID is now " + taskid)
elif command in ('exit', 'bye', 'quit'):
return
elif command in ('help', '?'):
logger.info(help_message)
else:
logger.error("Unknown command")