Skip to content

Commit 15168b4

Browse files
authored
Merge pull request #923 from pgrenaud/add-pipx-and-virtual-env-support
Add pipx and virtual env support
2 parents 1360e2d + 6612437 commit 15168b4

File tree

3 files changed

+97
-100
lines changed

3 files changed

+97
-100
lines changed

install.sh

Lines changed: 67 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -83,31 +83,39 @@ declare -A gotools=(
8383
["urlfinder"]="go install -v github.com/projectdiscovery/urlfinder/cmd/urlfinder@latest"
8484
)
8585

86-
# Declare repositories and their paths
87-
declare -A repos=(
88-
["dorks_hunter"]="six2dez/dorks_hunter"
86+
# Declare pipx tools and their paths
87+
declare -A pipxtools=(
8988
["dnsvalidator"]="vortexau/dnsvalidator"
9089
["interlace"]="codingo/Interlace"
9190
["wafw00f"]="EnableSecurity/wafw00f"
91+
["commix"]="commixproject/commix"
92+
["urless"]="xnl-h4ck3r/urless"
93+
["ghauri"]="r0oth3x49/ghauri"
94+
["xnLinkFinder"]="xnl-h4ck3r/xnLinkFinder"
95+
["porch-pirate"]="MandConsultingGroup/porch-pirate"
96+
["MetaFinder"]="Josue87/MetaFinder"
97+
["EmailFinder"]="Josue87/EmailFinder"
98+
)
99+
100+
# Declare repositories and their paths
101+
declare -A repos=(
102+
["dorks_hunter"]="six2dez/dorks_hunter"
92103
["gf"]="tomnomnom/gf"
93104
["Gf-Patterns"]="1ndianl33t/Gf-Patterns"
94105
["Corsy"]="s0md3v/Corsy"
95106
["CMSeeK"]="Tuhinshubhra/CMSeeK"
96107
["fav-up"]="pielco11/fav-up"
97108
["massdns"]="blechschmidt/massdns"
98109
["Oralyzer"]="r0075h3ll/Oralyzer"
99-
["testssl.sh"]="drwetter/testssl.sh"
100-
["commix"]="commixproject/commix"
110+
["testssl"]="drwetter/testssl.sh"
101111
["JSA"]="w9w/JSA"
102112
["CloudHunter"]="belane/CloudHunter"
103113
["ultimate-nmap-parser"]="shifty0g/ultimate-nmap-parser"
104114
["pydictor"]="LandGrey/pydictor"
105115
["gitdorks_go"]="damit5/gitdorks_go"
106-
["urless"]="xnl-h4ck3r/urless"
107116
["smuggler"]="defparam/smuggler"
108117
["Web-Cache-Vulnerability-Scanner"]="Hackmanit/Web-Cache-Vulnerability-Scanner"
109118
["regulator"]="cramppet/regulator"
110-
["ghauri"]="r0oth3x49/ghauri"
111119
["gitleaks"]="gitleaks/gitleaks"
112120
["trufflehog"]="trufflesecurity/trufflehog"
113121
["nomore403"]="devploit/nomore403"
@@ -116,10 +124,6 @@ declare -A repos=(
116124
["ffufPostprocessing"]="Damian89/ffufPostprocessing"
117125
["misconfig-mapper"]="intigriti/misconfig-mapper"
118126
["Spoofy"]="MattKeeley/Spoofy"
119-
["xnLinkFinder"]="xnl-h4ck3r/xnLinkFinder"
120-
["porch-pirate"]="MandConsultingGroup/porch-pirate"
121-
["MetaFinder"]="Josue87/MetaFinder"
122-
["EmailFinder"]="Josue87/EmailFinder"
123127
)
124128

125129
# Function to display the banner
@@ -169,6 +173,43 @@ function install_tools() {
169173
fi
170174
done
171175

176+
echo -e "\n${bblue}Running: Installing pipx tools (${#repos[@]})${reset}\n"
177+
178+
local pipx_step=0
179+
local failed_pipx_tools=()
180+
181+
for pipxtool in "${!pipxtools[@]}"; do
182+
((pipx_step++))
183+
if [[ $upgrade_tools == "false" ]]; then
184+
if command -v "$pipxtool" &>/dev/null; then
185+
echo -e "[${yellow}SKIPPING${reset}] $pipxtool already installed at $(command -v "$pipxtool")"
186+
continue
187+
fi
188+
fi
189+
190+
# Install the pipx tool
191+
eval pipx install "git+https://github.com/${pipxtools[$pipxtool]}" &>/dev/null
192+
exit_status=$?
193+
if [[ $exit_status -ne 0 ]]; then
194+
echo -e "${red}Failed to install $pipxtool, try manually (${pipx_step}/${#pipxtools[@]})${reset}"
195+
failed_pipx_tools+=("$pipxtool")
196+
double_check=true
197+
continue
198+
fi
199+
200+
# Upgrade the pipx tool
201+
eval pipx upgrade "${pipxtool}" &>/dev/null
202+
exit_status=$?
203+
if [[ $exit_status -ne 0 ]]; then
204+
echo -e "${red}Failed to upgrade $pipxtool, try manually (${pipx_step}/${#pipxtools[@]})${reset}"
205+
failed_pipx_tools+=("$pipxtool")
206+
double_check=true
207+
continue
208+
fi
209+
210+
echo -e "${yellow}$pipxtool installed (${pipx_step}/${#pipxtools[@]})${reset}"
211+
done
212+
172213
echo -e "\n${bblue}Running: Installing repositories (${#repos[@]})${reset}\n"
173214

174215
local repos_step=0
@@ -212,9 +253,14 @@ function install_tools() {
212253
continue
213254
fi
214255

215-
# Install dependencies if setup.py exists
216-
if [[ -f "setup.py" ]]; then
217-
eval "$SUDO pipx install . $DEBUG_STD" &>/dev/null
256+
# Install requirements inside a virtual environment
257+
if [[ -s "requirements.txt" ]]; then
258+
if [[ ! -f "venv/bin/activate" ]]; then
259+
python3 -m venv venv &>/dev/null
260+
fi
261+
source venv/bin/activate
262+
eval "pip3 install --upgrade -r requirements.txt $DEBUG_STD" &>/dev/null
263+
deactivate
218264
fi
219265

220266
# Special handling for certain repositories
@@ -273,6 +319,10 @@ function install_tools() {
273319
echo -e "\n${red}Failed to install the following Go tools: ${failed_tools[*]}${reset}"
274320
fi
275321

322+
if [[ ${#failed_pipx_tools[@]} -ne 0 ]]; then
323+
echo -e "\n${red}Failed to install the following pipx tools: ${failed_pipx_tools[*]}${reset}"
324+
fi
325+
276326
if [[ ${#failed_repos[@]} -ne 0 ]]; then
277327
echo -e "\n${red}Failed to clone or update the following repositories:\n${failed_repos[*]}${reset}"
278328
fi
@@ -448,7 +498,7 @@ function install_yum() {
448498

449499
# Function to install required packages for Arch-based systems
450500
function install_pacman() {
451-
"$SUDO" pacman -Sy --noconfirm python python-pip base-devel gcc cmake ruby git curl libpcap pipx whois wget zip pv bind openssl libffi libxml2 libxslt zlib nmap jq lynx medusa xorg-server-xvfb &>/dev/null
501+
"$SUDO" pacman -Sy --noconfirm python python-pip base-devel gcc cmake ruby git curl libpcap python-pipx whois wget zip pv bind openssl libffi libxml2 libxslt zlib nmap jq lynx medusa xorg-server-xvfb &>/dev/null
452502
curl https://sh.rustup.rs -sSf | sh -s -- -y >/dev/null 2>&1
453503
source "${HOME}/.cargo/env"
454504
cargo install ripgen &>/dev/null
@@ -475,12 +525,8 @@ function initial_setup() {
475525
touch "${dir}/.github_tokens"
476526
touch "${dir}/.gitlab_tokens"
477527

478-
wget -N -c https://bootstrap.pypa.io/get-pip.py -O /tmp/get-pip.py &>/dev/null
479-
python3 /tmp/get-pip.py &>/dev/null
480-
rm -f /tmp/get-pip.py
481-
482-
pipx install reconftw &>/dev/null
483-
pipx inject mkdocs -r requirements.txt &>/dev/null
528+
eval pipx ensurepath $DEBUG_STD
529+
source "${HOME}/${profile_shell}"
484530

485531
install_tools
486532

@@ -522,26 +568,6 @@ function initial_setup() {
522568
eval git -C "${dir}/massdns" pull $DEBUG_STD
523569
fi
524570

525-
# Interlace
526-
if [[ ! -d "${dir}/interlace" ]]; then
527-
#printf "${yellow}Cloning Interlace...${reset}\n"
528-
eval git clone https://github.com/codingo/Interlace.git "${dir}/interlace" $DEBUG_STD
529-
eval cd "${dir}/interlace" && eval $SUDO python3 setup.py install $DEBUG_STD
530-
else
531-
#printf "${yellow}Updating Interlace...${reset}\n"
532-
eval git -C "${dir}/interlace" pull $DEBUG_STD
533-
fi
534-
535-
# wafw00f
536-
if [[ ! -d "${dir}/wafw00f" ]]; then
537-
#printf "${yellow}Cloning wafw00f...${reset}\n"
538-
eval git clone https://github.com/EnableSecurity/wafw00f.git "${dir}/wafw00f" $DEBUG_STD
539-
eval cd "${dir}/wafw00f" && eval $SUDO python3 setup.py install $DEBUG_STD
540-
else
541-
#printf "${yellow}Updating wafw00f...${reset}\n"
542-
eval git -C "${dir}/wafw00f" pull $DEBUG_STD
543-
fi
544-
545571
# gf patterns
546572
if [[ ! -d "$HOME/.gf" ]]; then
547573
#printf "${yellow}Installing gf patterns...${reset}\n"

reconftw.sh

Lines changed: 30 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -120,32 +120,42 @@ function tools_installed() {
120120
# Define tools and their paths/commands
121121
declare -A tools_files=(
122122
["dorks_hunter"]="${tools}/dorks_hunter/dorks_hunter.py"
123+
["dorks_hunter_python"]="${tools}/dorks_hunter/venv/bin/python3"
123124
["fav-up"]="${tools}/fav-up/favUp.py"
125+
["fav-up_python"]="${tools}/fav-up/venv/bin/python3"
124126
["Corsy"]="${tools}/Corsy/corsy.py"
125-
["testssl.sh"]="${tools}/testssl.sh/testssl.sh"
127+
["Corsy_python"]="${tools}/Corsy/venv/bin/python3"
128+
["testssl"]="${tools}/testssl.sh/testssl.sh"
126129
["CMSeeK"]="${tools}/CMSeeK/cmseek.py"
130+
["CMSeeK_python"]="${tools}/CMSeeK/venv/bin/python3"
127131
["OneListForAll"]="$fuzz_wordlist"
128132
["lfi_wordlist"]="$lfi_wordlist"
129133
["ssti_wordlist"]="$ssti_wordlist"
130134
["subs_wordlist"]="$subs_wordlist"
131135
["subs_wordlist_big"]="$subs_wordlist_big"
132136
["resolvers"]="$resolvers"
133137
["resolvers_trusted"]="$resolvers_trusted"
134-
["commix"]="${tools}/commix/commix.py"
135138
["getjswords"]="${tools}/getjswords.py"
136139
["JSA"]="${tools}/JSA/jsa.py"
140+
["JSA_python"]="${tools}/JSA/venv/bin/python3"
137141
["CloudHunter"]="${tools}/CloudHunter/cloudhunter.py"
142+
["CloudHunter_python"]="${tools}/CloudHunter/venv/bin/python3"
138143
["nmap-parse-output"]="${tools}/ultimate-nmap-parser/ultimate-nmap-parser.sh"
139144
["pydictor"]="${tools}/pydictor/pydictor.py"
140-
["urless"]="${tools}/urless/urless/urless.py"
141145
["smuggler"]="${tools}/smuggler/smuggler.py"
142146
["regulator"]="${tools}/regulator/main.py"
147+
["regulator_python"]="${tools}/regulator/venv/bin/python3"
143148
["nomore403"]="${tools}/nomore403/nomore403"
144149
["ffufPostprocessing"]="${tools}/ffufPostprocessing/ffufPostprocessing"
145150
["misconfig-mapper"]="${tools}/misconfig-mapper/misconfig-mapper"
146151
["spoofy"]="${tools}/Spoofy/spoofy.py"
152+
["spoofy_python"]="${tools}/Spoofy/venv/bin/python3"
147153
["swaggerspy"]="${tools}/SwaggerSpy/swaggerspy.py"
154+
["swaggerspy_python"]="${tools}/SwaggerSpy/venv/bin/python3"
148155
["LeakSearch"]="${tools}/LeakSearch/LeakSearch.py"
156+
["LeakSearch_python"]="${tools}/LeakSearch/venv/bin/python3"
157+
["Oralyzer"]="${tools}/Oralyzer/oralyzer.py"
158+
["Oralyzer_python"]="${tools}/Oralyzer/venv/bin/python3"
149159
)
150160

151161
declare -A tools_folders=(
@@ -219,6 +229,8 @@ function tools_installed() {
219229
["sns"]="sns"
220230
["sourcemapper"]="sourcemapper"
221231
["jsluice"]="jsluice"
232+
["commix"]="commix"
233+
["urless"]="urless"
222234
["dnstake"]="dnstake"
223235
)
224236

@@ -280,7 +292,7 @@ function google_dorks() {
280292
if { [[ ! -f "$called_fn_dir/.${FUNCNAME[0]}" ]] || [[ $DIFF == true ]]; } && [[ $GOOGLE_DORKS == true ]] && [[ $OSINT == true ]]; then
281293
start_func "${FUNCNAME[0]}" "Running: Google Dorks in process"
282294

283-
python3 "${tools}/dorks_hunter/dorks_hunter.py" -d "$domain" -o "osint/dorks.txt"
295+
"${tools}/dorks_hunter/venv/bin/python3" "${tools}/dorks_hunter/dorks_hunter.py" -d "$domain" -o "osint/dorks.txt"
284296
end_func "Results are saved in $domain/osint/dorks.txt" "${FUNCNAME[0]}"
285297
else
286298
if [[ $GOOGLE_DORKS == false ]] || [[ $OSINT == false ]]; then
@@ -464,7 +476,7 @@ function apileaks() {
464476
fi
465477

466478
# Run swaggerspy.py and handle errors
467-
python3 swaggerspy.py "$domain" 2>>"$LOGFILE" | grep -i "[*]\|URL" >"${dir}/osint/swagger_leaks.txt"
479+
"${tools}/SwaggerSpy/venv/bin/python3" swaggerspy.py "$domain" 2>>"$LOGFILE" | grep -i "[*]\|URL" >"${dir}/osint/swagger_leaks.txt"
468480

469481
# Return to the previous directory
470482
if ! popd >/dev/null; then
@@ -518,7 +530,7 @@ function emails() {
518530
fi
519531

520532
# Run LeakSearch.py and handle errors
521-
python3 LeakSearch.py -k "$domain" -o "${dir}/.tmp/passwords.txt" 1>>"$LOGFILE"
533+
"${tools}/LeakSearch/venv/bin/python3" LeakSearch.py -k "$domain" -o "${dir}/.tmp/passwords.txt" 1>>"$LOGFILE"
522534

523535
# Return to the previous directory
524536
if ! popd >/dev/null; then
@@ -642,7 +654,7 @@ function spoof() {
642654
fi
643655

644656
# Run spoofy.py and handle errors
645-
./spoofy.py -d "$domain" >"${dir}/osint/spoof.txt"
657+
"${tools}/Spoofy/venv/bin/python3" spoofy.py -d "$domain" >"${dir}/osint/spoof.txt"
646658

647659
# Return to the previous directory
648660
if ! popd >/dev/null; then
@@ -1805,7 +1817,7 @@ function sub_regex_permut() {
18051817
fi
18061818

18071819
# Run the main.py script
1808-
python3 main.py -t "$domain" -f "${dir}/subdomains/subdomains.txt" -o "${dir}/.tmp/${domain}.brute" \
1820+
"${tools}/regulator/venv/bin/python3" main.py -t "$domain" -f "${dir}/subdomains/subdomains.txt" -o "${dir}/.tmp/${domain}.brute" \
18091821
2>>"$LOGFILE" >/dev/null
18101822

18111823
# Return to the previous directory
@@ -2389,7 +2401,7 @@ function s3buckets() {
23892401
esac
23902402

23912403
# Debug: Print the full CloudHunter command
2392-
printf "CloudHunter command: python3 %s/cloudhunter.py %s -r %s/resolvers.txt -t 50 [URL]\n" "$tools/CloudHunter" "$PERMUTATION_FLAG" "$tools/CloudHunter" >>"$LOGFILE"
2404+
printf "CloudHunter command: %s/venv/bin/python3 %s/cloudhunter.py %s -r %s/resolvers.txt -t 50 [URL]\n" "$tools/CloudHunter" "$tools/CloudHunter" "$PERMUTATION_FLAG" "$tools/CloudHunter" >>"$LOGFILE"
23932405

23942406
# Debug: Check if files exist
23952407
if [[ -f "$tools/CloudHunter/cloudhunter.py" ]]; then
@@ -2421,7 +2433,7 @@ function s3buckets() {
24212433
printf "%b[!] Failed to cd to %s.%b\n" "$bred" "$tools/CloudHunter" "$reset"
24222434
return 1
24232435
fi
2424-
if ! python3 ./cloudhunter.py ${PERMUTATION_FLAG#-p } -r ./resolvers.txt -t 50 "$url"; then
2436+
if ! "${tools}/CloudHunter/venv/bin/python3" ./cloudhunter.py ${PERMUTATION_FLAG#-p } -r ./resolvers.txt -t 50 "$url"; then
24252437
printf "%b[!] CloudHunter command failed for URL %s.%b\n" "$bred" "$url" "$reset"
24262438
fi
24272439
) >>"$dir/subdomains/cloudhunter_open_buckets.txt" 2>>"$LOGFILE"
@@ -2920,7 +2932,7 @@ function favicon() {
29202932
fi
29212933

29222934
# Run the favicon IP lookup tool
2923-
python3 favUp.py -w "$domain" -sc -o favicontest.json 2>>"$LOGFILE" >/dev/null
2935+
"${tools}/fav-up/venv/bin/python3" "${tools}/fav-up/favUp.py" -w "$domain" -sc -o favicontest.json 2>>"$LOGFILE" >/dev/null
29242936

29252937
# Process the results if favicontest.json exists and is not empty
29262938
if [[ -s "favicontest.json" ]]; then
@@ -3456,7 +3468,7 @@ function cms_scanner() {
34563468
fi
34573469

34583470
# Run CMSeeK with timeout
3459-
if ! timeout -k 1m "${CMSSCAN_TIMEOUT}s" python3 "${tools}/CMSeeK/cmseek.py" -l .tmp/cms.txt --batch -r &>>"$LOGFILE"; then
3471+
if ! timeout -k 1m "${CMSSCAN_TIMEOUT}s" "${tools}/CMSeeK/venv/bin/python3" "${tools}/CMSeeK/cmseek.py" -l .tmp/cms.txt --batch -r &>>"$LOGFILE"; then
34603472
exit_status=$?
34613473
if [[ ${exit_status} -eq 124 || ${exit_status} -eq 137 ]]; then
34623474
echo "TIMEOUT cmseek.py - investigate manually for $dir" >>"$LOGFILE"
@@ -3560,13 +3572,13 @@ function urlchecks() {
35603572
grep "$domain" .tmp/url_extract_tmp.txt | grep -E '^((http|https):\/\/)?([a-zA-Z0-9\-\.]+\.)+[a-zA-Z]{1,}(\/.*)?$' | grep -aEi "\.js$" | anew -q .tmp/url_extract_js.txt
35613573
grep "$domain" .tmp/url_extract_tmp.txt | grep -E '^((http|https):\/\/)?([a-zA-Z0-9\-\.]+\.)+[a-zA-Z]{1,}(\/.*)?$' | grep -aEi "\.js\.map$" | anew -q .tmp/url_extract_jsmap.txt
35623574
if [[ $DEEP == true ]] && [[ -s ".tmp/url_extract_js.txt" ]]; then
3563-
interlace -tL .tmp/url_extract_js.txt -threads 10 -c "python3 ${tools}/JSA/jsa.py -f _target_ | anew -q .tmp/url_extract_tmp.txt" &>/dev/null
3575+
interlace -tL .tmp/url_extract_js.txt -threads 10 -c "${tools}/JSA/venv/bin/python3 ${tools}/JSA/jsa.py -f _target_ | anew -q .tmp/url_extract_tmp.txt" &>/dev/null
35643576
fi
35653577

35663578
grep "$domain" .tmp/url_extract_tmp.txt | grep -E '^((http|https):\/\/)?([a-zA-Z0-9\-\.]+\.)+[a-zA-Z]{1,}(\/.*)?$' | grep "=" | qsreplace -a 2>>"$LOGFILE" | grep -aEiv "\.(eot|jpg|jpeg|gif|css|tif|tiff|png|ttf|otf|woff|woff2|ico|pdf|svg|txt|js)$" | anew -q .tmp/url_extract_tmp2.txt
35673579

35683580
if [[ -s ".tmp/url_extract_tmp2.txt" ]]; then
3569-
python3 "${tools}/urless/urless/urless.py" <.tmp/url_extract_tmp2.txt | anew -q .tmp/url_extract_uddup.txt 2>>"$LOGFILE" >/dev/null
3581+
urless <.tmp/url_extract_tmp2.txt | anew -q .tmp/url_extract_uddup.txt 2>>"$LOGFILE" >/dev/null
35703582
fi
35713583

35723584
if [[ -s ".tmp/url_extract_uddup.txt" ]]; then
@@ -3764,7 +3776,7 @@ function jschecks() {
37643776
grep -iE "\.js($|\?)" .tmp/subjslinks.txt | anew -q .tmp/url_extract_js.txt
37653777
fi
37663778

3767-
python3 "${tools}/urless/urless/urless.py" <.tmp/url_extract_js.txt |
3779+
urless <.tmp/url_extract_js.txt |
37683780
anew -q js/url_extract_js.txt 2>>"$LOGFILE" >/dev/null
37693781

37703782
printf "%bRunning: Resolving JS URLs 2/6%b\n" "$yellow" "$reset"
@@ -4180,7 +4192,7 @@ function cors() {
41804192
# Proceed only if webs_all.txt exists and is non-empty
41814193
if [[ -s "webs/webs_all.txt" ]]; then
41824194
printf "${yellow}\n[$(date +'%Y-%m-%d %H:%M:%S')] Running: Corsy for CORS Scan${reset}\n\n"
4183-
python3 "${tools}/Corsy/corsy.py" -i "webs/webs_all.txt" -o "vulns/cors.txt" 2>>"$LOGFILE" >/dev/null
4195+
"${tools}/Corsy/venv/bin/python3" "${tools}/Corsy/corsy.py" -i "webs/webs_all.txt" -o "vulns/cors.txt" 2>>"$LOGFILE" >/dev/null
41844196
else
41854197
end_func "No webs/webs_all.txt file found, CORS Scan skipped." "${FUNCNAME[0]}"
41864198
return
@@ -4225,7 +4237,7 @@ function open_redirect() {
42254237
qsreplace FUZZ <"gf/redirect.txt" | sed '/FUZZ/!d' | anew -q ".tmp/tmp_redirect.txt"
42264238

42274239
# Run Oralyzer with the generated payloads
4228-
python3 "${tools}/Oralyzer/oralyzer.py" -l ".tmp/tmp_redirect.txt" -p "${tools}/Oralyzer/payloads.txt" >"vulns/redirect.txt" 2>>"$LOGFILE" >/dev/null
4240+
"${tools}/Oralyzer/venv/bin/python3" "${tools}/Oralyzer/oralyzer.py" -l ".tmp/tmp_redirect.txt" -p "${tools}/Oralyzer/payloads.txt" >"vulns/redirect.txt" 2>>"$LOGFILE" >/dev/null
42294241

42304242
# Remove ANSI color codes from the output
42314243
sed -r -i "s/\x1B\[([0-9]{1,3}(;[0-9]{1,2})?)?[mGK]//g" "vulns/redirect.txt"
@@ -4650,7 +4662,7 @@ function command_injection() {
46504662
# Run Commix if enabled
46514663
if [[ $SQLMAP == true ]]; then
46524664
printf "${yellow}\n[$(date +'%Y-%m-%d %H:%M:%S')] Running: Commix for Command Injection Checks${reset}\n\n"
4653-
python3 "${tools}/commix/commix.py" --batch -m ".tmp/tmp_rce.txt" --output-dir "vulns/command_injection" 2>>"$LOGFILE" >/dev/null
4665+
commix --batch -m ".tmp/tmp_rce.txt" --output-dir "vulns/command_injection" 2>>"$LOGFILE" >/dev/null
46544666
fi
46554667

46564668
# Additional tools can be integrated here (e.g., Ghauri, sqlmap)

0 commit comments

Comments
 (0)