Repositório organizado para reproduzir dois pipelines de detecção de backdoors/webshells em PHP:
- Semgrep → SVM (Linear) — usa hits por regra do Semgrep como features esparsas.
- TF‑IDF (char 3–6) → SVM (Linear) — usa n‑grams de caracteres diretamente do código fonte.
Ambos fazem avaliação k‑fold repetida (5×2) e salvam modelos e relatórios.
Estrutura inspirada no trabalho apresentado em “Detecção de Webshells em PHP com SVM” (2025) do Pietro Hoffchneider.
php-webshell-svm-repo/
├─ data/
│ ├─ benign/ # coloque aqui .php legítimos
│ └─ malicious/ # coloque aqui .php maliciosos
├─ models/ # modelos treinados (.joblib)
├─ reports/ # métricas por fold (CSV)
├─ scripts/
│ ├─ train_semgrep.py # pipeline Semgrep → LinearSVC (calibrado)
│ ├─ train_tfidf.py # pipeline TF‑IDF char 3–6 → LinearSVC (calibrado)
│ ├─ predict.py # inferência usando qualquer modelo salvo
│ └─ compare.py # executa os dois pipelines e gera relatórios
├─ utils/
│ └─ common.py # avaliação kfold e helpers
└─ requirements.txt
- Python 3.10+
pip install -r requirements.txt- Para rodar o Semgrep automaticamente:
pip install semgrep(ou instale via brew/pipx)
Coloque arquivos .php em:
data/benign/data/malicious/
Você pode começar pequeno para validar o pipeline e depois ampliar.
Dica: se já tiver JSONs do Semgrep por arquivo, passe
--json-cache path/para/jsonsnotrain_semgrep.pypara reutilizar sem reexecutar o Semgrep.
pip install -r requirements.txtpython scripts/train_tfidf.py --data data --out models/tfidf_linear_svm.joblib --report reports/tfidf_metrics.csv --max_features 100000 --min_df 2python scripts/train_semgrep.py --data data --out models/semgrep_linear_svm.joblib --report reports/semgrep_metrics.csv --semgrep-config p/php
# (opcional) para usar JSONs já existentes (um por arquivo .php):
# python scripts/train_semgrep.py --data data --json-cache out_json/python scripts/compare.pypython scripts/predict.py --model models/tfidf_linear_svm.joblib --file sample.php
python scripts/predict.py --model models/semgrep_linear_svm.joblib --file sample.php- Modelos (.joblib) ficam em
models/. - Relatórios CSV com métricas por fold ficam em
reports/:reports/tfidf_metrics.csvreports/semgrep_metrics.csv
Cada CSV possui colunas: fold, acc, prec, rec, f1, auc.
Use sua ferramenta favorita (ou Pandas) para sumarizar:
import pandas as pd
df = pd.read_csv("reports/tfidf_metrics.csv")
print(df.mean(numeric_only=True))Processo:
- O Semgrep analisa os arquivos PHP e identifica padrões sintáticos e comportamentais com base em regras.
- Cada ocorrência (regra acionada) é convertida em uma matriz de atributos fixos (71 características) para treinar um SVM (testando kernels Linear, Polynomial, RBF e Sigmoid).
Resultados:
- RBF: 100% no treino, mas baixa performance no teste → overfitting.
- Linear: melhor equilíbrio, porém acurácia ≤ ~72%.
- Limitação: 71 features baseadas em regras não capturam bem a variabilidade/obfuscação típica de webshells PHP.
Processo:
- Analisa diretamente o texto do código PHP.
- Vetores TF-IDF (n-grams de 3 a 6 caracteres) com até 100.000 atributos.
- SVM treinado com os mesmos kernels para comparação justa.
Resultados:
- Todos os kernels com alta acurácia; Linear chegou a 100% no melhor teste, com baixa variância entre folds.
- Excelente generalização e ausência de overfitting severo.
- Acurácia média ≈ 98%, indicando que n-grams capturam padrões estruturais/estilo mesmo com ofuscação.
| Abordagem | Fonte das Features | Nº Atributos | Acurácia Média | Observações |
|---|---|---|---|---|
| Semgrep | Regras fixas | 71 | ~60–72% | Explicável, mas pouco sensível à ofuscação |
| TF-IDF n-grams | Texto (char 3–6) | até 100.000 | ~98% | Melhor generalização e estabilidade |
A extração de características determina o desempenho: Semgrep é ótimo para explicabilidade (quais regras disparam), mas TF‑IDF n‑grams entrega poder discriminativo superior para detecção de webshells PHP. Este repositório mantém ambas as abordagens:
- Semgrep → SVM para interpretabilidade/auditoria,
- TF‑IDF → SVM como baseline forte de classificação.
Base de dados utilizada nos testes: https://github.com/hannousse/Cleaned-PHP-Webshell-dataset
Este repositório inclui uma pasta .github/ com workflows de GitHub Actions (conforme o teste que você implementou) para validar automaticamente o pipeline em cada push ou pull request.
- Instala as dependências de
requirements.txt. - Executa um smoke test mínimo (veja
tests/smoke_test.sh) que:- Cria um dataset mínimo (
data/benign/ok.phpedata/malicious/bad.php); - Roda
scripts/compare.pypara treinar/avaliar ambos os modelos; - Gera
models/*.joblibereports/*.csvcomo artifacts.
- Cria um dataset mínimo (
bash tests/smoke_test.shDica: Se quiser subir artifacts no Actions (CSV e modelos), mantenha o passo
actions/upload-artifactno workflow.
- Balanceie benignos e maliciosos.
- Remova duplicatas e quase-duplicatas.
- Separe famílias de amostras por split (para evitar vazamento).
MIT. Sinta-se livre para usar e modificar.
