Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
name: D4N155 CI

on:
push:
branches: [master, main]
pull_request:
branches: [master, main]

jobs:
test:
name: Tests & Quality
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.10", "3.11", "3.12"]

steps:
- uses: actions/checkout@v4

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
pip install pytest pytest-asyncio bandit pip-audit

- name: Install lxml system deps
run: sudo apt-get install -y libxml2-dev libxslt1-dev

- name: Run unit tests
run: pytest tests/ -v --tb=short

- name: Security analysis (Bandit)
run: bandit -r modules/ -ll --skip B603,B607

- name: Dependency vulnerability scan (pip-audit)
run: pip-audit -r requirements.txt

shellcheck:
name: ShellCheck
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run ShellCheck on bash files
uses: ludeeus/action-shellcheck@master
with:
scandir: "."
additional_files: "main modules/functions.sh modules/load.sh"
279 changes: 92 additions & 187 deletions main
100755 → 100644
Original file line number Diff line number Diff line change
@@ -1,204 +1,109 @@
#!/usr/bin/env bash
# main — D4N155 Improved
# Compatível com a interface original. Integra os módulos Python otimizados.
# GoMutation preservado — compilado e chamado via modules/wordlist.py.

# Fix problems of directories
here=`dirname "$0"`
cd "$here"

# colors art
. ./modules/colors.sh
# Banner
echo -e """
$red /\ o
o /_ /~/
\ /\/
\ /
\ /
.{{}}}}}}.
{{{{{}}}}}}}.
{{{{ {}{{}}}}
}}}}} - - {{{{{
}}}} 0 0 }}}&
{{{{{---~^~---{{{&
}}}}}}\ ☭ /}}&&&
{{{{{{{;._ .;}}&&&&
'{{{{{{) \_(}}|//&
´''''': :''''´
[ \e[5m$bgred\033[38;5;232mOWASP D4N155$end $red]
"""

# ignore lower and uppercase
shopt -s nocasematch
# and colors with dont fuck terminal
printf "$end"
# Vars
export aggressive="0"
bug="""
You can report new bug or open a issue
\t$yellow→ $orange https://github.com/owasp/D4N155/issues$end
"""
help="""
Or use the Telegram bot https://t.me/D4N155_bot
D4N155: Tool for smart audit security

Usage: bash main <option> <value>
All options are optionals

Options:
-w, --wordlist <url|ip> Make the smartwordlist based in informations
on website.
-t, --targets <file> Make the smart-wordlist based in your passed
source informations in urls.
-b, --based <file> Analyze texts to generate the
custom wordlist
-r, --rate <time> Defines time interval between requests
-o, --output <file> For to store the all wordlist.
-?a, --aggressive Aggressive reading with headless
-h, --help Show this mensage.

Value: <url | ip | source | file | time>
URL URL target, example: scanme.nmap.org
IP IP address
TIME Time, example: 2.5. I.e: 00:00:02:30. 0 are default
FILE File, for save the result, get urls or using in
wordlist

Version: 1.3

It's GNU/GPL version 3
Project page: https://github.com/owasp/D4N155"""

# All functions
# shellcheck source=modules/functions.sh
. modules/functions.sh
# shellcheck source=modules/load.sh
. modules/load.sh
printf "\033[32m"

trap -- "printf \"\n$bug\";kill $! &> /dev/null;exit 2" "SIGINT"
printf "\033[32m"
trap -- "printf \"\n$bug\";kill \$! &>/dev/null;exit 2" "SIGINT"

# ── Compilação condicional do GoMutation (inalterado) ─────────────────
__compile(){
go build -o modules/GoMutation modules/GoMutation.go && \
echo "$success Compiled GoMutation" || echo "$error Golang dont installed"
echo "$success Compiled GoMutation" || \
echo "$error Go not installed — mutation step will be skipped"
}

test -x "modules/GoMutation" || __compile

# Menu
# ── Menu interativo ───────────────────────────────────────────────────
__interative(){
printf "\033[0m"
PS3="D4N155%#~> "
select option in "Make wordlist tradicional" "Make wordlist aggressive"
do
case $option in
"Make wordlist tradicional")
printf "\033[0m"
PS3="D4N155%#~> "
select option in "Make wordlist traditional" "Make wordlist aggressive" "Quit"
do
case $option in
"Make wordlist traditional")
export aggressive="0"
__wordlist
;;
"Make wordlist aggressive")
__wordlist
;;
"Make wordlist aggressive")
export aggressive="1"
_checkGecko
__wordlist
;;
*) echo -e "\033[31mRFTM\033[0m";exit ;;
esac
done
printf "\033[0m"
__wordlist
;;
"Quit")
exit 0
;;
*)
echo -e "\033[31mUnknown option. Try again.\033[0m"
;;
esac
done
printf "\033[0m"
}

if [[ ! "$1" ]]
then
__interative
else
# vars for iterations
i=1
x=1
util=0
save=""
time=""

while [ "$i" -le "$#" ]
do
# arg: argument
# narg: next arg.
# parg: primary arg.
# pvarg: primary value of arg.

eval "arg=\${$i}"
eval "narg=\${$(($i+1))}"

# The block of code are for arguments
# like "-o, --output", for get the arg.
# when will be used.

while [ "$x" -le "$#" ]
do
# para: parameter
# dest: destination
eval "para=\${$x}"
eval "dest=\${$(($x+1))}"

case "$para" in
--o* | "-o")
# export the file for storaged
export save="$dest"
;;
--r* | "-r")
export time="$dest"
;;
--a* | -*a*)
export aggressive="1"
_checkGecko
;;
esac

# For work in loop
x=$(($x+1))
done

case "$arg" in
--h* | "-h")
echo "$help"
exit 0
;;&
--w* | -*w*)
echo "Make the smart wordlist"
if [[ $narg =~ ^- ]]
then
test "$save" == "" && \
__wordlist "" "" "$time"|| \
__wordlist "" "$save" "$time"
else
test "$save" == "" && \
__wordlist "$narg" "" "$time"|| \
__wordlist "$narg" "$save" "$time"
fi

util=$(($util+1))
;;&
--b* | -*b*)
echo "Make custom wordlist"
if [ $save ]
then
[ "$narg" ] && __cus "$narg" "$save" || ( echo -e " $orange → bash main --help$end ";exit 2)
else
[ "$narg" ] && __cus "$narg" || ( echo -e " $orange → bash main --help$end ";exit 2 )
fi

util=$(($util+1))
;;
--t* | -*t*)
echo -e "Targets inputed in $orange $narg $green "
__fwordlist "$narg" "" "$time"


util=$(($util+1))
;;

esac
i=$(($i+1))
done

if [ $util == 0 ]
then
echo "Opening to interative mode..."
__interative
fi
fi
# ── Despacho principal ────────────────────────────────────────────────
# O módulo Python correto é selecionado com base nos flags.
# scraper.py → -w / -t (assíncrono, lxml)
# aggressive.py → -a (pool de browser Playwright/geckodriver)
# wordlist.py → -b (streaming, Counter, GoMutation integrado)

case "$1" in
-w|--wordlist)
python3 -c "
from modules.scraper import scrape
from modules.wordlist import generate
import sys, os

url = sys.argv[1]
rate = float(os.environ.get('rate', 0))
output = os.environ.get('output', '')

words = scrape([url], rate=rate)
generate(words=words, output=output or None, mutate=True)
" "$2"
;;

-t|--targets)
python3 -c "
from modules.scraper import scrape
from modules.wordlist import generate
import sys, os

targets_file = sys.argv[1]
rate = float(os.environ.get('rate', 0))
output = os.environ.get('output', '')

with open(targets_file) as f:
urls = [line.strip() for line in f if line.strip()]

words = scrape(urls, rate=rate)
generate(words=words, output=output or None, mutate=True)
" "$2"
;;

-b|--based)
python3 -c "
from modules.wordlist import generate
import sys, os

based_file = sys.argv[1]
output = os.environ.get('output', '')
generate(based_file=based_file, output=output or None, mutate=True)
" "$2"
;;

*)
# Sem argumento → menu interativo ou parse via load.sh (comportamento original)
if [ -z "$1" ]; then
__interative
else
# Delegação ao parser de argumentos original (functions.sh)
__parse_args "$@"
fi
;;
esac
Loading
Loading