automajicly commited on
Commit
f8bc565
Β·
verified Β·
1 Parent(s): 7dbffb0

Upload 5 files

Browse files

This is a VM security build integrated with an obliterated uncensored local and private AI agent.

Files changed (5) hide show
  1. README.md +53 -3
  2. agent_loop.py +61 -0
  3. mcp_server.py +77 -0
  4. request.json +5 -0
  5. tools_manifest.json +12 -0
README.md CHANGED
@@ -1,3 +1,53 @@
1
- ---
2
- license: apache-2.0
3
- ---
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Autonomous Security Agent
2
+
3
+ A self-contained security agent built with Qwen 2.5-7B running locally via LM Studio on Kali Linux. The agent can autonomously execute security tools, analyze results, and take action through an MCP (Model Context Protocol) server.
4
+
5
+ ## Features
6
+
7
+ - **Local LLM Backend** β€” Qwen 2.5-7B served via LM Studio at `192.168.0.39:1234`
8
+ - **Autonomous Tool Execution** β€” Runs security tools (nmap, masscan) through MCP
9
+ - **Agent Loop** β€” Continuous reasoning and decision-making
10
+ - **MCP Server** β€” Tool chain execution with `run_masscan`, `run_nmap`, `write_file`, `read_file`
11
+
12
+ ## Components
13
+
14
+ - `agent_loop.py` β€” Main agent reasoning loop
15
+ - `mcp_server.py` β€” Tool execution server
16
+ - `tools_manifest.json` β€” Tool definitions
17
+ - `request.json` β€” Sample request format
18
+
19
+ ## Security Setup
20
+
21
+ ### Firewall Configuration
22
+
23
+ - **Outbound**: All traffic allowed
24
+ - **Inbound**: All traffic blocked (default deny)
25
+ - **IDS**: Suricata for behavioral alerting
26
+
27
+ ### Network Security
28
+
29
+ - TOR integration for privacy
30
+ - Local-only LLM inference (no external API calls)
31
+ - MCP server bound to localhost only
32
+
33
+ ## Installation & Setup
34
+
35
+ 1. Install Kali Linux with Suricata
36
+ 2. Install LM Studio and load Qwen 2.5-7B
37
+ 3. Configure firewall rules (see docs/firewall-setup.md)
38
+ 4. Clone this repository
39
+ 5. Install Python dependencies
40
+ 6. Run the agent: `python agent_loop.py`
41
+
42
+ ## Documentation
43
+
44
+ See the `docs/` folder for:
45
+
46
+ - Detailed setup instructions
47
+ - Firewall rule examples
48
+ - Suricata configuration
49
+ - MCP server setup
50
+
51
+ ## License
52
+
53
+ MIT
agent_loop.py ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import requests
2
+ import json
3
+
4
+ OLLAMA_URL = "http://192.168.0.39:1234/v1/chat/completions"
5
+ MCP_URL = "http://localhost:8000"
6
+
7
+ def call_model(goal):
8
+ payload = {
9
+ "model": "qwen",
10
+ "messages": [
11
+ {
12
+ "role": "user",
13
+ "content": (
14
+ "Generate ONLY JSON. Valid tools: run_command, run_masscan, run_nmap, write_file, read_file.\n"
15
+ "Example: {\"chain\": [{\"tool\": \"run_masscan\", \"target\": \"192.168.1.100\", \"ports\": \"1-443\"}]}\n"
16
+ "Goal: " + goal
17
+ )
18
+ }
19
+ ],
20
+ "temperature": 0.05
21
+ }
22
+
23
+ try:
24
+ response = requests.post(OLLAMA_URL, json=payload, timeout=30)
25
+ content = response.json()["choices"][0]["message"]["content"]
26
+ content = content.replace("```json", "").replace("```", "").strip()
27
+ return json.loads(content)
28
+ except Exception as e:
29
+ print(f"Error parsing: {e}")
30
+ return {"chain": []}
31
+
32
+ def execute_chain(chain):
33
+ print("\nEXECUTING:\n")
34
+ for i, step in enumerate(chain, 1):
35
+ print(f"{i}. {step}")
36
+ try:
37
+ result = requests.post(MCP_URL, json=step, timeout=30)
38
+ print(f"Result: {result.json()}\n")
39
+ except Exception as e:
40
+ print(f"Error: {e}\n")
41
+
42
+ def main():
43
+ print("INTELLIGENT SECURITY AGENT\n")
44
+ while True:
45
+ goal = input("Goal: ").strip()
46
+ if goal.lower() == "exit":
47
+ break
48
+ if not goal:
49
+ continue
50
+
51
+ data = call_model(goal)
52
+ chain = data.get("chain", [])
53
+
54
+ if chain:
55
+ print(f"\nChain: {chain}")
56
+ execute_chain(chain)
57
+ else:
58
+ print("No chain generated")
59
+
60
+ if __name__ == "__main__":
61
+ main()
mcp_server.py ADDED
@@ -0,0 +1,77 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ import subprocess, json, sys
3
+ from flask import Flask, request, jsonify
4
+ import logging
5
+ app = Flask(__name__)
6
+ logging.basicConfig(level=logging.INFO)
7
+ logger = logging.getLogger(__name__)
8
+ SUPPORTED_TOOLS = ["run_command", "run_masscan", "run_nmap", "run_netstat", "run_sqlmap", "run_nikto", "run_hydra", "run_searchsploit", "run_curl", "run_wget", "write_file", "read_file"]
9
+ PRIVILEGED_TOOLS = {"masscan", "nmap", "arp-scan", "wireshark", "tcpdump", "iptables", "ip6tables", "ufw", "hashcat", "airmon-ng", "aircrack-ng", "hydra", "metasploit", "burpsuite"}
10
+ class ToolExecutor:
11
+ def __init__(self):
12
+ self.execution_log = []
13
+ self.error_recovery_attempts = {}
14
+ def execute_tool(self, tool, params):
15
+ if tool == "run_command": return self._run_command(params.get("command", ""))
16
+ elif tool == "run_masscan": return self._run_masscan(params.get("target", ""), params.get("ports", "1-65535"), params.get("rate", "1000"))
17
+ elif tool == "run_nmap": return self._run_nmap(params.get("target", ""), params.get("flags", "-sV"))
18
+ elif tool == "run_netstat": return self._run_netstat(params.get("flags", "-tuln"))
19
+ elif tool == "write_file": return self._write_file(params.get("filename", ""), params.get("content", ""))
20
+ elif tool == "read_file": return self._read_file(params.get("filename", ""))
21
+ return {"status": "error", "error_type": "unsupported_tool", "message": f"Tool '{tool}' not supported"}
22
+ def _execute_command(self, command, retry_with_sudo=False):
23
+ if retry_with_sudo and not command.strip().startswith("sudo"): command = f"sudo {command}"
24
+ try:
25
+ result = subprocess.run(command, shell=True, capture_output=True, text=True, timeout=300)
26
+ if result.returncode == 0: return {"status": "success", "stdout": result.stdout.strip(), "stderr": result.stderr.strip()}
27
+ else:
28
+ stderr = result.stderr.lower()
29
+ if "permission denied" in stderr or "operation not permitted" in stderr:
30
+ if not retry_with_sudo: return self._execute_command(command, retry_with_sudo=True)
31
+ return {"status": "error", "error_type": "permission_denied", "message": result.stderr}
32
+ elif "not found" in stderr: return {"status": "error", "error_type": "command_not_found", "message": result.stderr}
33
+ else: return {"status": "error", "error_type": "command_failed", "message": result.stderr if result.stderr else result.stdout}
34
+ except subprocess.TimeoutExpired: return {"status": "error", "error_type": "timeout", "message": "Command timed out"}
35
+ except Exception as e: return {"status": "error", "error_type": "execution_error", "message": str(e)}
36
+ def _run_command(self, command):
37
+ if not command: return {"status": "error", "error_type": "invalid_params", "message": "No command"}
38
+ result = self._execute_command(command)
39
+ self.execution_log.append({"tool": "run_command", "result": result})
40
+ return result
41
+ def _run_masscan(self, target, ports, rate):
42
+ if not target: return {"status": "error", "error_type": "invalid_params", "message": "No target"}
43
+ command = f"masscan {target} -p {ports} --rate {rate}"
44
+ result = self._execute_command(command)
45
+ self.execution_log.append({"tool": "run_masscan", "result": result})
46
+ return result
47
+ def _run_nmap(self, target, flags):
48
+ if not target: return {"status": "error", "error_type": "invalid_params", "message": "No target"}
49
+ command = f"nmap {flags} {target}"
50
+ result = self._execute_command(command)
51
+ self.execution_log.append({"tool": "run_nmap", "result": result})
52
+ return result
53
+ def _run_netstat(self, flags):
54
+ command = f"netstat {flags}"
55
+ result = self._execute_command(command)
56
+ self.execution_log.append({"tool": "run_netstat", "result": result})
57
+ return result
58
+ def _write_file(self, filename, content):
59
+ if not filename: return {"status": "error", "message": "No filename"}
60
+ try:
61
+ with open(filename, 'w') as f: f.write(content)
62
+ return {"status": "success", "message": f"File written", "filename": filename}
63
+ except Exception as e: return {"status": "error", "message": str(e)}
64
+ def _read_file(self, filename):
65
+ if not filename: return {"status": "error", "message": "No filename"}
66
+ try:
67
+ with open(filename, 'r') as f: content = f.read()
68
+ return {"status": "success", "filename": filename, "content": content}
69
+ except Exception as e: return {"status": "error", "message": str(e)}
70
+ executor = ToolExecutor()
71
+ @app.route('/', methods=['POST'])
72
+ def execute():
73
+ try:
74
+ data = request.get_json()
75
+ if not data:​​​​​​​​​​​​​​​​
76
+
77
+
request.json ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ {
2
+ "tool": "write_file",
3
+ "filename": "auto_ai.txt",
4
+ "content": "This was created automatically"
5
+ }
tools_manifest.json ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "tools": [
3
+ {
4
+ "name": "write_file",
5
+ "description": "Writes text content to a file on the local system",
6
+ "input": {
7
+ "filename": "string",
8
+ "content": "string"
9
+ }
10
+ }
11
+ ]
12
+ }