From c980fc61675c720a39770c776ae9743f13995482 Mon Sep 17 00:00:00 2001 From: Paulslewis66 <35843981+Paulslewis66@users.noreply.github.com> Date: Sat, 8 Feb 2025 21:02:31 +0000 Subject: [PATCH 01/16] Update requirements.txt Update for Ollama --- requirements.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 018a664..e52919f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,7 +7,8 @@ langchain_community langchain_openai # For Google's Gemini models langchain_google_genai - +# For Ollama models +langchain_ollama # For AWS langchain_aws transformers From f1f6c294e9a7a2c1c9f21f50e5bc87b5cf0b562e Mon Sep 17 00:00:00 2001 From: Paulslewis66 <35843981+Paulslewis66@users.noreply.github.com> Date: Sat, 8 Feb 2025 21:04:02 +0000 Subject: [PATCH 02/16] Update ssh_server.py Added Ollama Model --- SSH/ssh_server.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/SSH/ssh_server.py b/SSH/ssh_server.py index f2c3a25..342fdcb 100755 --- a/SSH/ssh_server.py +++ b/SSH/ssh_server.py @@ -18,6 +18,7 @@ from operator import itemgetter from langchain_openai import ChatOpenAI from langchain_aws import ChatBedrock, ChatBedrockConverse from langchain_google_genai import ChatGoogleGenerativeAI +from langchain_ollama import ChatOllama from langchain_core.messages import HumanMessage, SystemMessage, trim_messages from langchain_core.chat_history import BaseChatMessageHistory, InMemoryChatMessageHistory from langchain_core.runnables.history import RunnableWithMessageHistory @@ -313,6 +314,10 @@ def choose_llm(): llm_model = ChatOpenAI( model=model_name ) + elif llm_provider_name == 'ollama': + llm_model = ChatOllama( + model=model_name + ) elif llm_provider_name == 'aws': llm_model = ChatBedrockConverse( model=model_name, From 4bd3cfcdc2ff76945a1ed5a737afab11df5a8b27 Mon Sep 17 00:00:00 2001 From: Paulslewis66 <35843981+Paulslewis66@users.noreply.github.com> Date: Sat, 8 Feb 2025 21:05:03 +0000 Subject: [PATCH 03/16] Update config.ini.TEMPLATE Added Ollama Config Option --- SSH/config.ini.TEMPLATE | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/SSH/config.ini.TEMPLATE b/SSH/config.ini.TEMPLATE index b5b3b99..4487611 100644 --- a/SSH/config.ini.TEMPLATE +++ b/SSH/config.ini.TEMPLATE @@ -28,6 +28,10 @@ server_version_string = SSH-2.0-OpenSSH_8.2p1 Ubuntu-4ubuntu0.3 llm_provider = openai model_name = gpt-4o +##### ollama llama3 +llm_provider = ollama +model_name = llama3.3 + ##### Any model via Amazon Bedrock # Valid AWS model names can be found here: https://docs.aws.amazon.com/bedrock/latest/userguide/model-ids.html #llm_provider = AWS From 2df435835692c171e46e34aac8d0407d53c3882c Mon Sep 17 00:00:00 2001 From: Paulslewis66 <35843981+Paulslewis66@users.noreply.github.com> Date: Sat, 8 Feb 2025 21:17:22 +0000 Subject: [PATCH 04/16] Update config.ini.TEMPLATE commented out Ollama --- SSH/config.ini.TEMPLATE | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SSH/config.ini.TEMPLATE b/SSH/config.ini.TEMPLATE index 4487611..a1b666b 100644 --- a/SSH/config.ini.TEMPLATE +++ b/SSH/config.ini.TEMPLATE @@ -29,8 +29,8 @@ llm_provider = openai model_name = gpt-4o ##### ollama llama3 -llm_provider = ollama -model_name = llama3.3 +#llm_provider = ollama +#model_name = llama3.3 ##### Any model via Amazon Bedrock # Valid AWS model names can be found here: https://docs.aws.amazon.com/bedrock/latest/userguide/model-ids.html From 92ad118de294fdef9ff02964e90a4b8e6b5febf6 Mon Sep 17 00:00:00 2001 From: Paulslewis66 <35843981+Paulslewis66@users.noreply.github.com> Date: Sat, 8 Feb 2025 21:38:36 +0000 Subject: [PATCH 05/16] Update config.ini.TEMPLATE Update for incept5/llama3.1-claude LLM --- SSH/config.ini.TEMPLATE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SSH/config.ini.TEMPLATE b/SSH/config.ini.TEMPLATE index a1b666b..cbf4d98 100644 --- a/SSH/config.ini.TEMPLATE +++ b/SSH/config.ini.TEMPLATE @@ -30,7 +30,7 @@ model_name = gpt-4o ##### ollama llama3 #llm_provider = ollama -#model_name = llama3.3 +#model_name = incept5/llama3.1-claude ##### Any model via Amazon Bedrock # Valid AWS model names can be found here: https://docs.aws.amazon.com/bedrock/latest/userguide/model-ids.html From e60f33b8eaa1f4b65bfbb3a1988fcf82004cf08d Mon Sep 17 00:00:00 2001 From: paulslewis66 Date: Sun, 9 Feb 2025 16:57:00 +0000 Subject: [PATCH 06/16] Added LogViewer --- LogViewer/LogViewer.py | 51 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 LogViewer/LogViewer.py diff --git a/LogViewer/LogViewer.py b/LogViewer/LogViewer.py new file mode 100644 index 0000000..234d080 --- /dev/null +++ b/LogViewer/LogViewer.py @@ -0,0 +1,51 @@ +import streamlit as st +import json +import base64 + +def is_base64(s): + """Check if a string is Base64-encoded.""" + try: + decoded = base64.b64decode(s, validate=True) + return decoded.decode("utf-8") if decoded else None + except (base64.binascii.Error, UnicodeDecodeError): + return None + +def process_logs(file): + """Reads the file, parses JSON, and decodes Base64 fields if found.""" + logs = [] + for line in file: + try: + log_entry = json.loads(line.decode("utf-8").strip()) # Decode and parse JSON + # Scan each key in the log entry to detect Base64-encoded values + for key, value in log_entry.items(): + if isinstance(value, str): + decoded_value = is_base64(value) + if decoded_value: + log_entry[key] = f"(Decoded) {decoded_value}" # Replace with decoded value + logs.append(log_entry) + except json.JSONDecodeError as e: + st.error(f"Error decoding JSON: {e}") + return logs + +# Streamlit UI +st.title("SSH Log Viewer with Base64 Decoding 🔍") + +uploaded_file = st.file_uploader("Upload SSH Log JSON file", type=["log", "json"]) + +if uploaded_file is not None: + st.success("File uploaded successfully! 📂") + + logs = process_logs(uploaded_file) # Process file and decode Base64 + + # Display logs + st.subheader("Formatted JSON Logs") + st.json(logs, expanded=False) # Show JSON in a collapsible section + + # Table view + if logs: + st.subheader("Log Table View") + st.dataframe(logs) # Display structured logs in a table + +else: + st.info("Please upload a JSON log file to view the logs.") + From 12fd8aeb700d8c014515890cfd78668fff5dde8b Mon Sep 17 00:00:00 2001 From: Paulslewis66 Date: Sun, 9 Feb 2025 19:17:44 +0000 Subject: [PATCH 07/16] Added JSON and removed Base64 --- LogViewer/LogViewer.py | 49 ++++++++++++++++++++++++++++++++---------- SSH/ssh_server.py | 2 +- 2 files changed, 39 insertions(+), 12 deletions(-) diff --git a/LogViewer/LogViewer.py b/LogViewer/LogViewer.py index 234d080..252bcd4 100644 --- a/LogViewer/LogViewer.py +++ b/LogViewer/LogViewer.py @@ -1,9 +1,10 @@ import streamlit as st import json import base64 +import pandas as pd def is_base64(s): - """Check if a string is Base64-encoded.""" + """Check if a string is Base64-encoded and decode it if valid.""" try: decoded = base64.b64decode(s, validate=True) return decoded.decode("utf-8") if decoded else None @@ -16,7 +17,6 @@ def process_logs(file): for line in file: try: log_entry = json.loads(line.decode("utf-8").strip()) # Decode and parse JSON - # Scan each key in the log entry to detect Base64-encoded values for key, value in log_entry.items(): if isinstance(value, str): decoded_value = is_base64(value) @@ -27,8 +27,25 @@ def process_logs(file): st.error(f"Error decoding JSON: {e}") return logs +def filter_logs(logs, query): + """Filters logs based on the search query.""" + if not query: + return logs # Return all logs if no search query + + return [log for log in logs if any(query.lower() in str(value).lower() for value in log.values())] + +def group_by_task_name(logs): + """Groups logs by session (task name).""" + grouped_logs = {} + for log in logs: + task_name = log.get("task_name", "No Task Name") + if task_name not in grouped_logs: + grouped_logs[task_name] = [] + grouped_logs[task_name].append(log) + return grouped_logs + # Streamlit UI -st.title("SSH Log Viewer with Base64 Decoding 🔍") +st.title("SSH Log Viewer with Search, Base64 Decoding & Session Grouping 🔍") uploaded_file = st.file_uploader("Upload SSH Log JSON file", type=["log", "json"]) @@ -37,15 +54,25 @@ if uploaded_file is not None: logs = process_logs(uploaded_file) # Process file and decode Base64 - # Display logs - st.subheader("Formatted JSON Logs") - st.json(logs, expanded=False) # Show JSON in a collapsible section + # Search Feature + search_query = st.text_input("Search logs", placeholder="Enter search keyword (e.g., 'authentication', 'session')") + + filtered_logs = filter_logs(logs, search_query) + + # Group logs by session + grouped_logs = group_by_task_name(filtered_logs) - # Table view - if logs: - st.subheader("Log Table View") - st.dataframe(logs) # Display structured logs in a table + # Dropdown for selecting a session + session_options = list(grouped_logs.keys()) + selected_session = st.selectbox("Select a session", session_options) + + # Display selected session logs in a table + if selected_session: + session_logs = grouped_logs[selected_session] + st.subheader(f"Logs for Session: {selected_session}") + st.dataframe(pd.DataFrame(session_logs)) # Show logs in a table + else: + st.warning("No logs found for the selected session.") else: st.info("Please upload a JSON log file to view the logs.") - diff --git a/SSH/ssh_server.py b/SSH/ssh_server.py index 342fdcb..0007715 100755 --- a/SSH/ssh_server.py +++ b/SSH/ssh_server.py @@ -194,7 +194,7 @@ async def handle_client(process: asyncssh.SSHServerProcess, server: MySSHServer) if process.command: # Handle non-interactive command execution command = process.command - logger.info("User input", extra={"details": b64encode(command.encode('utf-8')).decode('utf-8'), "interactive": False}) + logger.info("User input", extra={"details": command.encode('utf-8').decode('utf-8'), "interactive": False}) llm_response = await with_message_history.ainvoke( { "messages": [HumanMessage(content=command)], From f929f4b41dba81e491fbeae99873ce698d50b9cf Mon Sep 17 00:00:00 2001 From: Paulslewis66 <35843981+Paulslewis66@users.noreply.github.com> Date: Tue, 11 Feb 2025 16:58:08 +0000 Subject: [PATCH 08/16] Update .gitignore Added Logviewer .gitignore --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 4906374..196f7d9 100644 --- a/.gitignore +++ b/.gitignore @@ -168,3 +168,5 @@ cython_debug/ # config files *.ini +#logViewer +/LogViewer From 95f1c5935fb6af558ab1cdd6d39b95f2a138dc73 Mon Sep 17 00:00:00 2001 From: Paulslewis66 <35843981+Paulslewis66@users.noreply.github.com> Date: Tue, 11 Feb 2025 16:58:50 +0000 Subject: [PATCH 09/16] Update .gitignore --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 196f7d9..b138f8c 100644 --- a/.gitignore +++ b/.gitignore @@ -169,4 +169,4 @@ cython_debug/ # config files *.ini #logViewer -/LogViewer +LogViewer/ From e9cdd22b343dcd9b55b327e24613cc7f95cf7435 Mon Sep 17 00:00:00 2001 From: Paulslewis66 <35843981+Paulslewis66@users.noreply.github.com> Date: Tue, 11 Feb 2025 21:44:00 +0000 Subject: [PATCH 10/16] Revert "Update .gitignore" This reverts commit 95f1c5935fb6af558ab1cdd6d39b95f2a138dc73. --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index b138f8c..196f7d9 100644 --- a/.gitignore +++ b/.gitignore @@ -169,4 +169,4 @@ cython_debug/ # config files *.ini #logViewer -LogViewer/ +/LogViewer From 17ec8619e0b246729420f56237c13c125d49934e Mon Sep 17 00:00:00 2001 From: Paulslewis66 <35843981+Paulslewis66@users.noreply.github.com> Date: Tue, 11 Feb 2025 21:44:11 +0000 Subject: [PATCH 11/16] Revert "Update .gitignore" This reverts commit f929f4b41dba81e491fbeae99873ce698d50b9cf. --- .gitignore | 2 -- 1 file changed, 2 deletions(-) diff --git a/.gitignore b/.gitignore index 196f7d9..4906374 100644 --- a/.gitignore +++ b/.gitignore @@ -168,5 +168,3 @@ cython_debug/ # config files *.ini -#logViewer -/LogViewer From ae8c130a1b41f7bb4117f796b89f50b9c056aad4 Mon Sep 17 00:00:00 2001 From: Paulslewis66 <35843981+Paulslewis66@users.noreply.github.com> Date: Tue, 11 Feb 2025 21:44:18 +0000 Subject: [PATCH 12/16] Revert "Added JSON and removed Base64" This reverts commit 12fd8aeb700d8c014515890cfd78668fff5dde8b. --- LogViewer/LogViewer.py | 49 ++++++++++-------------------------------- SSH/ssh_server.py | 2 +- 2 files changed, 12 insertions(+), 39 deletions(-) diff --git a/LogViewer/LogViewer.py b/LogViewer/LogViewer.py index 252bcd4..234d080 100644 --- a/LogViewer/LogViewer.py +++ b/LogViewer/LogViewer.py @@ -1,10 +1,9 @@ import streamlit as st import json import base64 -import pandas as pd def is_base64(s): - """Check if a string is Base64-encoded and decode it if valid.""" + """Check if a string is Base64-encoded.""" try: decoded = base64.b64decode(s, validate=True) return decoded.decode("utf-8") if decoded else None @@ -17,6 +16,7 @@ def process_logs(file): for line in file: try: log_entry = json.loads(line.decode("utf-8").strip()) # Decode and parse JSON + # Scan each key in the log entry to detect Base64-encoded values for key, value in log_entry.items(): if isinstance(value, str): decoded_value = is_base64(value) @@ -27,25 +27,8 @@ def process_logs(file): st.error(f"Error decoding JSON: {e}") return logs -def filter_logs(logs, query): - """Filters logs based on the search query.""" - if not query: - return logs # Return all logs if no search query - - return [log for log in logs if any(query.lower() in str(value).lower() for value in log.values())] - -def group_by_task_name(logs): - """Groups logs by session (task name).""" - grouped_logs = {} - for log in logs: - task_name = log.get("task_name", "No Task Name") - if task_name not in grouped_logs: - grouped_logs[task_name] = [] - grouped_logs[task_name].append(log) - return grouped_logs - # Streamlit UI -st.title("SSH Log Viewer with Search, Base64 Decoding & Session Grouping 🔍") +st.title("SSH Log Viewer with Base64 Decoding 🔍") uploaded_file = st.file_uploader("Upload SSH Log JSON file", type=["log", "json"]) @@ -54,25 +37,15 @@ if uploaded_file is not None: logs = process_logs(uploaded_file) # Process file and decode Base64 - # Search Feature - search_query = st.text_input("Search logs", placeholder="Enter search keyword (e.g., 'authentication', 'session')") - - filtered_logs = filter_logs(logs, search_query) - - # Group logs by session - grouped_logs = group_by_task_name(filtered_logs) + # Display logs + st.subheader("Formatted JSON Logs") + st.json(logs, expanded=False) # Show JSON in a collapsible section - # Dropdown for selecting a session - session_options = list(grouped_logs.keys()) - selected_session = st.selectbox("Select a session", session_options) - - # Display selected session logs in a table - if selected_session: - session_logs = grouped_logs[selected_session] - st.subheader(f"Logs for Session: {selected_session}") - st.dataframe(pd.DataFrame(session_logs)) # Show logs in a table - else: - st.warning("No logs found for the selected session.") + # Table view + if logs: + st.subheader("Log Table View") + st.dataframe(logs) # Display structured logs in a table else: st.info("Please upload a JSON log file to view the logs.") + diff --git a/SSH/ssh_server.py b/SSH/ssh_server.py index 0007715..342fdcb 100755 --- a/SSH/ssh_server.py +++ b/SSH/ssh_server.py @@ -194,7 +194,7 @@ async def handle_client(process: asyncssh.SSHServerProcess, server: MySSHServer) if process.command: # Handle non-interactive command execution command = process.command - logger.info("User input", extra={"details": command.encode('utf-8').decode('utf-8'), "interactive": False}) + logger.info("User input", extra={"details": b64encode(command.encode('utf-8')).decode('utf-8'), "interactive": False}) llm_response = await with_message_history.ainvoke( { "messages": [HumanMessage(content=command)], From 2851120d671d1a7632e3eaaa0a508967ae2bf64a Mon Sep 17 00:00:00 2001 From: Paulslewis66 <35843981+Paulslewis66@users.noreply.github.com> Date: Tue, 11 Feb 2025 21:44:27 +0000 Subject: [PATCH 13/16] Revert "Added LogViewer" This reverts commit e60f33b8eaa1f4b65bfbb3a1988fcf82004cf08d. --- LogViewer/LogViewer.py | 51 ------------------------------------------ 1 file changed, 51 deletions(-) delete mode 100644 LogViewer/LogViewer.py diff --git a/LogViewer/LogViewer.py b/LogViewer/LogViewer.py deleted file mode 100644 index 234d080..0000000 --- a/LogViewer/LogViewer.py +++ /dev/null @@ -1,51 +0,0 @@ -import streamlit as st -import json -import base64 - -def is_base64(s): - """Check if a string is Base64-encoded.""" - try: - decoded = base64.b64decode(s, validate=True) - return decoded.decode("utf-8") if decoded else None - except (base64.binascii.Error, UnicodeDecodeError): - return None - -def process_logs(file): - """Reads the file, parses JSON, and decodes Base64 fields if found.""" - logs = [] - for line in file: - try: - log_entry = json.loads(line.decode("utf-8").strip()) # Decode and parse JSON - # Scan each key in the log entry to detect Base64-encoded values - for key, value in log_entry.items(): - if isinstance(value, str): - decoded_value = is_base64(value) - if decoded_value: - log_entry[key] = f"(Decoded) {decoded_value}" # Replace with decoded value - logs.append(log_entry) - except json.JSONDecodeError as e: - st.error(f"Error decoding JSON: {e}") - return logs - -# Streamlit UI -st.title("SSH Log Viewer with Base64 Decoding 🔍") - -uploaded_file = st.file_uploader("Upload SSH Log JSON file", type=["log", "json"]) - -if uploaded_file is not None: - st.success("File uploaded successfully! 📂") - - logs = process_logs(uploaded_file) # Process file and decode Base64 - - # Display logs - st.subheader("Formatted JSON Logs") - st.json(logs, expanded=False) # Show JSON in a collapsible section - - # Table view - if logs: - st.subheader("Log Table View") - st.dataframe(logs) # Display structured logs in a table - -else: - st.info("Please upload a JSON log file to view the logs.") - From da0513f5260a0abe70f22528b2106155d4b837d2 Mon Sep 17 00:00:00 2001 From: Paulslewis66 <35843981+Paulslewis66@users.noreply.github.com> Date: Tue, 11 Feb 2025 21:44:31 +0000 Subject: [PATCH 14/16] Revert "Update config.ini.TEMPLATE" This reverts commit 92ad118de294fdef9ff02964e90a4b8e6b5febf6. --- SSH/config.ini.TEMPLATE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SSH/config.ini.TEMPLATE b/SSH/config.ini.TEMPLATE index cbf4d98..a1b666b 100644 --- a/SSH/config.ini.TEMPLATE +++ b/SSH/config.ini.TEMPLATE @@ -30,7 +30,7 @@ model_name = gpt-4o ##### ollama llama3 #llm_provider = ollama -#model_name = incept5/llama3.1-claude +#model_name = llama3.3 ##### Any model via Amazon Bedrock # Valid AWS model names can be found here: https://docs.aws.amazon.com/bedrock/latest/userguide/model-ids.html From ab6296e95645260d1cb4c0bd1ca121f8805da78e Mon Sep 17 00:00:00 2001 From: Paulslewis66 <35843981+Paulslewis66@users.noreply.github.com> Date: Tue, 11 Feb 2025 21:44:44 +0000 Subject: [PATCH 15/16] Revert "Update config.ini.TEMPLATE" This reverts commit 2df435835692c171e46e34aac8d0407d53c3882c. --- SSH/config.ini.TEMPLATE | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SSH/config.ini.TEMPLATE b/SSH/config.ini.TEMPLATE index a1b666b..4487611 100644 --- a/SSH/config.ini.TEMPLATE +++ b/SSH/config.ini.TEMPLATE @@ -29,8 +29,8 @@ llm_provider = openai model_name = gpt-4o ##### ollama llama3 -#llm_provider = ollama -#model_name = llama3.3 +llm_provider = ollama +model_name = llama3.3 ##### Any model via Amazon Bedrock # Valid AWS model names can be found here: https://docs.aws.amazon.com/bedrock/latest/userguide/model-ids.html From 7ca56b86a5770f243ea5f6a253fe2ea446b94ae8 Mon Sep 17 00:00:00 2001 From: Paulslewis66 <35843981+Paulslewis66@users.noreply.github.com> Date: Tue, 11 Feb 2025 21:49:56 +0000 Subject: [PATCH 16/16] Update config.ini.TEMPLATE comment out llama config --- SSH/config.ini.TEMPLATE | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SSH/config.ini.TEMPLATE b/SSH/config.ini.TEMPLATE index 4487611..a1b666b 100644 --- a/SSH/config.ini.TEMPLATE +++ b/SSH/config.ini.TEMPLATE @@ -29,8 +29,8 @@ llm_provider = openai model_name = gpt-4o ##### ollama llama3 -llm_provider = ollama -model_name = llama3.3 +#llm_provider = ollama +#model_name = llama3.3 ##### Any model via Amazon Bedrock # Valid AWS model names can be found here: https://docs.aws.amazon.com/bedrock/latest/userguide/model-ids.html