new: Multiple queries at once on web interface

pull/382/head
Raphaël Vinot 2022-03-31 00:48:58 +02:00
parent f17f6f1a37
commit ee69e66750
4 changed files with 57 additions and 22 deletions

18
poetry.lock generated
View File

@ -359,24 +359,17 @@ Flask = ">=0.9"
Six = "*"
[[package]]
name = "Flask-Login"
version = "0.6.0.dev0"
name = "flask-login"
version = "0.6.0"
description = "User authentication and session management for Flask."
category = "main"
optional = false
python-versions = ">=3.7"
develop = false
[package.dependencies]
Flask = ">=1.0.4"
Werkzeug = ">=1.0.1"
[package.source]
type = "git"
url = "https://github.com/maxcountryman/flask-login"
reference = "main"
resolved_reference = "0f94639858946ea8e921743db684b6da97d46385"
[[package]]
name = "flask-restx"
version = "0.5.1"
@ -1530,7 +1523,7 @@ misp = ["python-magic", "pydeep"]
[metadata]
lock-version = "1.1"
python-versions = ">=3.8,<3.11"
content-hash = "a1c1bf9772f545beeebf0e22a59bfb19932e4d88f5016744941fec9f5b8770fa"
content-hash = "45a1f781fb6065d0091dafc64bbfe2c3512adbdd18dcd20a61ba399302e449ab"
[metadata.files]
aiohttp = [
@ -1821,7 +1814,10 @@ flask-cors = [
{file = "Flask-Cors-3.0.10.tar.gz", hash = "sha256:b60839393f3b84a0f3746f6cdca56c1ad7426aa738b70d6c61375857823181de"},
{file = "Flask_Cors-3.0.10-py2.py3-none-any.whl", hash = "sha256:74efc975af1194fc7891ff5cd85b0f7478be4f7f59fe158102e91abb72bb4438"},
]
Flask-Login = []
flask-login = [
{file = "Flask-Login-0.6.0.tar.gz", hash = "sha256:aa84fcfb4c3cf09ca58c08e816b7bce73f1349ba1cf13d00d8dffc5872d5fcf6"},
{file = "Flask_Login-0.6.0-py3-none-any.whl", hash = "sha256:5cb01ce4dc253967b6ac722a11e46de83b6272ef7a19cc7b5725ae636916d04d"},
]
flask-restx = [
{file = "flask-restx-0.5.1.tar.gz", hash = "sha256:63c69a61999a34f1774eaccc6fc8c7f504b1aad7d56a8ec672264e52d9ac05f4"},
{file = "flask_restx-0.5.1-py2.py3-none-any.whl", hash = "sha256:96157547acaa8892adcefd8c60abf9040212ac2a8634937a82946e07b46147fd"},

View File

@ -65,7 +65,7 @@ Flask-Cors = "^3.0.10"
pyhashlookup = "^1.1.1"
lief = "^0.12.0"
ua-parser = "^0.10.0"
flask-login = {git = "https://github.com/maxcountryman/flask-login", rev = "main"}
Flask-Login = "^0.6.0"
[tool.poetry.extras]
misp = ['python-magic', 'pydeep']

View File

@ -837,8 +837,8 @@ def capture_web():
else:
user = src_request_ip(request)
if request.method == 'POST' and request.form.get('url'):
capture_query: Dict[str, Union[str, bytes, int, bool]] = {'url': request.form['url']}
if request.method == 'POST' and (request.form.get('url') or request.form.get('urls')):
capture_query: Dict[str, Union[str, bytes, int, bool]] = {}
# check if the post request has the file part
if 'cookies' in request.files and request.files['cookies'].filename:
capture_query['cookies'] = request.files['cookies'].stream.read()
@ -875,9 +875,21 @@ def capture_web():
else:
flash('Invalid proxy: Check that you entered a scheme, a hostname and a port.', 'error')
perma_uuid = lookyloo.enqueue_capture(capture_query, source='web', user=user, authenticated=flask_login.current_user.is_authenticated)
time.sleep(2)
return redirect(url_for('tree', tree_uuid=perma_uuid))
if request.form.get('url'):
capture_query['url'] = request.form['url']
perma_uuid = lookyloo.enqueue_capture(capture_query, source='web', user=user, authenticated=flask_login.current_user.is_authenticated)
time.sleep(2)
return redirect(url_for('tree', tree_uuid=perma_uuid))
else:
# bulk query
bulk_captures = []
for url in request.form['urls'].split('\n'):
query = capture_query.copy()
query['url'] = url
new_capture_uuid = lookyloo.enqueue_capture(query, source='web', user=user, authenticated=flask_login.current_user.is_authenticated)
bulk_captures.append((new_capture_uuid, url))
return render_template('bulk_captures.html', bulk_captures=bulk_captures)
elif request.method == 'GET' and request.args.get('url'):
url = unquote_plus(request.args['url']).strip()
capture_query = {'url': url}

View File

@ -38,12 +38,20 @@
</div>
</div>
</div>
<div class="row mb-3">
<div class="row input-group mb-3">
<label for="url" class="col-sm-1 col-form-label">URL:</label>
<div class="col-sm-10">
<input type="text" class="form-control" name="url" id=url
placeholder="URL to capture" value="{{predefined_url_to_capture}}" required>
</div>
<input type="text" class="form-control col-auto" name="url" id=singleCaptureField
placeholder="URL to capture" value="{{predefined_url_to_capture}}" required>
<textarea class="form-control col-auto d-none" placeholder="URLs to capture, one per line"
name="urls" id=multipleCapturesField></textarea>
<span class="col-sm-2 input-group-text">
<div class="form-check">
<input class="form-check-input" name="multipleCaptures" id="multipleCaptures" type="checkbox"
value="" aria-label="tick to enable multiple captures">
<label for="multipleCaptures" class="form-check-label">Multiple captures</label>
</div>
</span>
</div>
<div>
@ -208,4 +216,23 @@
<script src='{{ url_for('static', filename='capture.js') }}'
integrity="{{get_sri('static', 'capture.js')}}"
crossorigin="anonymous"></script>
<script>
$('#multipleCaptures').on('click', function(e) {
if (document.getElementById('multipleCaptures').checked == true) {
document.getElementById('singleCaptureField').value = '';
$("#singleCaptureField").addClass("d-none");
$("#singleCaptureField").removeAttr("required");
$("#multipleCapturesField").removeClass("d-none");
$("#multipleCapturesField").attr("required", true);
}
else {
document.getElementById('multipleCapturesField').value = '';
$("#singleCaptureField").removeClass("d-none");
$("#singleCaptureField").attr("required", true);
$("#multipleCapturesField").addClass("d-none");
$("#multipleCapturesField").removeAttr("required");
}
})
</script>
{% endblock %}