mirror of https://github.com/CIRCL/lookyloo
chg: refactorize and normalize the way we initialize the tables for the indexes
parent
f3db8b91c0
commit
b225e3043d
|
@ -11,7 +11,6 @@ import json
|
|||
import logging
|
||||
import logging.config
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
|
||||
import filetype # type: ignore[import-untyped]
|
||||
|
@ -49,7 +48,6 @@ from lookyloo.helpers import (UserAgents, load_cookies,
|
|||
)
|
||||
|
||||
from zoneinfo import available_timezones
|
||||
all_timezones_set = available_timezones()
|
||||
|
||||
from .genericapi import api as generic_api
|
||||
from .helpers import (User, build_users_table, get_secret_key,
|
||||
|
@ -58,6 +56,7 @@ from .helpers import (User, build_users_table, get_secret_key,
|
|||
from .proxied import ReverseProxied
|
||||
|
||||
logging.config.dictConfig(get_config('logging'))
|
||||
all_timezones_set = available_timezones()
|
||||
|
||||
app: Flask = Flask(__name__)
|
||||
app.wsgi_app = ReverseProxied(app.wsgi_app) # type: ignore[method-assign]
|
||||
|
@ -1478,13 +1477,19 @@ def rebuild_cache() -> WerkzeugResponse:
|
|||
def search() -> str | Response | WerkzeugResponse:
|
||||
if request.form.get('url'):
|
||||
quoted_url: str = quote_plus(request.form['url'])
|
||||
return redirect(url_for('url_details', url=quoted_url))
|
||||
return redirect(url_for('url_details', from_popup=True, url=quoted_url))
|
||||
if request.form.get('hostname'):
|
||||
return redirect(url_for('hostname_details', hostname=request.form.get('hostname')))
|
||||
return redirect(url_for('hostname_details', from_popup=True, hostname=request.form.get('hostname')))
|
||||
if request.form.get('ressource'):
|
||||
return redirect(url_for('body_hash_details', body_hash=request.form.get('ressource')))
|
||||
return redirect(url_for('body_hash_details', from_popup=True, body_hash=request.form.get('ressource')))
|
||||
if request.form.get('cookie'):
|
||||
return redirect(url_for('cookies_name_detail', cookie_name=request.form.get('cookie')))
|
||||
return redirect(url_for('cookies_name_detail', from_popup=True, cookie_name=request.form.get('cookie')))
|
||||
if request.form.get('favicon_sha512'):
|
||||
return redirect(url_for('favicon_detail', from_popup=True, favicon_sha512=request.form.get('favicon_sha512')))
|
||||
if 'favicon_file' in request.files:
|
||||
favicon = request.files['favicon_file'].stream.read()
|
||||
favicon_sha512 = hashlib.sha512(favicon).hexdigest()
|
||||
return redirect(url_for('favicon_detail', from_popup=True, favicon_sha512=favicon_sha512))
|
||||
return render_template('search.html')
|
||||
|
||||
|
||||
|
@ -1731,8 +1736,9 @@ def simple_capture() -> str | Response | WerkzeugResponse:
|
|||
|
||||
@app.route('/cookies/<string:cookie_name>', methods=['GET'])
|
||||
def cookies_name_detail(cookie_name: str) -> str:
|
||||
from_popup = True if (request.args.get('from_popup') and request.args.get('from_popup') == 'True') else False
|
||||
captures = get_cookie_name_investigator(cookie_name.strip())
|
||||
return render_template('cookie_name.html', cookie_name=cookie_name, captures=captures)
|
||||
return render_template('cookie_name.html', cookie_name=cookie_name, captures=captures, from_popup=from_popup)
|
||||
|
||||
|
||||
@app.route('/hhhdetails/<string:hhh>', methods=['GET'])
|
||||
|
@ -1760,11 +1766,13 @@ def capture_hash_details(hash_type: str, h: str) -> str:
|
|||
|
||||
@app.route('/favicon_details/<string:favicon_sha512>', methods=['GET'])
|
||||
def favicon_detail(favicon_sha512: str) -> str:
|
||||
from_popup = True if (request.args.get('from_popup') and request.args.get('from_popup') == 'True') else False
|
||||
captures, favicon = get_favicon_investigator(favicon_sha512.strip())
|
||||
mimetype, b64_favicon, mmh3_shodan = favicon
|
||||
return render_template('favicon_details.html', favicon_sha512=favicon_sha512,
|
||||
return render_template('favicon_details.html',
|
||||
captures=captures, mimetype=mimetype, b64_favicon=b64_favicon,
|
||||
mmh3_shodan=mmh3_shodan)
|
||||
mmh3_shodan=mmh3_shodan,
|
||||
from_popup=from_popup)
|
||||
|
||||
|
||||
@app.route('/body_hashes/<string:body_hash>', methods=['GET'])
|
||||
|
@ -1776,15 +1784,17 @@ def body_hash_details(body_hash: str) -> str:
|
|||
|
||||
@app.route('/urls/<string:url>', methods=['GET'])
|
||||
def url_details(url: str) -> str:
|
||||
from_popup = True if (request.args.get('from_popup') and request.args.get('from_popup') == 'True') else False
|
||||
url = unquote_plus(url).strip()
|
||||
captures = get_url_investigator(url)
|
||||
return render_template('url.html', url=url, captures=captures)
|
||||
return render_template('url.html', url=url, captures=captures, from_popup=from_popup)
|
||||
|
||||
|
||||
@app.route('/hostnames/<string:hostname>', methods=['GET'])
|
||||
def hostname_details(hostname: str) -> str:
|
||||
from_popup = True if (request.args.get('from_popup') and request.args.get('from_popup') == 'True') else False
|
||||
captures = get_hostname_investigator(hostname.strip())
|
||||
return render_template('hostname.html', hostname=hostname, captures=captures)
|
||||
return render_template('hostname.html', hostname=hostname, captures=captures, from_popup=from_popup)
|
||||
|
||||
|
||||
@app.route('/stats', methods=['GET'])
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
"favicon.ico": "KOmrfwRbOQqhhwSeBkNpMRAxSVMmmLg+2kRMg9iSv7OWjE9spJc7x4MKB4AE/hi0knaV7UBVctAU6XZ7AC72ZA==",
|
||||
"font.png": "RwoQkj9dT9SLUL2F7cAA16Nat9t2hDb58eQlHF9ThUar829p0INUXG+5XuDaFOC8SsmCZK5vw2f+YAQ6mLC1Qw==",
|
||||
"generic.css": "Sh/BcxFMLYYaLdCluVt9efGvJ9CF5d+YJ7lkL2M24PRGu8VZHI9lJiUlFObIocjQgwss3Ve2U5cUAE5WiAdpQQ==",
|
||||
"generic.js": "XgwjuFX2l5fhV2Ko9hJHenhI3LeKQTxnmL/844gJrzmwH/gSYnzikGavmucy9HjhwCaohXgZ5UD3ZJ3s8XHBog==",
|
||||
"generic.js": "/8a1CxlMcMAwl3UMfcGVe1smZZUB0gesxjd3Bmy7LLV16gE/ZPq6HciOnjNq0Jh+55PSSgIRLPsTbqGNv6Mcxw==",
|
||||
"hostname_popup.js": "8VoaZVwk2FBFCBVjgAup534WPy8B+e5/uUJPqyERUYf3kBcUVC8/T72ha9BYPYj5a6SNOOUJPgVmD5QI6qtAWw==",
|
||||
"html.png": "T7pZrb8MMDsA/JV/51hu+TOglTqlxySuEVY0rpDjTuAEyhzk2v+W4kYrj7vX+Tp3n2d2lvVD08PwhCG62Yfbzg==",
|
||||
"ifr.png": "rI5YJypmz1QcULRf9UaOYSqV4tPUSxUdLAycoYzCwywt4Pw4eWzBg9SUr769VyIimoiIyJR+aNuoIA4p5WO2fQ==",
|
||||
|
@ -33,11 +33,12 @@
|
|||
"loader.gif": "ZZKD5vLSKBWKeUpa2KI9qheUJ49iTI/UULmVU/AX28fBfH00K3lLc2v5pVJZ4qXG1BbB13LTXzRKKU35H2XfNg==",
|
||||
"lookyloo.jpeg": "i6wBj8CsIM5YAQLEMQfhs3CNOSKkErF8AMqqM6ZygSwCyQgv9CU8xt94veMZhM/ufBWoz7kAXmR+yywmxsTxug==",
|
||||
"redirect.png": "PAjzlPV97rEFvH55mG1ZC9wRl98be3yMeX/nENuFkJcds6/AXgSR2ig/QyPULgobSnNgiYieLVWY/oqsgeywrQ==",
|
||||
"render_tables.js": "4IWMmjPZR25ZfDUcX0WB8DShK9FxW34XP2dxudL+Hs9HVDe3rS15zGcOlFtn6XtaDKc1IcGxZSFmqCcRv6I5yw==",
|
||||
"secure.svg": "H8ni7t0d60nCJDVGuZpuxC+RBy/ipAjWT627D12HlZGg6LUmjSwPTQTUekm3UJupEP7TUkhXyq6WHc5gy7QBjg==",
|
||||
"stats.css": "/kY943FwWBTne4IIyf7iBROSfbGd82TeBicEXqKkRwawMVRIvM/Pk5MRa7okUyGIxaDjFQGmV/U1vy+PhN6Jbw==",
|
||||
"stats_graph.js": "S/sMNQK1UMMLD0xQeEa7sq3ce8o6oPxwxGlyKVtaHOODjair86dbBDm7cu6pa/elMRDJT1j09jEFjWp+5GbhTw==",
|
||||
"tree.css": "jc7+RiJaZy7utfMu7iMWicpt0y0ZFiEQlB4c7MFNdlWcZf0czi3LgSQUFlDWt828Mx463V+JP1RalXuRjbGcEg==",
|
||||
"tree.js": "V7P3EisB9n58pHvSv6xxPxWaU8Rkz7ci7/WnVasvz5m8z5ERrzgsp5DZXZfWLJ59MDPKphXg+wn6ljRgn2TiQQ==",
|
||||
"tree.js": "lj5SMtMYs2Oo++fWzHl2aQVHraCFZgpLCey99kql5wjhpYXryoacHM1zLHrP9E6A+b/1VA2zun9d445E3RLk4Q==",
|
||||
"tree_modals.js": "mGWQ9o4O+x8vBe9XNuAFrEfz8veuRwqE+wpreVKFQcvBvxNcgvxI0SjH9Z3gdozTTY7Hq7yqvC7xA9PWDblN/Q==",
|
||||
"up.jpg": "d1ljZJ9f5JekyM6RLFFH2Ua44j6neiQBdUIXOenRTjGppQr3JaeglpQIH6BjPCJL177+TH52U3UIRNS5YAyKIg==",
|
||||
"up_right.jpg": "OMmz+n+MxR34P8/fn5t4DkqKqdJRzQbXQ7fAi2lhkZIJGhVs2vIyY1f2hpYoBxDAX1OcYsSE2lqIR2vXNDGZsA==",
|
||||
|
|
|
@ -25,11 +25,37 @@ function checkAllBoxes(name) {
|
|||
}
|
||||
}
|
||||
|
||||
function openURLInNewTab(url) {
|
||||
let win = window.open(url, '_blank');
|
||||
if (win == null) {
|
||||
return false;
|
||||
}
|
||||
win.focus();
|
||||
return true;
|
||||
}
|
||||
|
||||
function openTreeInNewTab(capture_uuid, hostnode_uuid=null) {
|
||||
let url = `/tree/${capture_uuid}`;
|
||||
if (hostnode_uuid != null) {
|
||||
url += `/${hostnode_uuid}`;
|
||||
}
|
||||
return openURLInNewTab(url);
|
||||
}
|
||||
|
||||
const goBackButtons = document.querySelectorAll('.goBack');
|
||||
goBackButtons.forEach(el => el.addEventListener('click', event => {
|
||||
window.history.back();
|
||||
}));
|
||||
|
||||
const openNewTabButtons = document.querySelectorAll('.openNewTab');
|
||||
openNewTabButtons.forEach(el => el.addEventListener('click', event => {
|
||||
if (window.opener === null) {
|
||||
return openTreeInNewTab(el.dataset.capture, el.dataset.hostnode)
|
||||
} else {
|
||||
return window.opener.openTreeInNewTab(el.dataset.capture, el.dataset.hostnode);
|
||||
}
|
||||
}));
|
||||
|
||||
// Parameters:
|
||||
// contentType: The content type of your file.
|
||||
// its like application/pdf or application/msword or image/jpeg or
|
||||
|
|
|
@ -0,0 +1,183 @@
|
|||
["load", "shown.bs.modal"].forEach(e => window.addEventListener(e, function() {
|
||||
|
||||
if (document.getElementById('bodyHashDetailsTable')) {
|
||||
new DataTable('#bodyHashDetailsTable', {
|
||||
retrieve: true,
|
||||
order: [[ 0, "desc" ]],
|
||||
columnDefs: [{ width: '20%', targets: 0,
|
||||
render: (data) => {
|
||||
const date = new Date(data);
|
||||
return date.getFullYear() + '-' + (date.getMonth() + 1).toString().padStart(2, "0") + '-' + date.getDate().toString().padStart(2, "0") + ' ' + date.toTimeString();
|
||||
}
|
||||
},
|
||||
{ width: '40%', targets: 1 },
|
||||
{ width: '40%', targets: 2 }],
|
||||
});
|
||||
}
|
||||
if (document.getElementById('hashTypeDetailsTable')) {
|
||||
new DataTable('#hashTypeDetailsTable', {
|
||||
retrieve: true,
|
||||
order: [[ 0, "desc" ]],
|
||||
columnDefs: [{ width: '30%',
|
||||
targets: 0,
|
||||
render: (data) => {
|
||||
const date = new Date(data);
|
||||
return date.getFullYear() + '-' + (date.getMonth() + 1).toString().padStart(2, "0") + '-' + date.getDate().toString().padStart(2, "0") + ' ' + date.toTimeString();
|
||||
}
|
||||
},
|
||||
{ width: '30%', targets: 1 },
|
||||
{ width: '50%', targets: 2 }],
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
if (document.getElementById('identifierDetailsTable')) {
|
||||
new DataTable('#identifierDetailsTable', {
|
||||
retrieve: true,
|
||||
order: [[ 0, "desc" ]],
|
||||
columnDefs: [{ width: '30%',
|
||||
targets: 0,
|
||||
render: (data) => {
|
||||
const date = new Date(data);
|
||||
return date.getFullYear() + '-' + (date.getMonth() + 1).toString().padStart(2, "0") + '-' + date.getDate().toString().padStart(2, "0") + ' ' + date.toTimeString();
|
||||
}
|
||||
},
|
||||
{ width: '30%', targets: 1 },
|
||||
{ width: '50%', targets: 2 }],
|
||||
|
||||
});
|
||||
}
|
||||
if (document.getElementById('#bodyHashesTable')) {
|
||||
var table = new DataTable('#bodyHashesTable', {
|
||||
retrieve: true,
|
||||
order: [[ 0, "desc" ]],
|
||||
columnDefs: [{ width: '10%', targets: 0 },
|
||||
{ width: '10%', targets: 1 },
|
||||
{ width: '60%', targets: 2 },
|
||||
{ width: '20%', targets: 3 }],
|
||||
initComplete: function (settings, json) {
|
||||
$('[data-bs-toggle="tooltip"]').tooltip({html: true});
|
||||
}
|
||||
}).on('draw', function() {
|
||||
$('[data-bs-toggle="tooltip"]').tooltip({html: true});
|
||||
});
|
||||
}
|
||||
if (document.getElementById('faviconsTable')) {
|
||||
new DataTable('#faviconsTable', {
|
||||
retrieve: true,
|
||||
columnDefs: [{ width: '10%', targets: 0 },
|
||||
{ width: '40%', targets: 1 },
|
||||
{ width: '40%', targets: 2 },
|
||||
{ width: '10%', targets: 3 }],
|
||||
});
|
||||
}
|
||||
if (document.getElementById('treeHashesTable')) {
|
||||
new DataTable('#treeHashesTable', {
|
||||
retrieve: true,
|
||||
columnDefs: [{ width: '20%', targets: 0 },
|
||||
{ width: '40%', targets: 1 },
|
||||
{ width: '40%', targets: 2 }],
|
||||
});
|
||||
}
|
||||
if (document.getElementById('hostnamesTable')) {
|
||||
new DataTable('#hostnamesTable', {
|
||||
retrieve: true,
|
||||
order: [[ 0, "desc" ]],
|
||||
columnDefs: [{ width: '10%', targets: 0 },
|
||||
{ width: '40%', targets: 1 },
|
||||
{ width: '50%', targets: 2 }],
|
||||
initComplete: function (settings, json) {
|
||||
$('[data-bs-toggle="tooltip"]').tooltip({html: true});
|
||||
}
|
||||
}).on('draw', function() {
|
||||
$('[data-bs-toggle="tooltip"]').tooltip({html: true});
|
||||
});
|
||||
}
|
||||
if (document.getElementById('identifiersTable')) {
|
||||
new DataTable('#identifiersTable', {
|
||||
retrieve: true,
|
||||
columnDefs: [{ width: '20%', targets: 0 },
|
||||
{ width: '40%', targets: 1 },
|
||||
{ width: '40%', targets: 2 }],
|
||||
});
|
||||
}
|
||||
if (document.getElementById('urlsTable')) {
|
||||
new DataTable('#urlsTable', {
|
||||
retrieve: true,
|
||||
order: [[ 0, "desc" ]],
|
||||
columnDefs: [{ width: '10%', targets: 0 },
|
||||
{ width: '90%', targets: 1 }],
|
||||
initComplete: function (settings, json) {
|
||||
$('[data-bs-toggle="tooltip"]').tooltip({html: true});
|
||||
}
|
||||
}).on('draw', function() {
|
||||
$('[data-bs-toggle="tooltip"]').tooltip({html: true});
|
||||
});
|
||||
}
|
||||
if (document.getElementById('cookieNameTable')) {
|
||||
new DataTable('#cookieNameTable', {
|
||||
retrieve: true,
|
||||
order: [[ 0, "desc" ]],
|
||||
columnDefs: [{ width: '30%', targets: 0,
|
||||
render: (data) => {
|
||||
const date = new Date(data);
|
||||
return date.getFullYear() + '-' + (date.getMonth() + 1).toString().padStart(2, "0") + '-' + date.getDate().toString().padStart(2, "0") + ' ' + date.toTimeString();
|
||||
}
|
||||
},
|
||||
{ width: '70%', targets: 1 }]
|
||||
});
|
||||
}
|
||||
|
||||
if (document.getElementById('hostnameTable')) {
|
||||
new DataTable('#hostnameTable', {
|
||||
retrieve: true,
|
||||
order: [[ 0, "desc" ]],
|
||||
columnDefs: [{ width: '20%', targets: 0,
|
||||
render: (data) => {
|
||||
const date = new Date(data);
|
||||
return date.getFullYear() + '-' + (date.getMonth() + 1).toString().padStart(2, "0") + '-' + date.getDate().toString().padStart(2, "0") + ' ' + date.toTimeString();
|
||||
}
|
||||
},
|
||||
{ width: '40%', targets: 1 },
|
||||
{ width: '40%', targets: 2 }],
|
||||
});
|
||||
}
|
||||
|
||||
if (document.getElementById('urlTable')) {
|
||||
new DataTable('#urlTable', {
|
||||
retrieve: true,
|
||||
order: [[ 0, "desc" ]],
|
||||
columnDefs: [{ width: '20%', targets: 0,
|
||||
render: (data) => {
|
||||
const date = new Date(data);
|
||||
return date.getFullYear() + '-' + (date.getMonth() + 1).toString().padStart(2, "0") + '-' + date.getDate().toString().padStart(2, "0") + ' ' + date.toTimeString();
|
||||
}
|
||||
},
|
||||
{ width: '40%', targets: 1 },
|
||||
{ width: '40%', targets: 2 }],
|
||||
});
|
||||
}
|
||||
|
||||
if (document.getElementById('faviconDetailsTable')) {
|
||||
new DataTable('#faviconDetailsTable', {
|
||||
retrieve: true,
|
||||
order: [[ 0, "desc" ]],
|
||||
columnDefs: [{ width: '30%',
|
||||
targets: 0,
|
||||
render: (data) => {
|
||||
const date = new Date(data);
|
||||
return date.getFullYear() + '-' + (date.getMonth() + 1).toString().padStart(2, "0") + '-' + date.getDate().toString().padStart(2, "0") + ' ' + date.toTimeString();
|
||||
}
|
||||
},
|
||||
{ width: '30%', targets: 1 },
|
||||
{ width: '50%', targets: 2 }],
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
// Other things to trigger in modals
|
||||
document.querySelectorAll(".downloadFaviconButton").forEach(el => el.addEventListener('click', event => {
|
||||
downloadBase64File(el.dataset.mimetype, el.dataset.b64favicon, el.dataset.filename);
|
||||
}))
|
||||
|
||||
}));
|
|
@ -157,23 +157,6 @@ if (parent_uuid != null) {
|
|||
};
|
||||
|
||||
|
||||
function openURLInNewTab(url) {
|
||||
let win = window.open(url, '_blank');
|
||||
if (win == null) {
|
||||
return false;
|
||||
}
|
||||
win.focus();
|
||||
return true;
|
||||
}
|
||||
|
||||
function openTreeInNewTab(capture_uuid, hostnode_uuid=null) {
|
||||
let url = `/tree/${capture_uuid}`;
|
||||
if (hostnode_uuid != null) {
|
||||
url += `/${hostnode_uuid}`;
|
||||
}
|
||||
return openURLInNewTab(url);
|
||||
}
|
||||
|
||||
function open_hostnode_popup(hostnode_uuid) {
|
||||
let win = window.open(`/tree/${treeUUID}/host/${hostnode_uuid}`, '_blank', 'width=1024,height=768,left=200,top=100');
|
||||
if (win == null) {
|
||||
|
|
|
@ -7,50 +7,6 @@
|
|||
|
||||
{% block title %}{{ body_hash }}{% endblock %}
|
||||
|
||||
{% block scripts %}
|
||||
{{ super() }}
|
||||
|
||||
<script type="text/javascript" nonce="{{ csp_nonce() }}">
|
||||
const openNewTabButtons = document.querySelectorAll('.openNewTab');
|
||||
if (openNewTabButtons) {
|
||||
openNewTabButtons.forEach(el => el.addEventListener('click', event => {
|
||||
window.opener.openTreeInNewTab(el.dataset.capture, el.dataset.hostnode);
|
||||
}));
|
||||
}
|
||||
</script>
|
||||
|
||||
<script type="text/javascript" nonce="{{ csp_nonce() }}">
|
||||
new DataTable('#bodyHashDetailsTable', {
|
||||
order: [[ 0, "desc" ]],
|
||||
columnDefs: [{ width: '20%', targets: 0,
|
||||
render: (data) => {
|
||||
const date = new Date(data);
|
||||
return date.getFullYear() + '-' + (date.getMonth() + 1).toString().padStart(2, "0") + '-' + date.getDate().toString().padStart(2, "0") + ' ' + date.toTimeString();
|
||||
}
|
||||
},
|
||||
{ width: '40%', targets: 1 },
|
||||
{ width: '40%', targets: 2 }],
|
||||
});
|
||||
</script>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{%else%}
|
||||
|
||||
<script type="text/javascript" nonce="{{ csp_nonce() }}">
|
||||
new DataTable('#bodyHashDetailsTable', {
|
||||
order: [[ 0, "desc" ]],
|
||||
columnDefs: [{ width: '20%', targets: 0,
|
||||
render: (data) => {
|
||||
const date = new Date(data);
|
||||
return date.getFullYear() + '-' + (date.getMonth() + 1).toString().padStart(2, "0") + '-' + date.getDate().toString().padStart(2, "0") + ' ' + date.toTimeString();
|
||||
}
|
||||
},
|
||||
{ width: '40%', targets: 1 },
|
||||
{ width: '40%', targets: 2 }],
|
||||
});
|
||||
</script>
|
||||
|
||||
{%endif%}
|
||||
|
||||
|
||||
|
|
|
@ -1,32 +1,22 @@
|
|||
{% extends "main.html" %}
|
||||
|
||||
{% from "macros.html" import shorten_string %}
|
||||
|
||||
{% block scripts %}
|
||||
{{ super() }}
|
||||
<script type="text/javascript" nonce="{{ csp_nonce() }}">
|
||||
new DataTable('#cookieNameTable', {
|
||||
order: [[ 0, "desc" ]],
|
||||
columnDefs: [{ width: '30%', targets: 0,
|
||||
render: (data) => {
|
||||
const date = new Date(data);
|
||||
return date.getFullYear() + '-' + (date.getMonth() + 1).toString().padStart(2, "0") + '-' + date.getDate().toString().padStart(2, "0") + ' ' + date.toTimeString();
|
||||
}
|
||||
},
|
||||
{ width: '70%', targets: 1 }]
|
||||
});
|
||||
</script>
|
||||
<script type="text/javascript" nonce="{{ csp_nonce() }}">
|
||||
const openNewTabButtons = document.querySelectorAll('.openNewTab');
|
||||
if (openNewTabButtons) {
|
||||
openNewTabButtons.forEach(el => el.addEventListener('click', event => {
|
||||
window.opener.openTreeInNewTab(el.dataset.capture, el.dataset.hostnode);
|
||||
}));
|
||||
}
|
||||
</script>
|
||||
{% endblock %}
|
||||
{% if from_popup %}
|
||||
{% extends "main.html" %}
|
||||
|
||||
{% from 'bootstrap5/utils.html' import render_messages %}
|
||||
|
||||
{% block title %}{{ cookie_name }}{% endblock %}
|
||||
|
||||
{%endif%}
|
||||
|
||||
|
||||
{% block content %}
|
||||
|
||||
|
||||
{% if from_popup %}
|
||||
<center><button class="btn btn-primary goBack" type="button">Go Back</button></center>
|
||||
{%endif%}
|
||||
|
||||
<center>
|
||||
<h4>{{ cookie_name }}</h4>
|
||||
<h6>Only the most recent captures are listed below, this will change soon.</h6>
|
||||
|
|
|
@ -1,26 +1,27 @@
|
|||
{% from "macros.html" import shorten_string %}
|
||||
|
||||
<script type="text/javascript" nonce="{{ csp_nonce() }}">
|
||||
new DataTable('#faviconDetailsTable_{{favicon_sha512}}', {
|
||||
order: [[ 0, "desc" ]],
|
||||
columnDefs: [{ width: '30%',
|
||||
targets: 0,
|
||||
render: (data) => {
|
||||
const date = new Date(data);
|
||||
return date.getFullYear() + '-' + (date.getMonth() + 1).toString().padStart(2, "0") + '-' + date.getDate().toString().padStart(2, "0") + ' ' + date.toTimeString();
|
||||
}
|
||||
},
|
||||
{ width: '30%', targets: 1 },
|
||||
{ width: '50%', targets: 2 }],
|
||||
{% if from_popup %}
|
||||
{% extends "main.html" %}
|
||||
|
||||
{% from 'bootstrap5/utils.html' import render_messages %}
|
||||
|
||||
{% block title %}Favicon{% endblock %}
|
||||
|
||||
{%endif%}
|
||||
|
||||
|
||||
{% block content %}
|
||||
|
||||
{% if from_popup %}
|
||||
<center><button class="btn btn-primary goBack" type="button">Go Back</button></center>
|
||||
{%endif%}
|
||||
|
||||
});
|
||||
</script>
|
||||
|
||||
<center>
|
||||
<img src="data:{{mimetype}};base64,{{ b64_favicon }}" style="width:32px;height:32px;"/>
|
||||
<h5>Shodan MMH3 Hash: <a href="https://www.shodan.io/search?query=http.favicon.hash%3A{{ mmh3_shodan }}" target="_blank">{{ mmh3_shodan }}</a></h5>
|
||||
</center>
|
||||
<table id="faviconDetailsTable_{{favicon_sha512}}" class="table table-striped" style="width:100%">
|
||||
<table id="faviconDetailsTable" class="table table-striped" style="width:100%">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Capture Time</th>
|
||||
|
@ -48,3 +49,5 @@
|
|||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
{% endblock %}
|
||||
|
|
|
@ -1,21 +1,4 @@
|
|||
{% from "macros.html" import shorten_string %}
|
||||
|
||||
<script type="text/javascript" nonce="{{ csp_nonce() }}">
|
||||
new DataTable('#hashTypeDetailsTable', {
|
||||
order: [[ 0, "desc" ]],
|
||||
columnDefs: [{ width: '30%',
|
||||
targets: 0,
|
||||
render: (data) => {
|
||||
const date = new Date(data);
|
||||
return date.getFullYear() + '-' + (date.getMonth() + 1).toString().padStart(2, "0") + '-' + date.getDate().toString().padStart(2, "0") + ' ' + date.toTimeString();
|
||||
}
|
||||
},
|
||||
{ width: '30%', targets: 1 },
|
||||
{ width: '50%', targets: 2 }],
|
||||
|
||||
});
|
||||
</script>
|
||||
|
||||
<center>
|
||||
<h5>{{hash_type}}: {{h}}</h5>
|
||||
<h6>Only the most recent captures are listed below, this will change soon.</h6>
|
||||
|
|
|
@ -1,22 +1,7 @@
|
|||
{% if from_popup %}
|
||||
{% extends "main.html" %}
|
||||
|
||||
{% from 'bootstrap5/utils.html' import render_messages %}
|
||||
|
||||
{% block title %}{{ hhh }}{% endblock %}
|
||||
|
||||
{% block scripts %}
|
||||
{{ super() }}
|
||||
<script type="text/javascript" nonce="{{ csp_nonce() }}">
|
||||
const openNewTabButtons = document.querySelectorAll('.openNewTab');
|
||||
if (openNewTabButtons) {
|
||||
openNewTabButtons.forEach(el => el.addEventListener('click', event => {
|
||||
window.opener.openTreeInNewTab(el.dataset.capture, el.dataset.hostnode);
|
||||
}));
|
||||
}
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
{%endif%}
|
||||
|
||||
{% block content %}
|
||||
|
|
|
@ -1,26 +1,25 @@
|
|||
{% from "macros.html" import shorten_string %}
|
||||
|
||||
{% if from_popup %}
|
||||
{% extends "main.html" %}
|
||||
|
||||
{% from 'bootstrap5/utils.html' import render_messages %}
|
||||
|
||||
{% block title %}{{ hostname }}{% endblock %}
|
||||
|
||||
{%endif%}
|
||||
|
||||
{% block content %}
|
||||
|
||||
{% if from_popup %}
|
||||
<center><button class="btn btn-primary goBack" type="button">Go Back</button></center>
|
||||
{%endif%}
|
||||
|
||||
<center>
|
||||
<h4>{{ hostname }}</h4>
|
||||
<h6>Only the most recent captures are listed below, this will change soon.</h6>
|
||||
</center>
|
||||
|
||||
<script type="text/javascript" nonce="{{ csp_nonce() }}">
|
||||
new DataTable('#hostnameTable', {
|
||||
order: [[ 0, "desc" ]],
|
||||
columnDefs: [{ width: '20%', targets: 0,
|
||||
render: (data) => {
|
||||
const date = new Date(data);
|
||||
return date.getFullYear() + '-' + (date.getMonth() + 1).toString().padStart(2, "0") + '-' + date.getDate().toString().padStart(2, "0") + ' ' + date.toTimeString();
|
||||
}
|
||||
},
|
||||
{ width: '40%', targets: 1 },
|
||||
{ width: '40%', targets: 2 }],
|
||||
});
|
||||
</script>
|
||||
|
||||
<table id="hostnameTable" class="table table-striped" style="width:100%">
|
||||
<thead>
|
||||
<tr>
|
||||
|
|
|
@ -1,21 +1,5 @@
|
|||
{% from "macros.html" import shorten_string %}
|
||||
|
||||
<script type="text/javascript" nonce="{{ csp_nonce() }}">
|
||||
new DataTable('#identifierDetailsTable', {
|
||||
order: [[ 0, "desc" ]],
|
||||
columnDefs: [{ width: '30%',
|
||||
targets: 0,
|
||||
render: (data) => {
|
||||
const date = new Date(data);
|
||||
return date.getFullYear() + '-' + (date.getMonth() + 1).toString().padStart(2, "0") + '-' + date.getDate().toString().padStart(2, "0") + ' ' + date.toTimeString();
|
||||
}
|
||||
},
|
||||
{ width: '30%', targets: 1 },
|
||||
{ width: '50%', targets: 2 }],
|
||||
|
||||
});
|
||||
</script>
|
||||
|
||||
<center>
|
||||
<h5>{{identifier_type}}: {{identifier}}</h5>
|
||||
</center>
|
||||
|
|
|
@ -47,6 +47,11 @@
|
|||
{{get_sri('static', 'generic.js')}}
|
||||
nonce="{{ csp_nonce() }}"
|
||||
crossorigin="anonymous"></script>
|
||||
<script src='{{ url_for('static', filename='render_tables.js') }}'
|
||||
{{get_sri('static', 'render_tables.js')}}
|
||||
nonce="{{ csp_nonce() }}"
|
||||
crossorigin="anonymous"></script>
|
||||
|
||||
{% endblock %}
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{% extends "main.html" %}
|
||||
{% block title %}Capture{% endblock %}
|
||||
{% block title %}Search{% endblock %}
|
||||
|
||||
{% block card %}
|
||||
<meta property="og:title" content="Lookyloo" />
|
||||
|
@ -54,6 +54,18 @@
|
|||
<input type="text" class="form-control" name="cookie" id=cookie placeholder="Cookie name to search">
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-3">
|
||||
<div class="col-sm-10">
|
||||
<label for="favicon_sha512" class="col-sm-2 col-form-label">Favicon SHA512:</label>
|
||||
<input type="text" class="form-control" name="favicon_sha512" id=favicon_sha512 placeholder="SHA512 of a favicon">
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-3">
|
||||
<div class="col-sm-10">
|
||||
<label for="favicon_file" class="col-sm-2 col-form-label">Favicon:</label>
|
||||
<input class="form-control" type="file" id="favicon_file" name="favicon_file">
|
||||
</div>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary" id="btn-looking">Start looking!</button>
|
||||
</form>
|
||||
</div>
|
||||
|
|
|
@ -1,28 +1,4 @@
|
|||
{% from "macros.html" import popup_icons_response %}
|
||||
|
||||
<script type="text/javascript" nonce="{{ csp_nonce() }}">
|
||||
var table = new DataTable('#bodyHashesTable', {
|
||||
order: [[ 0, "desc" ]],
|
||||
columnDefs: [{ width: '10%', targets: 0 },
|
||||
{ width: '10%', targets: 1 },
|
||||
{ width: '60%', targets: 2 },
|
||||
{ width: '20%', targets: 3 }],
|
||||
initComplete: function (settings, json) {
|
||||
$('[data-bs-toggle="tooltip"]').tooltip({html: true});
|
||||
}
|
||||
}).on('draw', function() {
|
||||
$('[data-bs-toggle="tooltip"]').tooltip({html: true});
|
||||
});
|
||||
</script>
|
||||
<script type="text/javascript" nonce="{{ csp_nonce() }}">
|
||||
let openNewTabButtons = document.querySelectorAll('.openNewTab');
|
||||
if (openNewTabButtons) {
|
||||
openNewTabButtons.forEach(el => el.addEventListener('click', event => {
|
||||
openTreeInNewTab(el.dataset.capture, el.dataset.hostnode);
|
||||
}));
|
||||
}
|
||||
</script>
|
||||
|
||||
<table id="bodyHashesTable" class="table table-striped" style="width:100%">
|
||||
<thead>
|
||||
<tr>
|
||||
|
|
|
@ -1,22 +1,3 @@
|
|||
<script type="text/javascript" nonce="{{ csp_nonce() }}">
|
||||
new DataTable('#faviconsTable', {
|
||||
columnDefs: [{ width: '10%', targets: 0 },
|
||||
{ width: '40%', targets: 1 },
|
||||
{ width: '40%', targets: 2 },
|
||||
{ width: '10%', targets: 3 }],
|
||||
});
|
||||
</script>
|
||||
|
||||
<script type="text/javascript" nonce="{{ csp_nonce() }}">
|
||||
const downloadFavicons = document.querySelectorAll(".downloadFaviconButton")
|
||||
if (downloadFavicons) {
|
||||
downloadFavicons.forEach(el => el.addEventListener('click', event => {
|
||||
downloadBase64File(el.dataset.mimetype, el.dataset.b64favicon, el.dataset.filename);
|
||||
}));
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
<h5 class="text-center">Click on the favicon to see the other captures it's been found in</h5>
|
||||
<table id="faviconsTable" class="table table-striped" style="width:100%">
|
||||
<thead>
|
||||
|
|
|
@ -1,12 +1,3 @@
|
|||
<script type="text/javascript" nonce="{{ csp_nonce() }}">
|
||||
new DataTable('#treeHashesTable', {
|
||||
columnDefs: [{ width: '20%', targets: 0 },
|
||||
{ width: '40%', targets: 1 },
|
||||
{ width: '40%', targets: 2 }],
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
<h5 class="text-center">Click on the hash to see the other captures it's been found in</h5>
|
||||
<table id="treeHashesTable" class="table table-striped" style="width:100%">
|
||||
<thead>
|
||||
|
|
|
@ -1,28 +1,5 @@
|
|||
{% from "macros.html" import popup_icons_response %}
|
||||
|
||||
<script type="text/javascript" nonce="{{ csp_nonce() }}">
|
||||
var table = new DataTable('#hostnamesTable', {
|
||||
order: [[ 0, "desc" ]],
|
||||
columnDefs: [{ width: '10%', targets: 0 },
|
||||
{ width: '40%', targets: 1 },
|
||||
{ width: '50%', targets: 2 }],
|
||||
initComplete: function (settings, json) {
|
||||
$('[data-bs-toggle="tooltip"]').tooltip({html: true});
|
||||
}
|
||||
}).on('draw', function() {
|
||||
$('[data-bs-toggle="tooltip"]').tooltip({html: true});
|
||||
});
|
||||
</script>
|
||||
|
||||
<script type="text/javascript" nonce="{{ csp_nonce() }}">
|
||||
let openNewTabButtons = document.querySelectorAll('.openNewTab');
|
||||
if (openNewTabButtons) {
|
||||
openNewTabButtons.forEach(el => el.addEventListener('click', event => {
|
||||
openTreeInNewTab(el.dataset.capture, el.dataset.hostnode);
|
||||
}));
|
||||
}
|
||||
</script>
|
||||
|
||||
<table id="hostnamesTable" class="table table-striped" style="width:100%">
|
||||
<thead>
|
||||
<tr>
|
||||
|
|
|
@ -1,11 +1,3 @@
|
|||
<script type="text/javascript" nonce="{{ csp_nonce() }}">
|
||||
new DataTable('#identifiersTable', {
|
||||
columnDefs: [{ width: '20%', targets: 0 },
|
||||
{ width: '40%', targets: 1 },
|
||||
{ width: '40%', targets: 2 }],
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
<h5 class="text-center">Click on the identifier to see the other captures it's been found in</h5>
|
||||
<table id="identifiersTable" class="table table-striped" style="width:100%">
|
||||
|
|
|
@ -1,18 +1,5 @@
|
|||
{% from "macros.html" import popup_icons_response %}
|
||||
|
||||
<script type="text/javascript" nonce="{{ csp_nonce() }}">
|
||||
var table = new DataTable('#urlsTable', {
|
||||
order: [[ 0, "desc" ]],
|
||||
columnDefs: [{ width: '10%', targets: 0 },
|
||||
{ width: '90%', targets: 1 }],
|
||||
initComplete: function (settings, json) {
|
||||
$('[data-bs-toggle="tooltip"]').tooltip({html: true});
|
||||
}
|
||||
}).on('draw', function() {
|
||||
$('[data-bs-toggle="tooltip"]').tooltip({html: true});
|
||||
});
|
||||
</script>
|
||||
|
||||
<table id="urlsTable" class="table table-striped" style="width:100%">
|
||||
<thead>
|
||||
<tr>
|
||||
|
|
|
@ -1,26 +1,27 @@
|
|||
{% from "macros.html" import shorten_string %}
|
||||
|
||||
{% if from_popup %}
|
||||
{% extends "main.html" %}
|
||||
|
||||
{% from 'bootstrap5/utils.html' import render_messages %}
|
||||
|
||||
{% block title %}{{ url }}{% endblock %}
|
||||
|
||||
{%endif%}
|
||||
|
||||
|
||||
{% block content %}
|
||||
|
||||
{% if from_popup %}
|
||||
<center><button class="btn btn-primary goBack" type="button">Go Back</button></center>
|
||||
{%endif%}
|
||||
|
||||
|
||||
<center>
|
||||
<h4>{{ url }}</h4>
|
||||
<h6>Only the most recent captures are listed below, this will change soon.</h6>
|
||||
</center>
|
||||
|
||||
<script type="text/javascript" nonce="{{ csp_nonce() }}">
|
||||
new DataTable('#urlTable', {
|
||||
order: [[ 0, "desc" ]],
|
||||
columnDefs: [{ width: '20%', targets: 0,
|
||||
render: (data) => {
|
||||
const date = new Date(data);
|
||||
return date.getFullYear() + '-' + (date.getMonth() + 1).toString().padStart(2, "0") + '-' + date.getDate().toString().padStart(2, "0") + ' ' + date.toTimeString();
|
||||
}
|
||||
},
|
||||
{ width: '40%', targets: 1 },
|
||||
{ width: '40%', targets: 2 }],
|
||||
});
|
||||
</script>
|
||||
|
||||
<table id="urlTable" class="table table-striped" style="width:100%">
|
||||
<thead>
|
||||
<tr>
|
||||
|
|
Loading…
Reference in New Issue