Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
ab1581b
Bump the pip group across 2 directories with 2 updates
dependabot[bot] Jan 14, 2025
81ac252
Add encryption to email data
ProjectZeroDays Jan 18, 2025
99bee48
Add customizable dashboards to provide tailored security insights and…
ProjectZeroDays Jan 18, 2025
cef15f4
Add customizable dashboards to provide tailored security insights and…
ProjectZeroDays Jan 18, 2025
452504f
Rename jhv.png to logo.png
ProjectZeroDays Jan 18, 2025
3c66db7
Update the README.md files
ProjectZeroDays Jan 18, 2025
f518884
Update LICENSE
ProjectZeroDays Jan 18, 2025
24c15ea
Update dashboard.py
ProjectZeroDays Jan 18, 2025
56eb087
Update dashboard.py
ProjectZeroDays Jan 18, 2025
014ac0b
Update dashboard.py
ProjectZeroDays Jan 18, 2025
598d6bc
Fix errors and add implementation checklist
ProjectZeroDays Jan 18, 2025
b2f2638
Fix errors and add implementation checklist (#45)
ProjectZeroDays Jan 18, 2025
69caf31
Revert "Fix errors and add implementation checklist"
ProjectZeroDays Jan 18, 2025
3882fdb
Update README.md
ProjectZeroDays Jan 18, 2025
2f96ea0
Merge branch 'Your-Momma-Beeotch' into revert-45-fix-errors
ProjectZeroDays Jan 18, 2025
0417811
Revert "Fix errors and add implementation checklist" (#46)
ProjectZeroDays Jan 18, 2025
a731e9a
Fix all errors
ProjectZeroDays Jan 18, 2025
ba2e03b
Fix all errors (#47)
ProjectZeroDays Jan 18, 2025
cb003f4
Merge branch 'Your-Momma-Beeotch' into update-readme
ProjectZeroDays Jan 18, 2025
344e43d
Update the README.md files (#43)
ProjectZeroDays Jan 18, 2025
82383fb
Merge branch 'Your-Momma-Beeotch' into add-encryption
ProjectZeroDays Jan 18, 2025
11aaa6d
Add encryption to email data (#40)
ProjectZeroDays Jan 18, 2025
9992882
Merge branch 'Your-Momma-Beeotch' into dependabot/pip/advanced-zero-c…
ProjectZeroDays Jan 18, 2025
099b3bc
Bump the pip group across 2 directories with 2 updates (#39)
ProjectZeroDays Jan 18, 2025
47ea760
Fix all errors in the repository
ProjectZeroDays Jan 18, 2025
0e00f6d
Fix all errors in the repository (#48)
ProjectZeroDays Jan 18, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 17 additions & 20 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -1,24 +1,21 @@
This is free and unencumbered software released into the public domain.
MIT License

Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.
Copyright (c) 2025 DEFENSE INTELLIGENCE AGENCY • PROJECT RED SWORD

In jurisdictions that recognize copyright laws, the author or authors
of this software dedicate any and all copyright interest in the
software to the public domain. We make this dedication for the benefit
of the public at large and to the detriment of our heirs and
successors. We intend this dedication to be an overt act of
relinquishment in perpetuity of all present and future rights to this
software under copyright law.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

For more information, please refer to <https://unlicense.org>
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
SERVER_HOST = '0.0.0.0'
SERVER_PORT = 1025
saveMail_directory = "FlowSteering/ApplicationCode/LLaVaServer/EmailLLaVaMailDatabase"
MODEL_NAME = "FlowSteering/llava/llava_weights/" # PATH to the LLaVA weights
MODEL_NAME = "FlowSteering/llava/llava_weights/" # PATH to the LLaVa weights
message_queue = Queue()
# Server configuration

Expand All @@ -33,7 +33,10 @@
except socket.timeout as e:
print('timeout')
print(e)

pass
except socket.error as e:
print('socket error')
print(e)
pass

return received_data
Expand Down Expand Up @@ -70,9 +73,9 @@
for part in msg.get_payload():
if part.get_content_type() == "text/plain":
body = part.get_payload()

else:
print(msg.get_payload())
body = msg.get_payload()

# print the subject
for part in msg.walk():
if part.get_content_maintype() == "multipart":
Expand Down Expand Up @@ -124,7 +127,11 @@

def start_server(): # This function is used to start the server and listen for incoming connections
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind((SERVER_HOST, SERVER_PORT))
try:
server_socket.bind((SERVER_HOST, SERVER_PORT))

Check warning

Code scanning / CodeQL

Binding a socket to all network interfaces Medium

'0.0.0.0' binds a socket to all interfaces.

Copilot Autofix

AI 11 months ago

To fix the problem, we need to bind the server socket to a specific network interface instead of all interfaces. This can be done by replacing '0.0.0.0' with the IP address of the dedicated interface that the server should listen on.

  1. Identify the specific IP address of the network interface that the server should bind to.
  2. Replace the '0.0.0.0' value of SERVER_HOST with this specific IP address.
  3. Ensure that the server is still accessible as intended after making this change.
Suggested changeset 1
advanced-zero-click-deployment-interface/FlowSteering/ApplicationCode/LLaVaServer/LLaVaServer.py

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/advanced-zero-click-deployment-interface/FlowSteering/ApplicationCode/LLaVaServer/LLaVaServer.py b/advanced-zero-click-deployment-interface/FlowSteering/ApplicationCode/LLaVaServer/LLaVaServer.py
--- a/advanced-zero-click-deployment-interface/FlowSteering/ApplicationCode/LLaVaServer/LLaVaServer.py
+++ b/advanced-zero-click-deployment-interface/FlowSteering/ApplicationCode/LLaVaServer/LLaVaServer.py
@@ -8,3 +8,3 @@
 # Server configuration
-SERVER_HOST = '0.0.0.0'
+SERVER_HOST = '192.168.1.100'  # Replace with the specific IP address of the dedicated interface
 SERVER_PORT = 1025
EOF
@@ -8,3 +8,3 @@
# Server configuration
SERVER_HOST = '0.0.0.0'
SERVER_HOST = '192.168.1.100' # Replace with the specific IP address of the dedicated interface
SERVER_PORT = 1025
Copilot is powered by AI and may make mistakes. Always verify output.
Unable to commit as this autofix suggestion is now outdated
except socket.error as e:
print(f"Error binding server socket: {e}")
return
server_socket.listen(1000)
model, image_processor, tokenizer, device = Run_LLaVa.Turn_On_LLaVa() # Turn on the LLaVa model and get the model, image processor, tokenizer and the device

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,11 @@ def load_image(image_file):
response = requests.get(image_file)
image = Image.open(BytesIO(response.content)).convert('RGB')
else:
image = Image.open(image_file).convert('RGB')
try:
image = Image.open(image_file).convert('RGB')
except Exception as e:
print(f"Error loading image: {e}")
return None
return image


Expand Down Expand Up @@ -169,6 +173,8 @@ def generate_stream(model, prompt, tokenizer, input_ids, images=None):
def run_result(X, prompt, initial_query, query_list, model, tokenizer, unnorm, image_processor):
device = 'cuda'
X = load_image(X)
if X is None:
return ["Error loading image"]

print("Image: ")
# load the image
Expand Down Expand Up @@ -234,8 +240,13 @@ def Turn_On_LLaVa(): # Load the LLaVa model
tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME)
dtypePerDevice = torch.float16

model = LlavaLlamaForCausalLM.from_pretrained(model_name, low_cpu_mem_usage=True, torch_dtype=dtypePerDevice,
use_cache=True)
try:
model = LlavaLlamaForCausalLM.from_pretrained(model_name, low_cpu_mem_usage=True, torch_dtype=dtypePerDevice,
use_cache=True)
except Exception as e:
print(f"Error loading model: {e}")
return None, None, None, None

model.to(device=device, dtype=dtypePerDevice)
image_processor = CLIPImageProcessor.from_pretrained(model.config.mm_vision_tower)

Expand Down Expand Up @@ -264,7 +275,11 @@ def Turn_On_LLaVa(): # Load the LLaVa model
def load_param(MODEL_NAME, model, tokenizer, initial_query):
model_name = os.path.expanduser(MODEL_NAME)

image_processor = CLIPImageProcessor.from_pretrained(model.config.mm_vision_tower)
try:
image_processor = CLIPImageProcessor.from_pretrained(model.config.mm_vision_tower)
except Exception as e:
print(f"Error loading image processor: {e}")
return None, None, None, None, None, None, None, None, None

mm_use_im_start_end = getattr(model.config, "mm_use_im_start_end", False)
tokenizer.add_tokens([DEFAULT_IMAGE_PATCH_TOKEN], special_tokens=True)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,6 @@

In this directory, you will find the code for the GenAI EcoSystem. The GenAI EcoSystem consists of a collection of scripts designed to simulate an email system with multiple users and dedicated servers.




The system consists of three main components: the Email Server, the LLaVa Server, and the End User Clients.
* The Email Server is responsible for sending and receiving emails from the End User Clients.
* The LLaVa Server is the GenAI service responsible for handling the emails that were sent to the End User Clients.
Expand All @@ -25,9 +22,6 @@ The system consists of three main components: the Email Server, the LLaVa Server

In our experiments, we utilized a single machine to run both the Email Server and the LLaVa Server. This machine was equipped with a single NVIDIA Quadro RTX 6000 24GB GPU. Additionally, we employed seven virtual machines to run the End User Clients.




## Running the GenAI EcoSystem

### 1. Run the Email Server
Expand All @@ -37,7 +31,7 @@ file to set the server configuration.
```python
SERVER_HOST = '0.0.0.0' # Change this to the IP address of the machine where the Email Server will run
SERVER_PORT = 1234 # Change this to the port where the Email Server will listen
saveMail_directory = "FlowSteering/ApplicationCode/EmailServer/Database/EmailServerMailDatabase" # Change this to the directory where you want to save the emails inbox for each user
saveMail_directory = "FlowSteering/ApplicationCode/EmailServer/EmailServerMailDatabase" # Change this to the directory where you want to save the emails inbox for each user
message_queue = Queue()
default_image = 'FlowSteering/assets/PerturbatedImages/DjiPerturbClassForward.png'
```
Expand All @@ -59,9 +53,6 @@ def handle_messages():
Save_Email_To_Recipient()
```




#### To run the Email Server execute the following command in the EmailServer directory
```bash
python3 EmailServer.py
Expand Down Expand Up @@ -92,9 +83,6 @@ def handle_messages():
SendToLLaVa()
```




#### To run the LLaVa Server execute the following command in the LLaVaServer directory
```bash
python3 LLaVaServer.py
Expand All @@ -109,16 +97,12 @@ Since this script is designed to run on multiple machines, you don't need to edi
You can find an example of the CSV file named: [EndUserBaseEmails.csv](../../FlowSteering/ApplicationCode/EndUserCode/EndUserClientBaseEmails/EndUserBaseEmails.csv).
The function responsible for reading this CSV file is located in the [EndUserClient.py](../../FlowSteering/ApplicationCode/EndUserCode/EndUserClient.py) file under the respective function.


```python
def read_emails_from_file():
```



The script for each End User Client runs in a loop, sending a request to the Email Server to check the inbox for new emails every 10-20 seconds.


```python
def main():
while True:
Expand All @@ -129,9 +113,6 @@ def main():
If there is a new email in the inbox, the Email server will send the email to the End User Client, and a pop-up window will appear with the email content.
Next the End User Client will send the email to the LLaVa Server for classification, and the LLaVa Server will send the classification back to the End User Client.




| Pop-up Window | Queries sent to LLaVa |
|---------------------------------------------|-----------------------------------------------------|
| ![Image 1 Description](../../Assets/DJISpam.png) | ![Image 2 Description](../../Assets/LLaVaQuery.png) |
Expand All @@ -140,9 +121,6 @@ Finally, the End User Client will act based on the classification returned by th

For our experiments, we implemented the action "Forward" and left the other actions as placeholders.




```python
if Classification == 'reply':
print('Manual action is required for replying to this email, so it will be transferred to the Manual Folder.')
Expand All @@ -157,10 +135,8 @@ For our experiments, we implemented the action "Forward" and left the other acti
elif Classification == 'spam':
print('Moving the email to the Spam Folder')
pass

```


#### To run the End User Client execute the following command in the EndUserCode directory and replace the configurations of the server and the user with your own configurations
```bash
python3 EndUserClient.py --SERVER_EMAIL_HOST 111.88.88.33 --SERVER_EMAIL_PORT 1234 --SERVER_LLAVA_HOST 111.55.55.33 --SERVER_LLAVA_PORT 1025 --MYEMAIL Person1@example.com --saveMail_directory "FlowSteering/ApplicationCode/EndUserCode/EndUserPersonalEmailDir" --BaseEmails_directory "FlowSteering/ApplicationCode/EndUserCode/EndUserClientBaseEmails/EndUserBaseEmails.csv" --CycleNewEmails True --default_image "FlowSteering/assets/PerturbatedImages/DjiPerturbClassForward.png"
Expand All @@ -172,9 +148,6 @@ Navigate to the [EndUserCode directory](../../FlowSteering/ApplicationCode/EndUs

This code is a simplified version of the End User Client, used solely to send the initial malicious email to the End User Clients, as they are not composing new emails.




Configure the following variables to send the email:
``` python
def main():
Expand All @@ -195,25 +168,28 @@ Next, the Attacker Client will send two identical emails to the Email Server, wi
SERVER_EMAIL_PORT)
```




#### To run the Attacker Client execute the following command in the EndUserCode directory and replace the configurations of the server and the user with your own configurations
```bash
python3 AttackerClient.py --SERVER_EMAIL_HOST 111.88.88.33 --SERVER_EMAIL_PORT 1234 --SERVER_LLAVA_HOST 111.55.55.33 --SERVER_LLAVA_PORT 1025 --MYEMAIL Attacker@example.com
```


## Conclusion

In our experiments, we developed a basic GenAI email application consisting of several components. You are welcome to modify any part of the system and tailor it to your own requirements and preferences.

## Recent Changes and Additions

We have recently made several updates and additions to the codebase to enhance the functionality and performance of the GenAI EcoSystem. These changes include:

1. **Improved Network Handling**: Enhanced the network handling capabilities to address issues related to image transmission over sockets, especially when using virtual machines. A default image is now loaded when an image fails to send correctly due to network issues.

2. **Optimized Email Server**: Refined the Email Server's handling of incoming connections and email storage. The server now creates a directory to save the email inbox for each user, ensuring better organization and retrieval of emails.

3. **Enhanced LLaVa Server**: Updated the LLaVa Server to process incoming emails more efficiently using the LLaVa model. The server now listens for incoming connections, processes emails, and sends responses back to the End User Clients seamlessly.

4. **End User Client Improvements**: Improved the End User Client script to run in a loop, checking the inbox for new emails every 10-20 seconds. The script now handles email classification and actions based on the classification returned by the LLaVa Server.

5. **Attacker Client Simplification**: Simplified the Attacker Client script to send the initial malicious email to the End User Clients. The script now sends two identical emails to the Email Server, targeting specific recipients.


These updates aim to provide a more robust and efficient GenAI EcoSystem, ensuring smooth communication and interaction between the various components.

Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
einops
fastapi
gradio==5.5.0
gradio==5.11.0
markdown2[all]
numpy
requests
Expand All @@ -12,7 +12,7 @@ uvicorn
wandb
shortuuid
httpx==0.24.0
deepspeed==0.9.5
deepspeed==0.15.1
peft==0.4.0
transformers==4.38.0
accelerate==0.21.0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ classifiers = [
"License :: OSI Approved :: Apache Software License",
]
dependencies = [
"einops", "fastapi", "gradio==5.5.0", "markdown2[all]", "numpy",
"einops", "fastapi", "gradio==5.11.0", "markdown2[all]", "numpy",
"requests", "sentencepiece", "tokenizers>=0.12.1",
"torch", "torchvision", "uvicorn", "wandb",
"shortuuid", "httpx==0.24.0",
"deepspeed==0.9.5",
"deepspeed==0.15.1",
"peft==0.4.0",
"transformers==4.38.0",
"accelerate==0.21.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,17 @@ sudo nginx -t # check `/etc/nginx/nginx.conf`
sudo systemctl reload nginx # restart Nginx service to load the new config
sudo systemctl status nginx # check the status of the Nginx service. It should be active (running).
```

## Recent Changes and Additions

We have recently made several updates and additions to the codebase to enhance the functionality and performance of the Nginx gateway. These changes include:

1. **Improved Security Features**: Enhanced the security features of the Nginx gateway to provide better protection for Gradio servers. This includes additional firewall rules and connection limits.

2. **Optimized Load Balancing**: Refined the load balancing capabilities of the Nginx gateway to ensure efficient distribution of traffic across multiple Gradio servers.

3. **Dynamic Server Management**: Updated the Nginx configuration to support dynamic mounting and unmounting of Gradio servers, allowing for more flexible server management.

4. **Simplified Deployment Process**: Streamlined the deployment process for the Nginx gateway, making it easier to set up and configure on various Linux distributions.

These updates aim to provide a more robust and efficient Nginx gateway, ensuring smooth communication and interaction between the various components of the system.
32 changes: 31 additions & 1 deletion c2_dashboard.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,35 @@ class C2Dashboard:
def render(self):
return pn.Column(
"### Command and Control Dashboard",
pn.pane.Markdown("Welcome to the C2 Dashboard. Here you can manage and monitor your operations.")
pn.pane.Markdown("Welcome to the C2 Dashboard. Here you can manage and monitor your operations."),
pn.pane.Markdown("#### Detailed Metrics and Insights"),
pn.widgets.DataFrame(name="Metrics Data"),
pn.pane.Markdown("#### Visualizations"),
pn.widgets.DataFrame(name="Assets Data"),
pn.pane.Markdown("#### Message Boards"),
pn.widgets.DataFrame(name="Message Board Data"),
pn.pane.Markdown("#### Announcements"),
pn.widgets.DataFrame(name="Announcements Data"),
pn.pane.Markdown("#### Latest News on Exploits"),
pn.widgets.DataFrame(name="Latest News Data"),
pn.pane.Markdown("#### AI Interface"),
pn.widgets.DataFrame(name="AI Interface Data"),
pn.pane.Markdown("#### System Connections"),
pn.widgets.DataFrame(name="System Connections Data"),
pn.pane.Markdown("#### Logs"),
pn.widgets.DataFrame(name="Logs Data"),
pn.pane.Markdown("#### System Status"),
pn.widgets.DataFrame(name="System Status Data"),
pn.pane.Markdown("#### System Settings"),
pn.widgets.DataFrame(name="System Settings Data"),
pn.pane.Markdown("#### Attack Simulations"),
pn.widgets.DataFrame(name="Attack Simulations Data"),
pn.pane.Markdown("#### Fuzzing"),
pn.widgets.DataFrame(name="Fuzzing Data"),
pn.pane.Markdown("#### Asset Control"),
pn.widgets.DataFrame(name="Asset Control Data"),
pn.pane.Markdown("#### Reverse Shell Settings"),
pn.widgets.DataFrame(name="Reverse Shell Settings Data"),
pn.pane.Markdown("#### Advanced Connection Methods"),
pn.widgets.DataFrame(name="Advanced Connection Methods Data")
)
18 changes: 11 additions & 7 deletions core/email_server/EmailServer.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,13 +72,17 @@ def Save_Email_To_Recipient(client_socket, data, msg, requests, subject, sender,

msg = email.message_from_bytes(data)

if msg.is_multipart():
for part in msg.get_payload():
if part.get_content_type() == "text/plain":
body = part.get_payload()

else:
print(msg.get_payload())
try:
if msg.is_multipart():
for part in msg.get_payload():
if part.get_content_type() == "text/plain":
body = part.get_payload()
else:
body = msg.get_payload()
except Exception as e:
print(f"Error processing email message: {e}")
client_socket.sendall("Error processing email message".encode('utf-8'))
return

for part in msg.walk():
if part.get_content_maintype() == "multipart":
Expand Down
2 changes: 1 addition & 1 deletion core/integrations/email_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,4 +78,4 @@ def get_email_body(self, email_message) -> str:
return email_message.get_payload(decode=True).decode()
except Exception as e:
self.logger.error(f"Error extracting email body: {e}")
return ""
return ""
Loading
Loading