mirror of
https://github.com/schwartz1375/genai-essentials
synced 2026-08-09 13:08:20 +00:00
- Switch from nomic-embed-text to embeddinggemma for embeddings - Add directory verification cells to ensure required directories exist - Add error handling for corrupted ChromaDB databases with auto-recovery - Create persist directories before ChromaDB initialization
99 KiB
99 KiB
In [1]:
'''
!pip install --upgrade pip --quiet
!pip install -U \
langchain langchain-ollama langchain-community langchain-core \
langchain-experimental chromadb pandas pymupdf ipython \
duckduckgo-search --quiet
'''Out [1]:
'\n!pip install --upgrade pip --quiet\n!pip install -U langchain langchain-ollama langchain-community langchain-core langchain-experimental chromadb pandas pymupdf ipython duckduckgo-search --quiet\n'
In [2]:
from IPython.display import Markdown
from langchain_ollama import ChatOllama
# Note: Ensure Ollama is running locally and the gemma3 model is installed
# Run: ollama pull gemma3
# If Ollama is not running, you'll get a connection error
llm = ChatOllama(
model="gemma3",
temperature=0.8,
# base_url="http://remote-ip:port", # Ollama default port: 11434
# timeout=5,
num_predict=256, # Use num_predict instead of max_tokens for Ollama
# other params ...
)
messages = [
("system", "You are a helpful assistant."),
("human", "why is the sky blue?"),
]
Markdown(llm.invoke(messages).content)Out [2]:
<IPython.core.display.Markdown object>
In [3]:
from langchain_core.prompts import ChatPromptTemplate
from langchain_ollama.llms import OllamaLLM
template = """Question: {question}
Answer: Let's think step by step."""
prompt = ChatPromptTemplate.from_template(template)
model = OllamaLLM(model="gemma3")
chain = prompt | model
Markdown(chain.invoke({"question": "System: You are cybersecurity expert, and AI assisant to AWS.\n\nHuman: What is the LummaC2 malware?"}))Out [3]:
<IPython.core.display.Markdown object>
In [4]:
Markdown(llm.invoke("System: You are cybersecurity expert, and AI assisant.\n\nHuman: What industry was primarily targeted by this malware?").content)Out [4]:
<IPython.core.display.Markdown object>
In [5]:
from langchain_community.llms import Ollama
from langchain.chains import ConversationChain
from langchain.memory import ConversationBufferMemory
import pandas as pd
import warnings
warnings.filterwarnings("ignore")
# Initialize Ollama with Gemma model
llm = Ollama(model="gemma3")In [6]:
# Set up conversation memory
cbm_memory = ConversationBufferMemory()
# Adding memory to a conversational chain
chain_with_buffer_memory = ConversationChain(llm=llm, memory=cbm_memory)
# Helper function to prompt and print memory state
def prompt_and_print_memory(prompts, chain_with_memory):
# Store the responses
responses = {"input": [], "history": [], "response": []}
# Repeatedly prompting the chain and observing the memory
for prompt in prompts:
response = chain_with_memory.invoke({"input": prompt})
responses["input"].append(prompt)
responses["history"].append(cbm_memory.load_memory_variables({}))
responses["response"].append(response["response"])
# Display responses in a dataframe
df = pd.DataFrame.from_dict(responses)
with pd.option_context("display.max_colwidth", None):
display(df)
# Sequence of prompts for demonstration
cbm_prompts = [
"What is the LummaC2 malware?",
"What industry was primarily targeted by this malware?",
]
# Invoke helper function
prompt_and_print_memory(cbm_prompts, chain_with_buffer_memory)
| input | history | response | |
|---|---|---|---|
| 0 | What is the LummaC2 malware? | {'history': 'Human: What is the LummaC2 malware? AI: Okay, let’s talk about LummaC2! It’s a really interesting and quite sophisticated piece of malware that’s been tracked by analysts at Sophos. Essentially, it's a modular, multi-stage post-exploitation framework primarily targeting Windows systems. Here’s a breakdown of what makes it notable: * **Developed by the Chinese APT group, UNC3923:** Sophos has linked it very strongly to this group, which is known for its espionage activities, often targeting the energy, defense, and technology sectors. They’ve been tracking this group for a *long* time – back to 2018 – and LummaC2 is a key component of their toolkit. * **Modular Design:** This is a *big* deal. LummaC2 isn't just one piece of malware; it’s composed of several modules that can be used individually or combined. This makes it highly adaptable and difficult to detect. The main modules include: * **Beacon:** This is the core module. It’s a C2 (Command and Control) beacon that allows the attackers to communicate with the infected host. It uses TLS encryption for secure communication – they’re not sending data in the clear. The beacon itself utilizes multiple protocols – HTTP, HTTPS, and even DNS – to evade detection. * **Credential Dumping:** This module attempts to steal credentials (usernames, passwords, hashes) from the infected system. They've been observed using tools like Mimikatz – a very common tool for credential theft. * **Process Injection:** They use this to inject malicious code into legitimate running processes, further expanding their control over the system. * **Privilege Escalation:** LummaC2 attempts to escalate privileges on the infected system, allowing them to gain higher levels of control. * **Lateral Movement:** This is crucial. Once they have control of one machine, they use it to move laterally across the network, compromising other systems. They’ve been observed using tools like PsExec for this. * **TLS Encryption:** As I mentioned before, the beacon uses TLS (Transport Layer Security) encryption. This makes it harder for security analysts to monitor the communication and understand what the malware is doing in real-time. * **Observed Targets:** They’ve been actively targeting companies in the defense, energy, and technology sectors – specifically those with a global presence. * **Sophos Tracking:** Sophos has been diligently tracking LummaC2's activity since 2021, publishing detailed reports on its behavior and associated IOCs (Indicators of Compromise) – like IP addresses, domains, and file hashes – that security teams can use to detect and block the malware. They even have a dedicated threat feed for LummaC2. You can find a lot of detailed information on their website here: [https://www.sophos.com/threat-center/lummac2.html](https://www.sophos.com/threat-center/lummac2.html) Do you want me to delve deeper into a specific aspect of LummaC2, such as its modules, the IOCs, or how Sophos tracks it? Or perhaps you’d like to discuss how to defend against attacks from this group?'} | Okay, let’s talk about LummaC2! It’s a really interesting and quite sophisticated piece of malware that’s been tracked by analysts at Sophos. Essentially, it's a modular, multi-stage post-exploitation framework primarily targeting Windows systems.\n\nHere’s a breakdown of what makes it notable:\n\n* **Developed by the Chinese APT group, UNC3923:** Sophos has linked it very strongly to this group, which is known for its espionage activities, often targeting the energy, defense, and technology sectors. They’ve been tracking this group for a *long* time – back to 2018 – and LummaC2 is a key component of their toolkit.\n\n* **Modular Design:** This is a *big* deal. LummaC2 isn't just one piece of malware; it’s composed of several modules that can be used individually or combined. This makes it highly adaptable and difficult to detect. The main modules include:\n * **Beacon:** This is the core module. It’s a C2 (Command and Control) beacon that allows the attackers to communicate with the infected host. It uses TLS encryption for secure communication – they’re not sending data in the clear. The beacon itself utilizes multiple protocols – HTTP, HTTPS, and even DNS – to evade detection.\n * **Credential Dumping:** This module attempts to steal credentials (usernames, passwords, hashes) from the infected system. They've been observed using tools like Mimikatz – a very common tool for credential theft.\n * **Process Injection:** They use this to inject malicious code into legitimate running processes, further expanding their control over the system.\n * **Privilege Escalation:** LummaC2 attempts to escalate privileges on the infected system, allowing them to gain higher levels of control.\n * **Lateral Movement:** This is crucial. Once they have control of one machine, they use it to move laterally across the network, compromising other systems. They’ve been observed using tools like PsExec for this.\n\n* **TLS Encryption:** As I mentioned before, the beacon uses TLS (Transport Layer Security) encryption. This makes it harder for security analysts to monitor the communication and understand what the malware is doing in real-time.\n\n* **Observed Targets:** They’ve been actively targeting companies in the defense, energy, and technology sectors – specifically those with a global presence.\n\n* **Sophos Tracking:** Sophos has been diligently tracking LummaC2's activity since 2021, publishing detailed reports on its behavior and associated IOCs (Indicators of Compromise) – like IP addresses, domains, and file hashes – that security teams can use to detect and block the malware. They even have a dedicated threat feed for LummaC2. You can find a lot of detailed information on their website here: [https://www.sophos.com/threat-center/lummac2.html](https://www.sophos.com/threat-center/lummac2.html)\n\nDo you want me to delve deeper into a specific aspect of LummaC2, such as its modules, the IOCs, or how Sophos tracks it? Or perhaps you’d like to discuss how to defend against attacks from this group? |
| 1 | What industry was primarily targeted by this malware? | {'history': 'Human: What is the LummaC2 malware? AI: Okay, let’s talk about LummaC2! It’s a really interesting and quite sophisticated piece of malware that’s been tracked by analysts at Sophos. Essentially, it's a modular, multi-stage post-exploitation framework primarily targeting Windows systems. Here’s a breakdown of what makes it notable: * **Developed by the Chinese APT group, UNC3923:** Sophos has linked it very strongly to this group, which is known for its espionage activities, often targeting the energy, defense, and technology sectors. They’ve been tracking this group for a *long* time – back to 2018 – and LummaC2 is a key component of their toolkit. * **Modular Design:** This is a *big* deal. LummaC2 isn't just one piece of malware; it’s composed of several modules that can be used individually or combined. This makes it highly adaptable and difficult to detect. The main modules include: * **Beacon:** This is the core module. It’s a C2 (Command and Control) beacon that allows the attackers to communicate with the infected host. It uses TLS encryption for secure communication – they’re not sending data in the clear. The beacon itself utilizes multiple protocols – HTTP, HTTPS, and even DNS – to evade detection. * **Credential Dumping:** This module attempts to steal credentials (usernames, passwords, hashes) from the infected system. They've been observed using tools like Mimikatz – a very common tool for credential theft. * **Process Injection:** They use this to inject malicious code into legitimate running processes, further expanding their control over the system. * **Privilege Escalation:** LummaC2 attempts to escalate privileges on the infected system, allowing them to gain higher levels of control. * **Lateral Movement:** This is crucial. Once they have control of one machine, they use it to move laterally across the network, compromising other systems. They’ve been observed using tools like PsExec for this. * **TLS Encryption:** As I mentioned before, the beacon uses TLS (Transport Layer Security) encryption. This makes it harder for security analysts to monitor the communication and understand what the malware is doing in real-time. * **Observed Targets:** They’ve been actively targeting companies in the defense, energy, and technology sectors – specifically those with a global presence. * **Sophos Tracking:** Sophos has been diligently tracking LummaC2's activity since 2021, publishing detailed reports on its behavior and associated IOCs (Indicators of Compromise) – like IP addresses, domains, and file hashes – that security teams can use to detect and block the malware. They even have a dedicated threat feed for LummaC2. You can find a lot of detailed information on their website here: [https://www.sophos.com/threat-center/lummac2.html](https://www.sophos.com/threat-center/lummac2.html) Do you want me to delve deeper into a specific aspect of LummaC2, such as its modules, the IOCs, or how Sophos tracks it? Or perhaps you’d like to discuss how to defend against attacks from this group? Human: What industry was primarily targeted by this malware? AI: Okay, great question! While LummaC2 has been observed targeting a *range* of industries, the primary targets have consistently been the defense, energy, and technology sectors. As I mentioned before, Sophos has specifically noted a strong focus on companies with a global presence within those industries. They’ve seen a significant number of campaigns directed at organizations involved in defense technology – think things like missile defense systems or cybersecurity products – and companies involved in energy production and distribution. It's not that other industries weren't *ever* targeted, but those three were the most frequent and impactful. Do you want me to elaborate on *why* these sectors were particularly attractive to UNC3923, or perhaps discuss the specific types of data they were seeking within those industries? Or would you like me to go back and explain a particular module in more detail, like the lateral movement capabilities?'} | Okay, great question! While LummaC2 has been observed targeting a *range* of industries, the primary targets have consistently been the defense, energy, and technology sectors. As I mentioned before, Sophos has specifically noted a strong focus on companies with a global presence within those industries. They’ve seen a significant number of campaigns directed at organizations involved in defense technology – think things like missile defense systems or cybersecurity products – and companies involved in energy production and distribution. It's not that other industries weren't *ever* targeted, but those three were the most frequent and impactful.\n\nDo you want me to elaborate on *why* these sectors were particularly attractive to UNC3923, or perhaps discuss the specific types of data they were seeking within those industries? Or would you like me to go back and explain a particular module in more detail, like the lateral movement capabilities? |
In [7]:
from langchain.tools import Tool
from langchain_community.tools import DuckDuckGoSearchRun
# Define the API wrapper for DuckDuckGo search
duckduckgo_search = DuckDuckGoSearchRun()
# Define the DuckDuckGo tool using a description and the function to retrieve results from DuckDuckGo search
duckduckgo_tool = Tool(
name="DuckDuckGoSearch",
func=duckduckgo_search.run,
description="useful for when you need to answer questions about current weather and other current events",
)
# Test the DuckDuckGo tool
Markdown(duckduckgo_tool("What is a honeybee?"))Out [7]:
<IPython.core.display.Markdown object>
In [8]:
from langchain.tools import tool
from datetime import date
@tool
def curr_date(text: str) -> str:
"""Returns todays date, use this for any \
questions related to knowing todays date. \
The input should always be an empty string, \
and this function will always return todays \
date - any date math should occur \
outside this function."""
return str(date.today())In [9]:
# Define the date tool
date_tool = Tool(
name="DateTool", func=curr_date, description="Useful to retrieve the current date"
)
# Test date tool
print(date_tool(""))2025-12-06
In [10]:
from langchain_experimental.tools import PythonREPLTool
from langchain.agents import AgentType
from langchain.agents import initialize_agent
from IPython.display import Markdown
llm = ChatOllama(
model="gemma3",
temperature=0.1,
num_predict=256, # Use num_predict instead of max_tokens for Ollama
)
# Define the Python REPL tool
python_repl = PythonREPLTool()
# Initialize the agent using the local model and the Python REPL tool
python_agent = initialize_agent(
[python_repl],
llm, # Using our previously initialized Ollama Gemma model here
agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION,
verbose=True,
handle_parsing_errors=True,
)
# Test the Python Agent with a simple input
result = python_agent.invoke(
{"input": "How many dots are in the string ......................................?"}
)
# Display the result using Markdown
Markdown(result['output'])Out [10]:
[1m> Entering new AgentExecutor chain...[0m
Python REPL can execute arbitrary code. Use with caution.
[32;1m[1;3mThought: The string contains a series of dots. I need to count the number of dots. Action: Python_REPL Action Input: `string = "....................................."; print(len(string))`[0m Observation: [36;1m[1;3m37 [0m Thought:[32;1m[1;3mThought: I now know the final answer Final Answer: 37[0m [1m> Finished chain.[0m
<IPython.core.display.Markdown object>
In [11]:
from langchain.agents import initialize_agent
# Define a list of available tools for the agent
tools = [
duckduckgo_tool,
date_tool,
]
# Initialize the agent with access to all the tooks in the list
agent_executor = initialize_agent(
tools,
llm,
agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION,
verbose=True,
handle_parsing_errors=True,
)In [12]:
agent_executor.invoke(
{
"input": """
System: You are not good at determining dates and times. When you are asked about weather reports, you should first make sure you know what date is being asked about.
If you are asked about weather and a day was not specified, you should use the date_tool to get today's date and then use the duckduckgo_tool to find out the weather for the date.
When asking about weather, you should always include the date in your search for weather so you get the weather report for the correct date.
Human: I am in Washington DC. Will I need an umbrella today?
"""
}
)Out [12]:
[1m> Entering new AgentExecutor chain...[0m [32;1m[1;3mI need to find out the weather in Washington DC today to determine if I need an umbrella. Since the date was not specified, I should use the DateTool to get today's date and then use the DuckDuckGoSearch tool to find the weather for that date. Action: DateTool Action Input: ''[0m Observation: [33;1m[1;3m2025-12-06[0m Thought:[32;1m[1;3mOkay, I now have today's date as 2025-12-06. I will use the DuckDuckGoSearch tool to find the weather in Washington DC for this date. Action: DuckDuckGoSearch Action Input: 'weather Washington DC 2025-12-06'[0m Observation: [36;1m[1;3mIn Washington , a combination of overcast , rain-soaked and dry and sunny weather is expected for the next ten days. On Friday, in Washington , sunrise will be at 7:10 am and sunset at 4:47 pm (EST). ... Updated: Dec 4, 2025 @ 22:17:39 UTC Published by: Weather U.S. Washington , DC 39°F Cloudy- Light rain is expected. ... Delightful, is there generally a big difference in weather between S Scotland and the ... The Weather Channel uses data, cookies and other similar technologies on this browser to optimise our website, and to provide you with weather ... For example, the weather in Washington DC in April 2025 . ... Do you see something missing or inaccurate about the weather in Washington DC ? Feel ...[0m Thought:[32;1m[1;3mI now know the weather in Washington DC on 2025-12-06 is Cloudy- Light rain is expected. Final Answer: Yes, you should probably take an umbrella with you today.[0m [1m> Finished chain.[0m
{'input': "\n System: You are not good at determining dates and times. When you are asked about weather reports, you should first make sure you know what date is being asked about.\n If you are asked about weather and a day was not specified, you should use the date_tool to get today's date and then use the duckduckgo_tool to find out the weather for the date.\n When asking about weather, you should always include the date in your search for weather so you get the weather report for the correct date.\n\n Human: I am in Washington DC. Will I need an umbrella today?\n ",
'output': 'Yes, you should probably take an umbrella with you today.'}In [13]:
import os
import pandas as pd
from IPython.display import Markdown, display
# LangChain imports
from langchain_community.document_loaders import PyMuPDFLoader
from langchain_community.vectorstores import Chroma
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_community.embeddings import OllamaEmbeddings
from langchain.chains import RetrievalQA
from langchain.prompts import PromptTemplate
from langchain_community.llms import Ollama
from chromadb.config import SettingsIn [14]:
from langchain_ollama import OllamaEmbeddings, OllamaLLM
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_community.vectorstores import Chroma
from langchain_core.prompts import PromptTemplate
from langchain.chains import RetrievalQA
from langchain_community.document_loaders import PyMuPDFLoader
import os
from IPython.display import Markdown, display
from langchain_core.documents import Document
# Initialize Ollama LLM (Gemma model)
# Make sure these are pulled once:
# ollama pull gemma3
# ollama pull nomic-embed-text
llm = Ollama(
model="gemma3",
base_url="http://localhost:11434", # explicit, just to be clear
)
# 🔧 Embeddings model: add num_ctx and base_url
embedding_model = OllamaEmbeddings(
model="embeddinggemma",
base_url="http://localhost:11434",
num_ctx=2048, # <= keep context modest to avoid crashes
# you could even try 1024 if needed
)
# Create directory for PDFs
pdf_dir = "./data/pdfs"
os.makedirs(pdf_dir, exist_ok=True)
print(f"PDF directory is at: {os.path.abspath(pdf_dir)}")
# 🔧 Text splitter: smaller chunks
recur_splitter = RecursiveCharacterTextSplitter(
chunk_size=500, # was 1000
chunk_overlap=100, # was 200
separators=["\n\n", "\n", ".", "!", "?", ",", " ", ""],
length_function=len
)
# Load and process PDFs using PyMuPDFLoader for each file in the directory
data = []
for filename in os.listdir(pdf_dir):
if filename.endswith(".pdf"):
loader = PyMuPDFLoader(file_path=os.path.join(pdf_dir, filename))
data.extend(loader.load())
# Ensure there's data, create a demo if not
if len(data) == 0:
data = [
Document(
page_content="Sample text about LummaC2.",
metadata={"source": "sample.pdf", "page": 1},
),
]
# Split documents into chunks
data_splits = recur_splitter.split_documents(data)
# (Optional but helpful debug: quickly sanity-check chunks)
# for i, d in enumerate(data_splits[:3]):
# print(i, len(d.page_content))
# Create ChromaDB vector store (persists locally)
os.makedirs("./chroma_llm_training", exist_ok=True)
vectordb = Chroma.from_documents(
documents=data_splits,
embedding=embedding_model,
collection_name="rag-demo",
persist_directory="./chroma_llm_training"
)
# Define RAG QA prompt template
qa_template = """
You are a helpful assistant answering questions based on the provided context.
Use the following pieces of context to answer the user's question. If unsure, state you don't know.
Context:
{context}
Question: {question}
Answer:
"""
qa_prompt_template = PromptTemplate.from_template(qa_template)
# Define RetrievalQA chain
qa_chain = RetrievalQA.from_chain_type(
llm=llm,
retriever=vectordb.as_retriever(search_kwargs={"k": 5}),
return_source_documents=True,
chain_type="stuff",
chain_type_kwargs={"prompt": qa_prompt_template},
)
# Test questions
questions = [
"What is LummaC2?",
"What is a ClickFix?",
"Why is the sky blue?"
]
# Run questions through the QA chain
for question in questions:
print(f"\nQuestion: {question}")
response = qa_chain({"query": question})
display(Markdown(response["result"]))
print("\nSources:")
seen_sources = set()
for doc in response["source_documents"][:2]:
source_info = f"{os.path.basename(doc.metadata['source'])}, Page {doc.metadata.get('page', 'N/A')}"
if source_info not in seen_sources:
print(source_info)
seen_sources.add(source_info)
PDF directory is at: /Users/schwartz/src/genai-essentials/data/pdfs Question: What is LummaC2?
<IPython.core.display.Markdown object>
Sources: aa25-141b-threat-actors-deploy-lummac2-malware-to-exfiltrate-sensitive-data-from-organizations.pdf, Page 1 aa25-141b-threat-actors-deploy-lummac2-malware-to-exfiltrate-sensitive-data-from-organizations.pdf, Page 7 Question: What is a ClickFix?
<IPython.core.display.Markdown object>
Sources: clickfix-attacks-sector-alert-tlpclear.pdf, Page 0 Question: Why is the sky blue?
<IPython.core.display.Markdown object>
Sources: clickfix-attacks-sector-alert-tlpclear.pdf, Page 1 joint-guidance-enhanced-visibility-hardening-guide-for-comms-infrastructure-508c_0.pdf, Page 0