Coleção de Módulos Especiais que estendem o comportamento padrão da ferramenta
String-X. Cada módulo orquestra uma
ferramenta externa instalada na máquina (nmap, httpx, SimpleReconSubdomain,
…): chama o binário via subprocess, passa o alvo e faz o parse da saída. Os
módulos não reimplementam a lógica em Python - apenas integram a ferramenta ao
pipeline do String-X.
- String-X: https://github.com/MrCl0wnLab/string-x
- Módulos de referência: https://github.com/MrCl0wnLab/string-x/tree/main/src/stringx/utils/auxiliary
String-X usa uma arquitetura modular: um arquivo .py = uma classe que herda de
BaseModule. O tipo do módulo define a subpasta e o prefixo usado no CLI
(tipo:nome). O nome do módulo no CLI é sempre igual ao nome do arquivo (sem .py).
| Tipo | Código | Diretório | Descrição |
|---|---|---|---|
| Extractor | ext |
ext/ |
Extração de dados (email, URL, domain, phone) |
| Collector | clc |
clc/ |
Coleta/agregação (DNS, whois, ferramentas externas) |
| Output | out |
out/ |
Formatação e envio de resultados (DB, API, files) |
| Connection | con |
con/ |
Conexões especializadas (SSH, FTP, etc.) |
| AI | ai |
ai/ |
Integrações com LLMs |
Estrutura do repositório:
string-x-modules/
├── default.json # variáveis (STRX_*) das ferramentas externas
├── install.py # merge da config + cópia dos módulos para o String-X
├── clc/ con/ ext/ out/ ai/ # módulos, uma subpasta por tipoAs ferramentas externas usadas pelos módulos não ficam hardcoded no código - seus
caminhos e parâmetros são declarados em default.json, na raiz deste repositório.
Toda chave segue o padrão fixo STRX_* e é mesclada na configuração do String-X
pelo install.py, ficando acessível dentro do módulo como atributo de self.setting
(ex.: self.setting.STRX_NMAP_PATH).
Use STRX_* para qualquer valor fundamental para a execução que dependa do
ambiente ou que o usuário possa querer redefinir como padrão - path do binário,
nome do binário, timeout, wordlist, etc.
{
"STRX_SIMPLERECON_PATH": "",
"STRX_SIMPLERECON_PYTHON": "",
"STRX_SIMPLERECON_TIMEOUT": 900,
"STRX_NMAP_PATH": "",
"STRX_NMAP_TIMEOUT": 600,
"STRX_HTTPX_PATH": "",
"STRX_HTTPX_TIMEOUT": 300
}Exemplo de arquivo preechido
{
"STRX_SIMPLERECON_PATH": "/home/osint/Documentos/SimpleReconSubdomain",
"STRX_SIMPLERECON_PYTHON": "python3.12",
"STRX_SIMPLERECON_TIMEOUT": 900,
"STRX_NMAP_PATH": "/bin/nmap",
"STRX_NMAP_TIMEOUT": 600,
"STRX_HTTPX_PATH": "httpx",
"STRX_HTTPX_TIMEOUT": 300
}Dentro do módulo, leia sempre com getattr (a chave só existe depois que o
install.py mescla o default.json):
nmap_bin = str(getattr(self.setting, 'STRX_NMAP_PATH', '') or '')
timeout = self.options.get('timeout') or getattr(self.setting, 'STRX_NMAP_TIMEOUT', 600)Coerção de tipos: o loader do String-X converte chaves que contêm
PATHparapathlib.Pathe chavesTIMEOUT/RETRY/etc. paraint. Por isso envolva valores de path emstr()ao montar o comando dosubprocess.
- String-X - a ferramenta-base na qual os módulos são instalados: https://github.com/MrCl0wnLab/string-x
- As ferramentas externas que cada módulo chama. Instale apenas as dos módulos
que for usar e aponte a respectiva chave
STRX_*para o binário/arquivo:
| Ferramenta | Como obter | Chave STRX_* |
|---|---|---|
nmap (+ NSE dns-brute) |
gerenciador de pacotes (apt install nmap) |
STRX_NMAP_PATH |
httpx da ProjectDiscovery (não a lib Python) |
go install github.com/projectdiscovery/httpx/cmd/httpx@latest |
STRX_HTTPX_PATH |
| SimpleReconSubdomain | clonar o repo + venv com httpx[socks], aiodns, dnspython, beautifulsoup4 |
STRX_SIMPLERECON_PATH (+ STRX_SIMPLERECON_PYTHON apontando p/ a venv) |
O install.py faz, de forma idempotente: (1) o merge não destrutivo do
default.json local com o do String-X (chaves existentes são preservadas; backup em
default.json.bak; --force sobrescreve) e (2) copia os módulos das pastas de
tipo (ext/clc/out/con/ai) para utils/auxiliary/ do String-X.
# pré-visualizar (não grava nada)
python install.py --path /caminho/para/string-x --dry-run
# instalar
python install.py --path /caminho/para/string-x
# forçar sobrescrita de chaves de config já existentes
python install.py --path /caminho/para/string-x --force
--pathé obrigatório. Depois de editardefault.json(paths das ferramentas), rode oinstall.pyde novo para propagar as mudanças.
Todos os módulos atuais são collectors (clc) e recebem um alvo via {STRING}.
As opções de cada módulo estão documentadas no próprio arquivo (clc/<nome>.py).
| Invocação | Ferramenta | Coleta |
|---|---|---|
clc:simplerecon_subdomain |
SimpleReconSubdomain | Subdomínios enumerados |
clc:simplerecon_ip |
SimpleReconSubdomain | IPs dos hosts vivos |
clc:simplerecon_url |
SimpleReconSubdomain | URLs descobertas |
clc:simplerecon_full |
SimpleReconSubdomain | Subdomínios + IPs + URLs + takeovers |
clc:nmap_subdomain |
nmap (NSE dns-brute) | Subdomínios (hostnames) |
clc:nmap_ip |
nmap (NSE dns-brute) | IPs únicos dos hosts descobertos |
clc:httpx_url |
httpx (ProjectDiscovery) | URLs vivas + destinos de redirect |
clc:httpx_ip |
httpx (ProjectDiscovery) | IPs do host |
clc:httpx_email |
httpx (ProjectDiscovery) | E-mails no corpo das respostas |
clc:httpx_check |
httpx (ProjectDiscovery) | URLs online com código de status |
{STRING} é a variável por linha do alvo. -pm imprime só a saída do módulo;
-pmc mantém separada a saída de cada módulo encadeado.
# módulo único
echo "example.com" > domains.txt
strx -l domains.txt -st "echo {STRING}" -module "clc:simplerecon_subdomain" -pm
strx -l domains.txt -st "echo {STRING}" -module "clc:nmap_ip" -pm
# encadeando módulos (a saída de um alimenta o próximo)
strx -l domains.txt -st "echo {STRING}" -module "clc:simplerecon_subdomain|clc:httpx_check" -pmcEsqueleto de um collector que envolve um binário externo. O arquivo
(clc/ffuf_paths.py) lê as variáveis STRX_*, monta o comando, executa o binário
da máquina e emite os resultados.
"""Collector de exemplo: envolve o binário externo ffuf."""
import os
import json
import subprocess
from stringx.core.basemodule import BaseModule
class FfufPaths(BaseModule):
def __init__(self):
super().__init__()
self.meta = {
'name': 'Ffuf Paths Collector',
'author': 'Seu Nome',
'version': '1.0',
'description': 'Fuzzing de paths web envolvendo o binário externo ffuf',
'type': 'collector', # casa com o prefixo CLI: clc
'example': './strx -l urls.txt -st "echo {STRING}" -module "clc:ffuf_paths" -pm'
}
self.options = {
'data': str(), # alvo, vem do pipeline do String-X
'timeout': None, # default: STRX_FFUF_TIMEOUT
'retry': 0,
'retry_delay': None,
}
def run(self) -> None:
try:
target = self.options.get('data', '').strip()
if not target:
return
# Variáveis fundamentais vindas do default.json (STRX_*)
ffuf_bin = str(getattr(self.setting, 'STRX_FFUF_PATH', '') or '')
wordlist = str(getattr(self.setting, 'STRX_FFUF_WORDLIST', '') or '')
timeout = self.options.get('timeout') or getattr(self.setting, 'STRX_FFUF_TIMEOUT', 300)
if not ffuf_bin or not os.path.isfile(ffuf_bin):
self.handle_error(
FileNotFoundError('STRX_FFUF_PATH'),
'Binário ffuf não encontrado - configure STRX_FFUF_* no default.json'
)
return
url = target if 'FUZZ' in target else target.rstrip('/') + '/FUZZ'
cmd = [ffuf_bin, '-u', url, '-w', wordlist, '-of', 'json', '-o', '-', '-s']
self.log_debug(f"[*] Executando: {' '.join(cmd)}")
result = subprocess.run(cmd, capture_output=True, text=True, timeout=int(timeout))
if result.returncode != 0:
self.handle_error(
subprocess.SubprocessError(result.stderr.strip()[:500]),
f'ffuf retornou código {result.returncode} para {target}'
)
return
for item in json.loads(result.stdout or '{}').get('results', []):
self.set_result(item.get('url', ''))
except Exception as e:
self.handle_error(e, 'Erro na coleta de paths (ffuf)')Para usar: declare as chaves STRX_FFUF_* no default.json, rode
python install.py --path /caminho/para/string-x e invoque com
-module "clc:ffuf_paths".
Checklist do módulo: (1) nome do arquivo = nome usado no CLI; (2)
meta['type']casa com o prefixo (collector→clc); (3) toda variável de ambiente fundamental está emdefault.jsoncomoSTRX_*; (4) paths são envolvidos emstr()ao montar o comando.
MrCl0wn
- 🌐 Blog: http://blog.mrcl0wn.com
- 🐙 GitHub: @MrCl0wnLab
- 🐦 Twitter: @MrCl0wnLab
- 📧 Email: mrcl0wnlab@gmail.com
⭐ Se este projeto foi útil, considere dar uma estrela!
💡 Sugestões e feedbacks são sempre bem-vindos!
💀 Hacker Hackeia!