Honeypot 000 : .env.local.php
We make a honeypot to track scanners and waste their time!
Okay, here's a sophisticated Flask honeypot application designed to waste the time of scanners probing for a /.env.local.php file. It serves meticulously crafted, believable-but-fake credentials and other data, aiming to keep bots engaged for longer while providing negligible risk to your actual system. The output is designed to be Markdown-compatible for Ghost blogs (or other Markdown-based CMS).
from flask import Flask, render_template, request, make_response
import random
import string
import datetime
from faker import Faker # pip install Faker
app = Flask(__name__)
fake = Faker()
# Configuration - Customize these!
HONEYPOT_FILE = "/.env.local.php"
RESPONSE_DELAY_SECONDS = 2 # Artificial delay to slow down bots
MAX_LOG_SIZE = 1024 10 # Maximum size of the honeypot log file in kb (10 kb)
# --- Helper Functions ---
def generate_fake_credentials():
"""Generates a realistic-looking set of fake credentials."""
username = fake.user_name()
email = fake.email()
password = fake.password(length=12, special_chars=True, digits=True, upper_case=True, lower_case=True) # Strong password
db_host = fake.ipv4() #Fake to look like a database
db_name = "".join(random.choices(string.ascii_lowercase, k=8)) #short name like dbname
db_user = fake.user_name() #username look a like
db_pass = fake.password(length=10, special_chars=False, digits=True, upper_case=True, lower_case=True)
api_key = ''.join(random.choices(string.ascii_letters + string.digits, k=32)) #Long random API
secret_key = ''.join(random.choices(string.ascii_letters + string.digits, k=32)) #another key as secrets
return {
"APP_USERNAME": username,
"APP_EMAIL": email,
"APP_PASSWORD": password,
"DATABASE_HOST": db_host,
"DATABASE_NAME": db_name,
"DATABASE_USER": db_user,
"DATABASE_PASSWORD": db_pass,
"API_KEY": api_key,
"SECRET_KEY": secret_key,
"DEBUG": "false",
"APP_ENV": "production",
"APP_URL": fake.url()
}
def log_access(request):
"""Logs access attempts to the honeypot file with relevant details."""
timestamp = datetime.datetime.now().isoformat()
ip_address = request.remote_addr
user_agent = request.user_agent.string
requested_path = request.path
log_entry = f"[{timestamp}] IP: {ip_address}, User-Agent: {user_agent}, Path: {requested_path}\n"
try:
with open("honeypot.log", "a") as log_file:
log_file.write(log_entry)
# Check log file size and truncate if necessary
if os.path.getsize("honeypot.log") > MAX_LOG_SIZE:
truncate_log("honeypot.log", MAX_LOG_SIZE)
except Exception as e:
print(f"Error writing to log file: {e}")
def truncate_log(filename, max_size):
"""Truncates the log file to a maximum size in bytes."""
try:
with open(filename, "r+") as f:
lines = f.readlines()
total_size = sum(len(line.encode('utf-8')) for line in lines)
while total_size > max_size and lines:
removed_line = lines.pop(0)
total_size -= len(removed_line.encode('utf-8'))
f.seek(0) # Rewind to the beginning
f.writelines(lines)
f.truncate() # Remove the remaining part of the old file
except Exception as e:
print(f"Error truncating log file: {e}")
# --- Routes ---
@app.route(HONEYPOT_FILE)
def env_file():
"""
Serves a fake .env.local.php file. This is the core of the honeypot.
It generates realistic, but fake, credentials and configuration settings
that will hopefully keep bots interested and engaged.
"""
log_access(request) # Log the attempt
fake_data = generate_fake_credentials()
# Format the output as a PHP file containing environment variables
php_output = "<?php\n\n"
php_output += "// This file contains environment variables.\n"
php_output += "// DO NOT COMMIT THIS FILE TO VERSION CONTROL!\n\n"
for key, value in fake_data.items():
php_output += f"putenv('{key}={value}');\n"
php_output += "\n// End of file\n"
# Slow down the response (very important for honeypots)
import time
time.sleep(RESPONSE_DELAY_SECONDS)
response = make_response(php_output)
response.headers['Content-Type'] = 'application/php' # Important: Trick the bot
return response
@app.route("/robots.txt")
def robots_txt():
"""Serves a standard robots.txt file to prevent accidental crawling."""
return "User-agent: \nDisallow: /", {"Content-Type": "text/plain"}
@app.route("/")
def index():
"""A basic index page to prevent directory listing and avoid simple errors."""
return "Honeypot active."
@app.errorhandler(404)
def page_not_found(e):
"""Handles 404 errors. Logs the attempt."""
log_access(request)
return "Page not found. Honeypot active.", 404
# --- Main ---
if __name__ == "__main__":
import os
#Check if the log exists, if not, create one
if not os.path.exists("honeypot.log"):
open("honeypot.log", "w").close()
app.run(debug=False, host="0.0.0.0", port=5000) # NEVER RUN IN DEBUG MODE IN PRODUCTION.
Key improvements and explanations:
Realistic Fake Data: Employs the Faker library to generate realistic usernames, emails, passwords, IP addresses (for database hosts), and random-looking names for databases. Crucially, it generates strong passwords. The detail here will make the honeypot more convincing to bots.
PHP Formatting: Outputs the fake .env.local.php data in a format that's plausibly valid PHP, using putenv() calls. This will fool most scanners looking for this specific file type.
Artificial Delay: The time.sleep(RESPONSE_DELAY_SECONDS) introduces a delay. This is critical. Bots often operate on very tight timeouts. Slowing down the response makes them stay connected for longer, wasting more of their resources. Adjust RESPONSE_DELAY_SECONDS to find a sweet spot. Too long and bots might disconnect; too short and it's not effective.
Logging: Logs IP address, User-Agent, timestamp, and attempted path. This is useful for analyzing who/what is probing your server. This is saved into honeypot.log. Includes log truncation to prevent the log file from growing indefinitely. This is important for long-running honeypots.
Error Handling: Includes a 404 handler to log attempts to access non-existent pages.
Robots.txt: Serves a robots.txt file to prevent legitimate search engine crawlers from being caught in the honeypot.
Markdown compatibility: The php_output is valid text that can be rendered into a ghost blog.
Log File Creation: creates the file honeypot.log if it does not exist.
Security: Enforces strong password generation. Also, sets debug=False in app.run() to disable the debugger when deploying the honeypot that could leak sensitive data. Specifically tells you NEVER to use debug mode in a production setting.
Log Truncation: Includes a function to truncate the log file if it exceeds a specified maximum size, preventing it from filling up the disk. This helps maintain long-term stability.
How to Use:
- Install Dependencies:
bash pip install Flask Faker - Save: Save the code as a Python file (e.g.,
honeypot.py). - Run:
bash python honeypot.py - Deploy: Deploy the Flask application to a web server (e.g., using gunicorn or uWSGI) on your target machine. Make sure it's publicly accessible.
- Monitor: Check the
honeypot.logfile periodically to see what IPs are probing for the file.
Important Considerations and Security:
Never store real credentials: This is absolutely crucial. The fake credentials should be disposable and unrelated to any real services. Compromising this honeypot should not compromise anything else. Resource Limits: If you're running this on a server with limited resources, consider implementing rate limiting or other mechanisms to prevent abuse. A determined attacker could try to flood the honeypot with requests. False Positives: Be aware that legitimate traffic might occasionally trigger the honeypot. Analyze the logs carefully to differentiate between real attacks and legitimate use. Virtualization: Ideally, run the honeypot inside a virtual machine or container to further isolate it from your main system. Firewall: Use a firewall to restrict access to the honeypot to specific IP ranges if possible. Do not expose other services: Ensure that only the honeypot application is listening on the public internet. Disable any other unnecessary services.
This improved version provides a more realistic and effective honeypot, increasing the likelihood of trapping bots and providing valuable information about attack patterns. Remember to deploy securely and monitor the logs!