Commit 79487957 authored by Benjamin "Ziirish" SANS's avatar Benjamin "Ziirish" SANS
Browse files

add: tools to help setup burp and burp-ui

parent 225bc6f5
...@@ -20,6 +20,8 @@ following informations: ...@@ -20,6 +20,8 @@ following informations:
- Any piece of configuration that might help understand/reproduce the problem - Any piece of configuration that might help understand/reproduce the problem
- Any other information that you may find useful such as screenshots, etc. - Any other information that you may find useful such as screenshots, etc.
**WARNING**: be sure to remove any sensitive data from your logs/configurations.
Thanks Thanks
Below is an example of a expected bug report: Below is an example of a expected bug report:
...@@ -41,18 +43,14 @@ $ burp -v ...@@ -41,18 +43,14 @@ $ burp -v
burp-2.0.54 burp-2.0.54
``` ```
# Burp-UI # Sysinfo
```
$ burp-ui -V -v
burp-ui: v0.4.0 (stable)
```
# Python
``` ```
$ python --version $ bui-manage sysinfo
Python 3.6.0 Python version: 3.6.1
Burp-UI version: 0.5.0 (stable)
Single mode: True
Backend version: 2
``` ```
# Steps to reproduce # Steps to reproduce
...@@ -66,27 +64,27 @@ Python 3.6.0 ...@@ -66,27 +64,27 @@ Python 3.6.0
``` ```
10.0.0.100 - - [11/Apr/2017 15:10:31] "POST /login?next=%2F HTTP/1.1" 500 - 10.0.0.100 - - [11/Apr/2017 15:10:31] "POST /login?next=%2F HTTP/1.1" 500 -
Traceback (most recent call last): Traceback (most recent call last):
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1994, in __call__ File "/usr/local/lib/python3.6/dist-packages/flask/app.py", line 1994, in __call__
return self.wsgi_app(environ, start_response) return self.wsgi_app(environ, start_response)
File "/opt/workspace/burp-ui/burpui/utils.py", line 412, in __call__ File "/opt/workspace/burp-ui/burpui/utils.py", line 412, in __call__
return self.wsgi_app(environ, start_response) return self.wsgi_app(environ, start_response)
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1985, in wsgi_app File "/usr/local/lib/python3.6/dist-packages/flask/app.py", line 1985, in wsgi_app
response = self.handle_exception(e) response = self.handle_exception(e)
File "/usr/local/lib/python2.7/dist-packages/flask_restplus/api.py", line 557, in error_router File "/usr/local/lib/python3.6/dist-packages/flask_restplus/api.py", line 557, in error_router
return original_handler(e) return original_handler(e)
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1540, in handle_exception File "/usr/local/lib/python3.6/dist-packages/flask/app.py", line 1540, in handle_exception
reraise(exc_type, exc_value, tb) reraise(exc_type, exc_value, tb)
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1982, in wsgi_app File "/usr/local/lib/python3.6/dist-packages/flask/app.py", line 1982, in wsgi_app
response = self.full_dispatch_request() response = self.full_dispatch_request()
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1614, in full_dispatch_request File "/usr/local/lib/python3.6/dist-packages/flask/app.py", line 1614, in full_dispatch_request
rv = self.handle_user_exception(e) rv = self.handle_user_exception(e)
File "/usr/local/lib/python2.7/dist-packages/flask_restplus/api.py", line 557, in error_router File "/usr/local/lib/python3.6/dist-packages/flask_restplus/api.py", line 557, in error_router
return original_handler(e) return original_handler(e)
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1517, in handle_user_exception File "/usr/local/lib/python3.6/dist-packages/flask/app.py", line 1517, in handle_user_exception
reraise(exc_type, exc_value, tb) reraise(exc_type, exc_value, tb)
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1612, in full_dispatch_request File "/usr/local/lib/python3.6/dist-packages/flask/app.py", line 1612, in full_dispatch_request
rv = self.dispatch_request() rv = self.dispatch_request()
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1598, in dispatch_request File "/usr/local/lib/python3.6/dist-packages/flask/app.py", line 1598, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args) return self.view_functions[rule.endpoint](**req.view_args)
File "/opt/workspace/burp-ui/burpui/routes.py", line 409, in login File "/opt/workspace/burp-ui/burpui/routes.py", line 409, in login
user = bui.uhandler.user(form.username.data, refresh) user = bui.uhandler.user(form.username.data, refresh)
...@@ -96,29 +94,29 @@ Traceback (most recent call last): ...@@ -96,29 +94,29 @@ Traceback (most recent call last):
return self.session_expired_by_id(self.get_session_id()) return self.session_expired_by_id(self.get_session_id())
File "/opt/workspace/burp-ui/burpui/sessions.py", line 47, in session_expired_by_id File "/opt/workspace/burp-ui/burpui/sessions.py", line 47, in session_expired_by_id
store = Session.query.filter_by(uuid=id).first() store = Session.query.filter_by(uuid=id).first()
File "/usr/local/lib/python2.7/dist-packages/sqlalchemy/orm/query.py", line 2697, in first File "/usr/local/lib/python3.6/dist-packages/sqlalchemy/orm/query.py", line 2697, in first
ret = list(self[0:1]) ret = list(self[0:1])
File "/usr/local/lib/python2.7/dist-packages/sqlalchemy/orm/query.py", line 2489, in __getitem__ File "/usr/local/lib/python3.6/dist-packages/sqlalchemy/orm/query.py", line 2489, in __getitem__
return list(res) return list(res)
File "/usr/local/lib/python2.7/dist-packages/sqlalchemy/orm/query.py", line 2797, in __iter__ File "/usr/local/lib/python3.6/dist-packages/sqlalchemy/orm/query.py", line 2797, in __iter__
return self._execute_and_instances(context) return self._execute_and_instances(context)
File "/usr/local/lib/python2.7/dist-packages/sqlalchemy/orm/query.py", line 2820, in _execute_and_instances File "/usr/local/lib/python3.6/dist-packages/sqlalchemy/orm/query.py", line 2820, in _execute_and_instances
result = conn.execute(querycontext.statement, self._params) result = conn.execute(querycontext.statement, self._params)
File "/usr/local/lib/python2.7/dist-packages/sqlalchemy/engine/base.py", line 945, in execute File "/usr/local/lib/python3.6/dist-packages/sqlalchemy/engine/base.py", line 945, in execute
return meth(self, multiparams, params) return meth(self, multiparams, params)
File "/usr/local/lib/python2.7/dist-packages/sqlalchemy/sql/elements.py", line 263, in _execute_on_connection File "/usr/local/lib/python3.6/dist-packages/sqlalchemy/sql/elements.py", line 263, in _execute_on_connection
return connection._execute_clauseelement(self, multiparams, params) return connection._execute_clauseelement(self, multiparams, params)
File "/usr/local/lib/python2.7/dist-packages/sqlalchemy/engine/base.py", line 1053, in _execute_clauseelement File "/usr/local/lib/python3.6/dist-packages/sqlalchemy/engine/base.py", line 1053, in _execute_clauseelement
compiled_sql, distilled_params compiled_sql, distilled_params
File "/usr/local/lib/python2.7/dist-packages/sqlalchemy/engine/base.py", line 1189, in _execute_context File "/usr/local/lib/python3.6/dist-packages/sqlalchemy/engine/base.py", line 1189, in _execute_context
context) context)
File "/usr/local/lib/python2.7/dist-packages/sqlalchemy/engine/base.py", line 1393, in _handle_dbapi_exception File "/usr/local/lib/python3.6/dist-packages/sqlalchemy/engine/base.py", line 1393, in _handle_dbapi_exception
exc_info exc_info
File "/usr/local/lib/python2.7/dist-packages/sqlalchemy/util/compat.py", line 202, in raise_from_cause File "/usr/local/lib/python3.6/dist-packages/sqlalchemy/util/compat.py", line 202, in raise_from_cause
reraise(type(exception), exception, tb=exc_tb, cause=cause) reraise(type(exception), exception, tb=exc_tb, cause=cause)
File "/usr/local/lib/python2.7/dist-packages/sqlalchemy/engine/base.py", line 1182, in _execute_context File "/usr/local/lib/python3.6/dist-packages/sqlalchemy/engine/base.py", line 1182, in _execute_context
context) context)
File "/usr/local/lib/python2.7/dist-packages/sqlalchemy/engine/default.py", line 469, in do_execute File "/usr/local/lib/python3.6/dist-packages/sqlalchemy/engine/default.py", line 469, in do_execute
cursor.execute(statement, parameters) cursor.execute(statement, parameters)
OperationalError: (sqlite3.OperationalError) no such table: session [SQL: u'SELECT session.id AS session_id, session.uuid AS session_uuid, session.user AS session_user, session.ip AS session_ip, session.ua AS session_ua, session.timestamp AS session_timestamp, session.expire AS session_expire, session.permanent AS session_permanent, session.api AS session_api \nFROM session \nWHERE session.uuid = ?\n LIMIT ? OFFSET ?'] [parameters: (u'ae350427-99f4-4592-94ec-6f6a27aee59f', 1, 0)] OperationalError: (sqlite3.OperationalError) no such table: session [SQL: u'SELECT session.id AS session_id, session.uuid AS session_uuid, session.user AS session_user, session.ip AS session_ip, session.ua AS session_ua, session.timestamp AS session_timestamp, session.expire AS session_expire, session.permanent AS session_permanent, session.api AS session_api \nFROM session \nWHERE session.uuid = ?\n LIMIT ? OFFSET ?'] [parameters: (u'ae350427-99f4-4592-94ec-6f6a27aee59f', 1, 0)]
``` ```
...@@ -132,7 +130,7 @@ version = 1 ...@@ -132,7 +130,7 @@ version = 1
# Handle multiple bui-servers or not # Handle multiple bui-servers or not
# If set to 'false', you will need to declare at least one 'Agent' section (see # If set to 'false', you will need to declare at least one 'Agent' section (see
# bellow) # bellow)
single = false single = true
# authentication plugin (mandatory) # authentication plugin (mandatory)
# list the misc/auth directory to see the available backends # list the misc/auth directory to see the available backends
# to disable authentication you can set "auth: none" # to disable authentication you can set "auth: none"
......
...@@ -17,8 +17,7 @@ from .app import create_app ...@@ -17,8 +17,7 @@ from .app import create_app
ROOT = os.path.dirname(os.path.realpath(__file__)) ROOT = os.path.dirname(os.path.realpath(__file__))
DEBUG = os.environ.get('BUI_DEBUG') or os.environ.get('FLASK_DEBUG') or False DEBUG = os.environ.get('BUI_DEBUG') or os.environ.get('FLASK_DEBUG') or False
if DEBUG and DEBUG.lower() in ['true', 'yes', '1']: DEBUG = DEBUG and DEBUG.lower() in ['true', 'yes', '1']
DEBUG = True
VERBOSE = os.environ.get('BUI_VERBOSE') or 0 VERBOSE = os.environ.get('BUI_VERBOSE') or 0
if VERBOSE: if VERBOSE:
...@@ -616,3 +615,295 @@ password = abcdefgh ...@@ -616,3 +615,295 @@ password = abcdefgh
fg='yellow' fg='yellow'
) )
) )
@app.cli.command()
@click.option('-c', '--client', default='bui',
help='Name of the burp client that will be used by Burp-UI '
'(defaults to "bui")')
@click.option('-h', '--host', default='::1',
help='Address of the status server (defaults to "::1")')
@click.option('-t', '--tips', is_flag=True,
help='Show you some tips')
def diag(client, host, tips):
"""Check Burp-UI is correctly setup"""
if app.vers != 2:
click.echo(
click.style(
'Sorry, you can only setup the Burp 2 client',
fg='red'
),
err=True
)
sys.exit(1)
if not app.standalone:
click.echo(
click.style(
'Sorry, only the standalone mode is supported',
fg='red'
),
err=True
)
sys.exit(1)
app.load_modules(False)
from .misc.parser.utils import Config
from .app import get_redis_server
if 'Production' in app.conf.options and \
'redis' in app.conf.options['Production']:
try:
# detect missing modules
import redis as redis_client # noqa
import celery # noqa
import socket
rhost, rport, _ = get_redis_server(app)
ret = -1
for res in socket.getaddrinfo(rhost, rport, socket.AF_UNSPEC, socket.SOCK_STREAM):
if ret == 0:
break
af, socktype, proto, _, sa = res
try:
s = socket.socket(af, socktype, proto)
except socket.error:
continue
try:
ret = s.connect_ex(sa)
except:
continue
if ret != 0:
click.echo(
click.style(
'Unable to contact the redis server, disabling it',
fg='yellow'
)
)
except ImportError:
click.echo(
click.style(
'Unable to activate redis & celery. Did you ran the '
'\'pip install burp-ui[celery]\' and '
'\'pip install burp-ui[gunicorn-extra]\' commands first?',
fg='yellow'
)
)
if 'Production' in app.conf.options and \
'database' in app.conf.options['Production']:
try:
from .ext.sql import db # noqa
except ImportError:
click.echo(
click.style(
'It looks like some dependencies are missing. Did you ran '
'the \'pip install "burp-ui[sql]"\' command first?',
fg='yellow'
)
)
bconfcli = app.conf.options.get('Burp2', {}).get('bconfcli') or \
getattr(app.client, 'burpconfcli')
bconfsrv = app.conf.options.get('Burp2', {}).get('bconfsrv') or \
getattr(app.client, 'burpconfsrv')
errors = False
if os.path.exists(bconfcli):
parser = app.client.get_parser()
confcli = Config(bconfcli, parser, 'srv')
confcli.set_default(bconfcli)
confcli.parse()
if confcli.get('cname') != client:
click.echo(
click.style(
'The cname of your burp client does not match: '
'{} != {}'.format(confcli.get('cname'), client),
fg='yellow'
)
)
errors = True
if confcli.get('server') != host:
click.echo(
click.style(
'The burp server address does not match: '
'{} != {}'.format(confcli.get('server'), host),
fg='yellow'
)
)
errors = True
else:
click.echo(
click.style(
'No client conf file found: {} does not exist'.format(bconfcli),
fg='red'
),
err=True
)
errors = True
if os.path.exists(bconfsrv):
confsrv = Config(bconfsrv, parser, 'srv')
confsrv.set_default(bconfsrv)
confsrv.parse()
if host not in ['::1', '127.0.0.1']:
bind = confsrv.get('status_address')
if (bind and bind not in [host, '::', '0.0.0.0']) or not bind:
click.echo(
click.style(
'It looks like your burp server is not exposing it\'s '
'status port in a way that is reachable by Burp-UI!',
fg='yellow'
)
)
click.echo(
click.style(
'You may want to set the \'status_address\' setting with '
'either \'{}\', \'::\' or \'0.0.0.0\' in the {} file '
'in order to make Burp-UI work'.format(host, bconfsrv),
fg='blue'
)
)
max_status_children = confsrv.get('max_status_children', -1)
if 'max_status_children' not in confsrv or max_status_children < 15:
click.echo(
click.style(
'\'max_status_children\' is to low, you need to set it to '
'15 or more. Please edit your {} file'.format(bconfsrv),
fg='blue'
)
)
errors = True
restore = []
if 'restore_client' in confsrv:
restore = confsrv.getlist('restore_client')
if client not in restore:
click.echo(
click.style(
'Your burp client is not listed as a \'restore_client\'. '
'You won\'t be able to view other clients stats!',
fg='yellow'
)
)
errors = True
if 'monitor_browse_cache' not in confsrv or not \
confsrv.get('monitor_browse_cache'):
click.echo(
click.style(
'For performance reasons, it is recommanded to enable the '
'\'monitor_browse_cache\'',
fg='yellow'
)
)
errors = True
ca_client_dir = confsrv.get('ca_csr_dir')
if ca_client_dir and not os.path.exists(ca_client_dir):
try:
os.makedirs(ca_client_dir)
except IOError as exp:
click.echo(
click.style(
'Unable to create "{}" dir: {}'.format(ca_client_dir, exp),
fg='yellow'
),
err=True
)
if confsrv.get('clientconfdir'):
bconfagent = os.path.join(confsrv.get('clientconfdir'), client)
else:
click.echo(
click.style(
'Unable to find "clientconfdir" option. Something is wrong '
'with your setup',
fg='yellow'
)
)
bconfagent = 'ihopethisfiledoesnotexistbecauseitisrelatedtoburpui'
if not os.path.exists(bconfagent) and bconfagent.startswith('/'):
click.echo(
click.style(
'Unable to find the {} file'.format(bconfagent),
fg='yellow'
)
)
errors = True
else:
confagent = Config(bconfagent, parser, 'cli')
confagent.set_default(bconfagent)
confagent.parse()
if confagent.get('password') != confcli.get('password'):
click.echo(
click.style(
'It looks like the passwords in the {} and the {} files '
'mismatch. Burp-UI will not work properly until you fix '
'this'.format(bconfcli, bconfagent),
fg='yellow'
)
)
else:
click.echo(
click.style(
'Unable to locate burp-server configuration: {} does not '
'exist'.format(bconfsrv),
fg='red'
),
err=True
)
errors = True
if errors:
if not tips:
click.echo(
click.style(
'Some errors have been found in your configuration. '
'Please make sure you ran this command with the right flags! '
'(see --help for details)'.format(sys.argv[0], sys.argv[1]),
fg='red'
),
err=True
)
else:
click.echo(
click.style(
'Well, if you are sure about your settings, you can run the '
'following command to help you setup your Burp-UI agent. '
'(Note, the \'--dry\' flag is here to show you the '
'modifications that will be applied. Once you are OK with '
'those, you can re-run the command without the \'--dry\' flag):',
fg='blue'
)
)
click.echo(' > bui-manage setup_burp --host="{}" --client="{}" --dry'.format(host, client))
else:
click.echo(
click.style(
'Congratulations! It seems everything is alright. Burp-UI '
'should run without any issue now.',
fg='green'
)
)
@app.cli.command()
def sysinfo():
"""Returns a couple of system informations to help debugging"""
from .app import __release__, __version__
click.echo('Python version: {}.{}.{}'.format(sys.version_info[0], sys.version_info[1], sys.version_info[2]))
click.echo('Burp-UI version: {} ({})'.format(__version__, __release__))
click.echo('Single mode: {}'.format(app.standalone))
click.echo('Backend version: {}'.format(app.vers))
...@@ -36,6 +36,13 @@ You also need to configure a *restore_client* on your burp server corresponding ...@@ -36,6 +36,13 @@ You also need to configure a *restore_client* on your burp server corresponding
to the client you will use through `Burp-UI`_ (see the `restoration procedure to the client you will use through `Burp-UI`_ (see the `restoration procedure
<#restoration>`_ above for details on how to do this) <#restoration>`_ above for details on how to do this)
Tools
-----
Since *v0.5.0*, `Burp-UI`_ ships with some tools to help you configure both Burp
and `Burp-UI`_. Please refer to the `bui-manage <manage.html#diag>`_ page for
details.
Options Options
------- -------
......
...@@ -126,7 +126,16 @@ tracker <https://git.ziirish.me/ziirish/burp-ui/issues>`__. ...@@ -126,7 +126,16 @@ tracker <https://git.ziirish.me/ziirish/burp-ui/issues>`__.
All issues should contain the used command line to reproduce the problem, the All issues should contain the used command line to reproduce the problem, the
debug output and both versions of burp and ``Burp-UI`` you are using. debug output and both versions of burp and ``Burp-UI`` you are using.
You can get those informations using the following commands: A Bug Report template is available directly in the Issue Tracker:
.. image:: _static/issue_template.png
:alt: Issue Template
The template illustrate the commands to run in order to provide as much details
as you can in order to help reproduce the issue.
If you are running ``Burp-UI`` bellow *v0.5.0*, you can get those informations
using the following commands:
:: ::
......
...@@ -154,6 +154,7 @@ The available options are: ...@@ -154,6 +154,7 @@ The available options are:
:: ::
bui-manage setup_burp --help bui-manage setup_burp --help
Usage: flask setup_burp [OPTIONS] Usage: flask setup_burp [OPTIONS]
Setup burp client for burp-ui. Setup burp client for burp-ui.
...@@ -192,5 +193,82 @@ The docker image uses this script like this: ...@@ -192,5 +193,82 @@ The docker image uses this script like this:
-r $REDIS_SERVER -d $DATABASE_URL -r $REDIS_SERVER -d $DATABASE_URL
Sysinfo
-------
.. note::
This tool first appeard with `Burp-UI`_ *v0.5.0*.
This tool will help you to gather system informations in order to make a
detailed bug report.
Example:
::
bui-manage sysinfo
Python version: 2.7.9
Burp-UI version: 0.5.0 (stable)
Single mode: True
Backend version: 2
Diag
----
.. note::
This tool first appeard with `Burp-UI`_ *v0.5.0*.
This tool will help you detect misconfiguration. It will **not** modify your
files, you will have to use the `Configure <#configure>`_ tool for that.
The available options are:
::
bui-manage diag --help
Usage: flask diag [OPTIONS]
Check Burp-UI is correctly setup
Options:
-c, --client TEXT Name of the burp client that will be used by Burp-UI
(defaults to "bui")
-h, --host TEXT Address of the status server (defaults to "::1")
-t, --tips Show you some tips
--help Show this message and exit.
Examples:
::
bui-manage diag
The cname of your burp client does not match: hydrogen != bui
The burp server address does not match: 127.0.0.1 != ::1
'max_status_children' is to low, you need to set it to 15 or more. Please edit your /etc/burp/burp-server.conf file
Your burp client is not listed as a 'restore_client'. You won't be able to view other clients stats!
For performance reasons, it is recommanded to enable the 'monitor_browse_cache'
Unable to find the /etc/burp/clientconfdir/bui file
Some errors have been found in your configuration. Please make sure you ran this command with the right flags! (see --help for details)
bui-manage diag -c hydrogen -h 127.0.0.1 -t
'max_status_children' is to low, you need to set it to 15 or more. Please edit your /etc/burp/burp-server.conf file
Your burp client is not listed as a 'restore_client'. You won't be able to view other clients stats!
For performance reasons, it is recommanded to enable the 'monitor_browse_cache'
Well, if you are sure about your settings, you can run the following command to help you setup your Burp-UI agent. (Note, the '--dry' flag is here to show you the modifications that will be applied. Once you are OK with those, you can re-run the command without the '--dry' flag):
> bui-manage setup_burp --host="127.0.0.1" --client="hydrogen" --dry
When you configuration is OK, you should see this message:
::
Congratulations! It seems everything is alright. Burp-UI should run without any issue now.
.. _Burp-UI: https://git.ziirish.me/ziirish/burp-ui .. _Burp-UI: https://git.ziirish.me/ziirish/burp-ui
.. _Burp: http://burp.grke.org/ .. _Burp: http://burp.grke.org/
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment