diff --git a/resources/html-templates/files.html b/resources/html-templates/files.html index 90da243c..61cf2fca 100644 --- a/resources/html-templates/files.html +++ b/resources/html-templates/files.html @@ -3,27 +3,42 @@
Files
-
+
+ Refresh Interval: + + seconds +
+
+ - {% for image in images %} - - - - - - {% endfor %} + + {% for image in images %} + + + + + + + {% endfor %} +
# VIEW FILENAMEACTION
{{loop.index}} - - - - {{image}}
{{(images|length + 1) - loop.index}} + + + + {{image}} + + + +
@@ -36,4 +51,55 @@ $("#subdomainimage").css("background-repeat", " no-repeat") $("#subdomainimage").show() } + + function updateFileTable() { + $.ajax({ + url: '/files-list', + method: 'GET', + success: function (response) { + let currentFiles = []; + $('#file-table-body tr').each(function () { + currentFiles.push($(this).find('td:nth-child(3)').text().trim()); + }); + let baseUrl = response.base_url; + response.files.forEach(function (file, index) { + if (!currentFiles.includes(file)) { + let fileUrl = baseUrl + encodeURIComponent(file); + $('#file-table-body').prepend( + '' + + '' + (currentFiles.length + 1) + '' + + '' + + '' + + '' + + '' + + '' + + '' + file + '' + + '' + + '' + + '' + + '' + + '' + + '' + ); + } + }); + }, + error: function () { + console.log('Error fetching files.'); + } + }); + } + + let interval = setInterval(updateFileTable, 30000); + $('input[name="refresh-interval"]').on('change', function () { + const value = $(this).val(); + if (value < 5) { + $(this).val(30); + return; + } + clearInterval(interval); + interval = setInterval(updateFileTable, value * 1000); + }); diff --git a/resources/html-templates/header.html b/resources/html-templates/header.html index 04fe9fa3..001eac29 100644 --- a/resources/html-templates/header.html +++ b/resources/html-templates/header.html @@ -14,8 +14,7 @@ const icon = document.getElementById('themeIcon'); // Function to update the icon based on the current theme - function updateIcon() { - isDark = document.documentElement.getAttribute('data-bs-theme') === 'dark'; + function updateIcon(isDark) { if (isDark) { icon.className = 'bi bi-sun-fill'; } else { @@ -24,9 +23,8 @@ } // Function to update the logo based on the current theme - function updateLogo() { + function updateLogo(isDark) { const logo = document.querySelector('#posh-logo'); - isDark = document.documentElement.getAttribute('data-bs-theme') === 'dark'; if (isDark) { logo.src = '/include/img/logo-for-dark.webp'; } else { @@ -36,23 +34,25 @@ // Function to load the theme from localStorage function loadTheme() { + const isDark = document.documentElement.getAttribute('data-bs-theme') === 'dark'; const theme = localStorage.getItem('theme'); + if (theme === 'dark') { document.documentElement.setAttribute('data-bs-theme', 'dark'); } else { document.documentElement.setAttribute('data-bs-theme', 'light'); } - updateIcon(); - updateLogo(); + updateIcon(isDark); + updateLogo(isDark); } // Function to toggle the theme and save it to localStorage function toggleTheme() { - isDark = document.documentElement.getAttribute('data-bs-theme') === 'dark'; + const isDark = document.documentElement.getAttribute('data-bs-theme') === 'dark'; document.documentElement.setAttribute('data-bs-theme', isDark ? 'light' : 'dark'); localStorage.setItem('theme', isDark ? 'light' : 'dark'); - updateIcon(); - updateLogo(); + updateIcon(isDark); + updateLogo(isDark); } // Load the theme on page load @@ -70,6 +70,7 @@ links.forEach(link => { if (link.getAttribute('href') === currentPath) { link.classList.add('active'); + return; } }); } @@ -97,9 +98,9 @@
+ style="width: 230px;"> - +
-
+
diff --git a/resources/html-templates/include/css/bootstrap-icons.min.css:Zone.Identifier b/resources/html-templates/include/css/bootstrap-icons.min.css:Zone.Identifier deleted file mode 100644 index e69de29b..00000000 diff --git a/resources/html-templates/include/css/fonts/bootstrap-icons.woff2:Zone.Identifier b/resources/html-templates/include/css/fonts/bootstrap-icons.woff2:Zone.Identifier deleted file mode 100644 index e69de29b..00000000 diff --git a/resources/html-templates/include/css/fonts/bootstrap-icons.woff:Zone.Identifier b/resources/html-templates/include/css/fonts/bootstrap-icons.woff:Zone.Identifier deleted file mode 100644 index e69de29b..00000000 diff --git a/resources/html-templates/payloads.html b/resources/html-templates/payloads.html index 135dbc14..8d36b95d 100644 --- a/resources/html-templates/payloads.html +++ b/resources/html-templates/payloads.html @@ -3,6 +3,15 @@
Payloads
+
+
+ Upload new file: +
+ +
+ +
+
diff --git a/start_api.py b/start_api.py index b7a4f778..b20c1ca5 100644 --- a/start_api.py +++ b/start_api.py @@ -295,12 +295,38 @@ def list_files(number_of_files=None): return render_template('files.html', images=images) +@app.route('/files-list', methods=['GET']) +@app.route('/files-list/', methods=['GET']) +@auth.login_required +def list_files_json(number_of_files=None): + files = os.listdir(DOWNLOADS_DIR) + sorted_files = sorted(files, key=lambda x: os.path.getctime(os.path.join(DOWNLOADS_DIR, x)), reverse=True) + if number_of_files: + images = [f for f in sorted_files[0:number_of_files]] + else: + images = [f for f in sorted_files] + response = { + 'files': sorted_files, + 'base_url': url_for('serve_file', filename='', _external=True) + } + return jsonify(response) + + @app.route('/file/', methods=['GET']) @auth.login_required def serve_file(filename): return send_from_directory(DOWNLOADS_DIR, filename) +@app.route('/file/upload', methods=['POST']) +@auth.login_required +def upload_file(): + file = request.files['file'] + if file: + file.save(os.path.join(PAYLOADS_DIR, file.filename)) + return redirect(url_for('list_payloads')) + + @app.route('/taskviewwithnew') @app.route('/taskviewwithnew/') @app.route('/taskviewwithnew/implant/')