From 46a958aea849e64ac74dc8ea7990b03b587f5287 Mon Sep 17 00:00:00 2001 From: "David J. Bianco" Date: Fri, 10 Jan 2025 15:46:42 -0500 Subject: [PATCH] Changed project name and expanded docs * Project is now called DECEIVE, so the README.md has been updated to reflect this * Added more details about installation, configuration, host platform support, and logging to the README.md --- README.md | 71 ++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 57 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 4cf911d..d430c10 100644 --- a/README.md +++ b/README.md @@ -1,22 +1,30 @@ -# HADES +# DECEIVE -HADES, the **Honeypot And Deception Emulation System**, is a high-interaction, low-effort honeypot system. Unlike most high-interaction honeypots, HADES doesn't provide attackers with access to any actual system. AI actually does all the work of simulating a realistic honeypot system based on a configurable system prompt that describes what type of system you want to simulate. Unlike many other high-interaction honeypots which require substantial effort to seed with realistic users, data, and applications, HADES's AI backend will do all this for you, automatically. +DECEIVE, the **Deceptive Emulation with Evaluative Integrated Validation Engine**, is a high-interaction, low-effort honeypot system. Unlike most high-interaction honeypots, DECEIVE doesn't provide attackers with access to any actual system. AI actually does all the work of simulating a realistic honeypot system based on a configurable system prompt that describes what type of system you want to simulate. Unlike many other high-interaction honeypots which require substantial effort to seed with realistic users, data, and applications, DECEIVE's AI backend will do all this for you, automatically. -This version of HADES simulates a Linux server via the SSH protocol. +This version of DECEIVE simulates a Linux server via the SSH protocol. It will log all the user inputs, the outputs returned by the LLM backend, as well as a summary of each session after they end. It'll even tell you if it thinks a users' session was benign, suspicious, or outright malicious. + +## Supported Host Platforms +DECEIVE is primarily developed on MacOS 15 (Sequoia), but it should work on any UNIX-like system which can run Python3. This includes other versions of MacOS, Linux, and even Windows (via Windows Subsystem for Linux). ## Setup +### Check out the latest code from GitHub +You can fetch the latest version using the following command: + + git clone https://github.com/splunk/DECEIVE + +The rest of these instructions assume you have changed your current directory to the repo after cloning completes. + ### Install Dependencies -Ensure you have Python3 installed. Then, install the required dependencies: +Ensure you have Python3 installed. We recommend running DECEIVE in it's own Python virtualenv but it is not required. - pip install -r requirements.txt +Next, install the Python modules the honeypot needs: -## Configuration - -Before running HADES, you need to configure it properly. Follow these steps: + pip3 install -r requirements.txt ### Generate the SSH Host Key -The SSH server requires a TLS keypair for security communications. You can generate an SSH keypair using the following command: +The SSH server requires a TLS keypair for security communications. From the top directory of the repo, generate an SSH keypair using the following command: ssh-keygen -t rsa -b 4096 -f SSH/ssh_host_key @@ -26,14 +34,18 @@ The SSH server requires a TLS keypair for security communications. You can gener ### Edit the Configuration File -Open the `SSH/config.ini` file and review the settings. Update the values as needed, paying special attention to the values in the `[llm]` and `[user_accounts]` sections. +Open the `SSH/config.ini` file and review the settings. Update the values as needed, paying special attention to the values in the `[llm]` section, where you will configure the LLM backend you wish to use, and to the `[user_accounts]` section, where you can configure the usernames and passwords you'd like the honeypot to support. -## Execution -To start the HADES honeypot server, change to the `SSH` directory and run the following command: +## Running the Honeypot +To start the DECEIVE honeypot server, first make sure that you have set any environment variables required by your chosen LLM backend. For example, if you are using any of the OpenAI models, you will need to set the `OPENAI_API_KEY` variable like so: + + export OPENAI_API_KEY=" + +Next, change to the `SSH` directory and run the following command: python3 ./ssh_server.py -The server will start and listen for incoming SSH connections on the configured port. +The server will start and listen for incoming SSH connections on the configured port. It will not produce any output, but will stay executing in the foreground. ## Test it Out Once the server is running (this can take a few seconds), access it on the configured port. If you are on a Linux or UNIX-like system, try the following command (substitute "localhost" and "8022" as appropriate for your config): @@ -41,7 +53,38 @@ Once the server is running (this can take a few seconds), access it on the confi ssh guest@localhost -p 8022 ### Logging -Logs will be written to the file specified in the `log_file` configuration option. Review the logs to monitor honeypot activity. +Logs will be written to the file specified in the `log_file` configuration option. By default, this is `SSH/ssh_log.log`. + +DECEIVE logs are in JSON lines format, with each line being a complete JSON document. + +The following is a complete example of a simple SSH session, in which the user executed two simple commands (`pwd` and `exit`): + +```json +{"timestamp": "2025-01-10T20:37:55.018+00:00", "level": "INFO", "task_name": "-", "src_ip": "::1", "src_port": 58164, "dst_ip": "::1", "dst_port": 8022, "message": "SSH connection received", "name": "__main__", "levelname": "INFO", "levelno": 20, "pathname": "/home/deceive/DECEIVE/SSH/./ssh_server.py", "filename": "ssh_server.py", "module": "ssh_server", "exc_info": null, "exc_text": null, "stack_info": null, "lineno": 59, "funcName": "connection_made", "created": 1736541475.0183098, "msecs": 18.0, "relativeCreated": 13872.790813446045, "thread": 8145041472, "threadName": "MainThread", "processName": "MainProcess", "process": 10823, "taskName": null} +{"timestamp": "2025-01-10T20:37:55.177+00:00", "level": "INFO", "task_name": "Task-5", "src_ip": "::1", "src_port": 58164, "dst_ip": "::1", "dst_port": 8022, "message": "Authentication success", "name": "__main__", "levelname": "INFO", "levelno": 20, "pathname": "/home/deceive/DECEIVE/SSH/./ssh_server.py", "filename": "ssh_server.py", "module": "ssh_server", "exc_info": null, "exc_text": null, "stack_info": null, "lineno": 75, "funcName": "begin_auth", "created": 1736541475.1775439, "msecs": 177.0, "relativeCreated": 14032.02486038208, "thread": 8145041472, "threadName": "MainThread", "processName": "MainProcess", "process": 10823, "taskName": "Task-5", "username": "guest", "password": ""} +{"timestamp": "2025-01-10T20:37:57.456+00:00", "level": "INFO", "task_name": "session-6355218b-59e5-4549-add3-49e6d1efc133", "src_ip": "::1", "src_port": 58164, "dst_ip": "::1", "dst_port": 8022, "message": "LLM response", "name": "__main__", "levelname": "INFO", "levelno": 20, "pathname": "/home/deceive/DECEIVE/SSH/./ssh_server.py", "filename": "ssh_server.py", "module": "ssh_server", "exc_info": null, "exc_text": null, "stack_info": null, "lineno": 174, "funcName": "handle_client", "created": 1736541477.4568708, "msecs": 456.0, "relativeCreated": 16311.351776123047, "thread": 8145041472, "threadName": "MainThread", "processName": "MainProcess", "process": 10823, "taskName": "session-6355218b-59e5-4549-add3-49e6d1efc133", "details": "V2VsY29tZSB0byBHYW1lRGV2IENvcnAncyBEZXZlbG9wbWVudCBFbnZpcm9ubWVudAoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICBXZWxjb21lLCBndWVzdCEgCiAgIExhc3QgbG9naW46IFR1ZSBPY3QgMjQgMTQ6MzI6MTUgMjAyMyBmcm9tIDE5Mi4xNjguMS4xMAogICBQcm9qZWN0czoKICAgICAtIEZhbnRhc3lRdWVzdAogICAgIC0gU3BhY2VFeHBsb3JlcnMKICAgICAtIFJhY2luZ01hbmlhCiAgIFN5c3RlbSBTdGF0dXM6IEFsbCBzeXN0ZW1zIG9wZXJhdGlvbmFsCiAgIFJlbWVtYmVyIHRvIGNvbW1pdCB5b3VyIGNoYW5nZXMhCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCmd1ZXN0QGRldi13b3Jrc3RhdGlvbjp+JCA="} +{"timestamp": "2025-01-10T20:37:59.333+00:00", "level": "INFO", "task_name": "session-6355218b-59e5-4549-add3-49e6d1efc133", "src_ip": "::1", "src_port": 58164, "dst_ip": "::1", "dst_port": 8022, "message": "User input", "name": "__main__", "levelname": "INFO", "levelno": 20, "pathname": "/home/deceive/DECEIVE/SSH/./ssh_server.py", "filename": "ssh_server.py", "module": "ssh_server", "exc_info": null, "exc_text": null, "stack_info": null, "lineno": 184, "funcName": "handle_client", "created": 1736541479.3334038, "msecs": 333.0, "relativeCreated": 18187.88480758667, "thread": 8145041472, "threadName": "MainThread", "processName": "MainProcess", "process": 10823, "taskName": "session-6355218b-59e5-4549-add3-49e6d1efc133", "details": "cHdk"} +{"timestamp": "2025-01-10T20:38:00.189+00:00", "level": "INFO", "task_name": "session-6355218b-59e5-4549-add3-49e6d1efc133", "src_ip": "::1", "src_port": 58164, "dst_ip": "::1", "dst_port": 8022, "message": "LLM response", "name": "__main__", "levelname": "INFO", "levelno": 20, "pathname": "/home/deceive/DECEIVE/SSH/./ssh_server.py", "filename": "ssh_server.py", "module": "ssh_server", "exc_info": null, "exc_text": null, "stack_info": null, "lineno": 200, "funcName": "handle_client", "created": 1736541480.189375, "msecs": 189.0, "relativeCreated": 19043.855905532837, "thread": 8145041472, "threadName": "MainThread", "processName": "MainProcess", "process": 10823, "taskName": "session-6355218b-59e5-4549-add3-49e6d1efc133", "details": "L2hvbWUvZ3Vlc3QKCmd1ZXN0QGRldi13b3Jrc3RhdGlvbjp+JCA="} +{"timestamp": "2025-01-10T20:38:01.944+00:00", "level": "INFO", "task_name": "session-6355218b-59e5-4549-add3-49e6d1efc133", "src_ip": "::1", "src_port": 58164, "dst_ip": "::1", "dst_port": 8022, "message": "User input", "name": "__main__", "levelname": "INFO", "levelno": 20, "pathname": "/home/deceive/DECEIVE/SSH/./ssh_server.py", "filename": "ssh_server.py", "module": "ssh_server", "exc_info": null, "exc_text": null, "stack_info": null, "lineno": 184, "funcName": "handle_client", "created": 1736541481.944072, "msecs": 944.0, "relativeCreated": 20798.552989959717, "thread": 8145041472, "threadName": "MainThread", "processName": "MainProcess", "process": 10823, "taskName": "session-6355218b-59e5-4549-add3-49e6d1efc133", "details": "ZXhpdA=="} +{"timestamp": "2025-01-10T20:38:04.132+00:00", "level": "INFO", "task_name": "session-6355218b-59e5-4549-add3-49e6d1efc133", "src_ip": "::1", "src_port": 58164, "dst_ip": "::1", "dst_port": 8022, "message": "Session summary", "name": "__main__", "levelname": "INFO", "levelno": 20, "pathname": "/home/deceive/DECEIVE/SSH/./ssh_server.py", "filename": "ssh_server.py", "module": "ssh_server", "exc_info": null, "exc_text": null, "stack_info": null, "lineno": 151, "funcName": "session_summary", "created": 1736541484.1324642, "msecs": 132.0, "relativeCreated": 22986.945152282715, "thread": 8145041472, "threadName": "MainThread", "processName": "MainProcess", "process": 10823, "taskName": "session-6355218b-59e5-4549-add3-49e6d1efc133", "details": "The user issued basic commands like `pwd` to check the current working directory and `exit` to terminate the session. This activity is typical of a benign user checking their environment upon logging in and then closing the session. There is no indication of reconnaissance, exploitation, or any post-foothold activity such as privilege escalation or data exfiltration. The actions appear to be standard and routine.\n\nJudgement: BENIGN", "judgement": "BENIGN"} +{"timestamp": "2025-01-10T20:38:04.139+00:00", "level": "INFO", "task_name": "-", "src_ip": "::1", "src_port": 58164, "dst_ip": "::1", "dst_port": 8022, "message": "SSH connection closed", "name": "__main__", "levelname": "INFO", "levelno": 20, "pathname": "/home/deceive/DECEIVE/SSH/./ssh_server.py", "filename": "ssh_server.py", "module": "ssh_server", "exc_info": null, "exc_text": null, "stack_info": null, "lineno": 65, "funcName": "connection_lost", "created": 1736541484.139776, "msecs": 139.0, "relativeCreated": 22994.2569732666, "thread": 8145041472, "threadName": "MainThread", "processName": "MainProcess", "process": 10823, "taskName": null} +``` + +Things to note: +* Timestamps are always in UTC. UTC||GTFO! +* The `task_name` field contains a unique value that can be used to associate all the entries from a single SSH session. +* The "message" field will tell you what type of entry this: + * `SSH connection received` + * `Authentication success` + * `User input` + * `LLM response` + * `Session summary` + * `SSH connection closed` +* Several of these message types also feature a `details` field with additional information + * `User input` messages contain a base64-encoded copy of the entire user input + * `LLM response` messages contain a base64-encoded copy of the entire simulated response + * `Session summary` messages contain not only a summary of the commands, but also a guess as to what they might have been intended to accomplish. There will also be a `judgement` field that contains one of "BENIGN", "SUSPICIOUS", or "MALICIOUS" +* Since this is a honeypot and not intended for use by real users, IT WILL LOG USERNAMES AND PASSWORDS! These are found in the `Authentication success` messages, in the `username` and `password` fields. ### Contributing Contributions are welcome! Please submit pull requests or open issues to discuss any changes or improvements.