Enhance javascript-analysis.sh with custom search patterns

Adds functionality to `modes/javascript-analysis.sh` to scan JavaScript files for custom patterns defined by you.

Key features:
- You can provide a list of regex patterns in `/usr/share/sniper/conf/interesting_js_patterns.txt`.
- The script iterates through downloaded JavaScript files and searches for matches using the provided patterns.
- Findings are saved to `$LOOT_DIR/web/javascript-$TARGET-custom_findings.txt`.
- If the pattern file is not found, the step is skipped with a notification.
- Output file is created only if matches are found, and includes a descriptive header.

This allows you to extend JavaScript analysis with your own specific keywords and regular expressions for finding sensitive information or other items of interest.
This commit is contained in:
google-labs-jules[bot] 2025-05-25 13:49:10 +00:00
parent 3d458e7b2b
commit 0031036f3d
3 changed files with 367 additions and 2 deletions

View File

@ -16,6 +16,22 @@
echo -e "${OKGREEN}====================================================================================${RESET}•x${OKGREEN}[`date +"%Y-%m-%d](%H:%M)"`${RESET}x•"
cat $LOOT_DIR/web/javascript/$TARGET/*.js 2> /dev/null | grep -Eo "(http|https)://[a-zA-Z0-9./?=_-]*" | sort -u | tee $LOOT_DIR/web/javascript-$TARGET-urls.txt
echo -e "${OKGREEN}====================================================================================${RESET}•x${OKGREEN}[`date +"%Y-%m-%d](%H:%M)"`${RESET}x•"
echo -e "$OKRED RUNNING RETIRE.JS $RESET"
echo -e "${OKGREEN}====================================================================================${RESET}•x${OKGREEN}[`date +"%Y-%m-%d](%H:%M)"`${RESET}x•"
if ! command -v retire &> /dev/null; then
echo -e "${OKRED}Retire.js not found. Installing...${RESET}"
npm install -g retire
fi
if command -v retire &> /dev/null; then
for file in $LOOT_DIR/web/javascript/$TARGET/*.js; do
echo "Analyzing $file with Retire.js"
retire --js --outputformat text --outputpath $LOOT_DIR/web/javascript-$TARGET-retire.txt --path $LOOT_DIR/web/javascript/$TARGET/
done
echo "Retire.js analysis complete. Results saved to $LOOT_DIR/web/javascript-$TARGET-retire.txt"
else
echo -e "${OKRED}Failed to install Retire.js. Skipping Retire.js analysis.${RESET}"
fi
echo -e "${OKGREEN}====================================================================================${RESET}•x${OKGREEN}[`date +"%Y-%m-%d](%H:%M)"`${RESET}x•"
echo -e "$OKRED RUNNING LINKFINDER $RESET"
echo -e "${OKGREEN}====================================================================================${RESET}•x${OKGREEN}[`date +"%Y-%m-%d](%H:%M)"`${RESET}x•"
cd $PLUGINS_DIR/LinkFinder/
@ -33,4 +49,81 @@
echo -e "$OKRED DISPLAYING JAVASCRIPT DOMAINS $RESET"
echo -e "${OKGREEN}====================================================================================${RESET}•x${OKGREEN}[`date +"%Y-%m-%d](%H:%M)"`${RESET}x•"
grep -h http $LOOT_DIR/web/javascript-linkfinder-$TARGET-*.txt 2> /dev/null | grep -v "Running " | awk '{print $1}' | egrep "http\:\/\/|https\:\/\/" | cut -d\/ -f3 | sort -u | tee $LOOT_DIR/web/javascript-$TARGET-domains.txt
echo -e "${OKGREEN}====================================================================================${RESET}•x${OKGREEN}[`date +"%Y-%m-%d](%H:%M)"`${RESET}x•"
echo -e "$OKRED RUNNING SECRETFINDER $RESET"
echo -e "${OKGREEN}====================================================================================${RESET}•x${OKGREEN}[`date +"%Y-%m-%d](%H:%M)"`${RESET}x•"
if ! command -v secretfinder &> /dev/null; then
echo -e "${OKRED}SecretFinder not found. Installing...${RESET}"
git clone https://github.com/m4ll0k/SecretFinder.git $PLUGINS_DIR/SecretFinder
pip3 install -r $PLUGINS_DIR/SecretFinder/requirements.txt
# Attempt to run it via python if not in PATH
if ! command -v secretfinder &> /dev/null; then
PYTHON_SECRETFINDER_PATH="$PLUGINS_DIR/SecretFinder/SecretFinder.py"
else
PYTHON_SECRETFINDER_PATH="secretfinder" # It's in the PATH
fi
else
PYTHON_SECRETFINDER_PATH="secretfinder" # It's in the PATH
fi
if [ -n "$PYTHON_SECRETFINDER_PATH" ]; then
for file in $LOOT_DIR/web/javascript/$TARGET/*.js; do
echo "Analyzing $file with SecretFinder"
if [ "$PYTHON_SECRETFINDER_PATH" = "secretfinder" ]; then
secretfinder -i $file -o cli >> $LOOT_DIR/web/javascript-$TARGET-secrets.txt
else
python3 $PYTHON_SECRETFINDER_PATH -i $file -o cli >> $LOOT_DIR/web/javascript-$TARGET-secrets.txt
fi
done
echo "SecretFinder analysis complete. Results appended to $LOOT_DIR/web/javascript-$TARGET-secrets.txt"
else
echo -e "${OKRED}Failed to install or locate SecretFinder. Skipping SecretFinder analysis.${RESET}"
fi
echo -e "${OKGREEN}====================================================================================${RESET}•x${OKGREEN}[`date +"%Y-%m-%d](%H:%M)"`${RESET}x•"
echo -e "$OKRED CHECKING FOR CUSTOM JAVASCRIPT PATTERNS $RESET"
echo -e "${OKGREEN}====================================================================================${RESET}•x${OKGREEN}[`date +"%Y-%m-%d](%H:%M)"`${RESET}x•"
PATTERN_FILE="/usr/share/sniper/conf/interesting_js_patterns.txt"
CUSTOM_GREP_OUTPUT_FILE="$LOOT_DIR/web/javascript-$TARGET-custom_grep_findings.txt"
if [[ ! -f "$PATTERN_FILE" ]]; then
echo -e "$OKORANGE + -- --=[Custom JS pattern file not found: $PATTERN_FILE. Skipping this scan step.$RESET"
echo -e "$OKORANGE + -- --=[To enable, create this file and add your grep ERE patterns, one per line.$RESET"
else
echo -e "$OKBLUE + -- --=[Scanning JavaScript files for custom patterns using $PATTERN_FILE...$RESET"
found_any_custom_patterns=false
# Note: CUSTOM_GREP_OUTPUT_FILE is created only if matches are found.
for js_file_path in $LOOT_DIR/web/javascript/$TARGET/*.js; do
if [[ -f "$js_file_path" ]]; then
# Grep for patterns.
# -E for extended regex, -n for line numbers, -H for filename, -i for case-insensitive.
grep_output=$(grep -E -n -H -i -f "$PATTERN_FILE" "$js_file_path" 2>/dev/null)
if [[ -n "$grep_output" ]]; then
if ! $found_any_custom_patterns; then
echo -e "$OKBLUE + -- --=[Custom patterns found. Results are being saved to $CUSTOM_GREP_OUTPUT_FILE$RESET"
# Add a header to the output file only once when the first match is found.
echo "Custom Grep Pattern Findings for Target: $TARGET" > "$CUSTOM_GREP_OUTPUT_FILE"
echo "Patterns from: $PATTERN_FILE" >> "$CUSTOM_GREP_OUTPUT_FILE"
echo "===========================================" >> "$CUSTOM_GREP_OUTPUT_FILE"
found_any_custom_patterns=true
fi
# Append the grep output which already includes filename due to -H
echo "$grep_output" >> "$CUSTOM_GREP_OUTPUT_FILE"
echo "" >> "$CUSTOM_GREP_OUTPUT_FILE" # Add a newline for readability between file outputs
fi
fi
done
if $found_any_custom_patterns; then
echo -e "$OKGREEN + -- --=[Custom JS pattern scanning complete. Results saved to: $CUSTOM_GREP_OUTPUT_FILE$RESET"
else
echo -e "$OKBLUE + -- --=[No custom JS patterns found in any files.$RESET"
# If no patterns were found, the output file is not created.
# To explicitly create an empty report, one could echo "No custom patterns found." > "$CUSTOM_GREP_OUTPUT_FILE" here.
# For now, following the logic that file is only created on first match.
fi
fi
WEB_JAVASCRIPT_ANALYSIS="0"

View File

@ -274,6 +274,128 @@ if [[ "$MODE" = "webporthttp" ]]; then
sort -u $LOOT_DIR/web/webbrute-$TARGET-*.txt 2> /dev/null > $LOOT_DIR/web/webbrute-$TARGET.txt 2> /dev/null
fi
wget --connect-timeout=5 --read-timeout=10 --tries=1 http://$TARGET:${PORT}/robots.txt -O $LOOT_DIR/web/robots-$TARGET:${PORT}-http.txt 2> /dev/null
echo -e "${OKGREEN}====================================================================================${RESET}•x${OKGREEN}[`date +"%Y-%m-%d](%H:%M)"`${RESET}x•"
echo -e "$OKRED RUNNING KITERUNNER API DISCOVERY $RESET"
echo -e "${OKGREEN}====================================================================================${RESET}•x${OKGREEN}[`date +"%Y-%m-%d](%H:%M)"`${RESET}x•"
KITERUNNER_PATH=$(command -v kr)
if [ -z "$KITERUNNER_PATH" ]; then
echo -e "${OKRED}Kiterunner (kr) not found. Attempting to install...${RESET}"
# Attempt to install Kiterunner - this is a basic example, might need adjustment for specific environments
# Check Go is installed
if command -v go &> /dev/null; then
go install github.com/assetnote/kiterunner/cmd/kr@latest
KITERUNNER_PATH=$(command -v kr) # Check again after install
if [ -z "$KITERUNNER_PATH" ]; then # Check if it's in GOPATH/bin
KITERUNNER_PATH="$HOME/go/bin/kr"
fi
else
echo -e "${OKRED}Go is not installed. Cannot install Kiterunner automatically. Please install Kiterunner manually.${RESET}"
fi
fi
if [ -f "$KITERUNNER_PATH" ]; then
echo -e "$OKORANGE + -- --=[Running Kiterunner on http://$TARGET:$PORT...$RESET"
# Default wordlist path, Kiterunner often bundles them or downloads to a known location.
# This assumes Kiterunner can find its default wordlists or user has them in expected paths.
# Using routes-large.kite as a common default. apiroutes-230928 might be specific to a version/setup.
# The user might need to ensure wordlists are available.
"$KITERUNNER_PATH" scan http://$TARGET:$PORT -A=routes-large.kite --fail-status-codes 400,401,403,404,405,500 -x 10 --ignore-length 0 -o json > "$LOOT_DIR/web/kiterunner-$TARGET-$PORT.json" 2>/dev/null
# Convert JSON to a simpler line-based format for easier parsing by shell scripts if needed, or for Nuclei list input
if [ -f "$LOOT_DIR/web/kiterunner-$TARGET-$PORT.json" ]; then
cat "$LOOT_DIR/web/kiterunner-$TARGET-$PORT.json" | jq -r '.[] | .url' 2>/dev/null > "$LOOT_DIR/web/kiterunner_urls_http-$TARGET-$PORT.txt"
echo -e "$OKGREEN + -- --=[Kiterunner scan complete for http://$TARGET:$PORT. Output saved to $LOOT_DIR/web/kiterunner_urls_http-$TARGET-$PORT.txt $RESET"
else
echo -e "$OKRED + -- --=[Kiterunner did not produce an output file for http://$TARGET:$PORT $RESET"
fi
else
echo -e "${OKRED}Kiterunner (kr) still not found or installation failed. Skipping Kiterunner API discovery.${RESET}"
echo -e "${OKRED}Please ensure Kiterunner is installed and in your PATH or $HOME/go/bin.${RESET}"
fi
echo -e "${OKGREEN}====================================================================================${RESET}•x${OKGREEN}[`date +"%Y-%m-%d](%H:%M)"`${RESET}x•"
# Users can place custom API Nuclei templates in /root/nuclei-templates/custom/api/
NUCLEI_CUSTOM_API_TEMPLATES_DIR="/root/nuclei-templates/custom/api/"
if [ -d "$NUCLEI_CUSTOM_API_TEMPLATES_DIR" ] && [ -n "$(ls -A $NUCLEI_CUSTOM_API_TEMPLATES_DIR/*.yaml 2>/dev/null)" ]; then
if [ -f "$LOOT_DIR/web/kiterunner_urls_http-$TARGET-$PORT.txt" ] && [ -s "$LOOT_DIR/web/kiterunner_urls_http-$TARGET-$PORT.txt" ]; then
echo -e "${OKGREEN}====================================================================================${RESET}•x${OKGREEN}[`date +"%Y-%m-%d](%H:%M)"`${RESET}x•"
echo -e "$OKRED RUNNING NUCLEI SCAN ON DISCOVERED API ENDPOINTS (HTTP) $RESET"
echo -e "${OKGREEN}====================================================================================${RESET}•x${OKGREEN}[`date +"%Y-%m-%d](%H:%M)"`${RESET}x•"
echo -e "$OKORANGE + -- --=[Found custom API Nuclei templates and Kiterunner output. Starting API scan...$RESET"
API_NUCLEI_OUTPUT_DIR="$LOOT_DIR/web/nuclei_api_scans_http-$TARGET-$PORT/"
mkdir -p "$API_NUCLEI_OUTPUT_DIR" 2>/dev/null
while IFS= read -r api_url; do
# Sanitize URL to create a valid filename for Nuclei output
safe_filename=$(echo "$api_url" | sed 's|http[s]*://||g' | sed 's|/|_|g' | sed 's|[^a-zA-Z0-9_-]||g')
if [ -z "$safe_filename" ]; then
safe_filename="api_endpoint_$(date +%s%N)" # Fallback filename
fi
echo -e "$OKORANGE + -- --=[Scanning API endpoint: $api_url $RESET"
nuclei -silent -t "$NUCLEI_CUSTOM_API_TEMPLATES_DIR" -c "$THREADS" -target "$api_url" -o "$API_NUCLEI_OUTPUT_DIR/nuclei_api_scan_$(echo $TARGET)_$(echo $PORT)_${safe_filename}.txt" 2>/dev/null
done < "$LOOT_DIR/web/kiterunner_urls_http-$TARGET-$PORT.txt"
echo -e "$OKGREEN + -- --=[Nuclei API scan complete for http://$TARGET:$PORT. Output saved to $API_NUCLEI_OUTPUT_DIR $RESET"
else
echo -e "$OKORANGE + -- --=[Custom API Nuclei templates found, but no Kiterunner API endpoints discovered for http://$TARGET:$PORT. Skipping Nuclei API scan.$RESET"
fi
else
echo -e "$OKORANGE + -- --=[Custom API Nuclei template directory '$NUCLEI_CUSTOM_API_TEMPLATES_DIR' not found or is empty.$RESET"
echo -e "$OKORANGE + -- --=[To enable API scanning with Nuclei, create this directory and add your API-specific .yaml template files.$RESET"
fi
echo -e "${OKGREEN}====================================================================================${RESET}•x${OKGREEN}[`date +"%Y-%m-%d](%H:%M)"`${RESET}x•"
# TODO: Make SQLMap options configurable via sniper.conf (e.g., SQLMAP_ENABLE, SQLMAP_LEVEL, SQLMAP_RISK, SQLMAP_TAMPERS)
echo -e "${OKGREEN}====================================================================================${RESET}•x${OKGREEN}[`date +"%Y-%m-%d](%H:%M)"`${RESET}x•"
echo -e "$OKRED RUNNING SQLMAP SCAN $RESET"
echo -e "${OKGREEN}====================================================================================${RESET}•x${OKGREEN}[`date +"%Y-%m-%d](%H:%M)"`${RESET}x•"
if ! command -v sqlmap &> /dev/null; then
echo -e "${OKRED}SQLMap not found. Skipping SQLMap scan. Please install it first.${RESET}"
else
echo -e "$OKORANGE + -- --=[Searching for URLs with parameters for SQLMap...$RESET"
SQLMAP_TARGET_DIR_HOST=$(echo "$TARGET" | sed -e 's|^[^/]*//||' -e 's|/.*$||')
SQLMAP_OUTPUT_DIR="$LOOT_DIR/web/sqlmap/$SQLMAP_TARGET_DIR_HOST-$PORT"
mkdir -p "$SQLMAP_OUTPUT_DIR" 2> /dev/null
FOUND_URLS_FOR_SQLMAP=0
# Collect URLs from spider results
if [[ -f "$LOOT_DIR/web/spider-$TARGET.txt" ]]; then
grep '?' "$LOOT_DIR/web/spider-$TARGET.txt" | grep "http://" | sort -u > "$LOOT_DIR/web/sqlmap_urls_http_temp.txt"
else
touch "$LOOT_DIR/web/sqlmap_urls_http_temp.txt" # ensure file exists for cat
fi
# Consider URLs from dirsearch/gobuster if they exist and might have params (less common)
# For dirsearch (ensure it's the final processed file, not the raw output)
if [[ -f "$LOOT_DIR/web/dirsearch-$TARGET.txt" ]]; then
grep '?' "$LOOT_DIR/web/dirsearch-$TARGET.txt" | grep "http://" | sort -u >> "$LOOT_DIR/web/sqlmap_urls_http_temp.txt"
fi
# For gobuster (usually no params, but added for completeness if format changes)
if [[ -f "$LOOT_DIR/web/webbrute-$TARGET.txt" ]]; then
grep '?' "$LOOT_DIR/web/webbrute-$TARGET.txt" | grep "http://" | sort -u >> "$LOOT_DIR/web/sqlmap_urls_http_temp.txt"
fi
sort -u "$LOOT_DIR/web/sqlmap_urls_http_temp.txt" > "$LOOT_DIR/web/sqlmap_urls_http-$TARGET-$PORT.txt"
rm -f "$LOOT_DIR/web/sqlmap_urls_http_temp.txt"
if [[ -s "$LOOT_DIR/web/sqlmap_urls_http-$TARGET-$PORT.txt" ]]; then
FOUND_URLS_FOR_SQLMAP=1
echo -e "$OKORANGE + -- --=[Found $(wc -l < "$LOOT_DIR/web/sqlmap_urls_http-$TARGET-$PORT.txt") unique URLs with parameters. Starting SQLMap...$RESET"
while IFS= read -r url; do
echo -e "$OKORANGE + -- --=[Running SQLMap on: $url$RESET"
# Ensure URL is properly quoted for sqlmap command
sqlmap -u "$url" --batch --random-agent --level=2 --risk=1 --tamper=space2comment,randomcase --output-dir="$SQLMAP_OUTPUT_DIR" --hostname --threads=5 2>/dev/null
done < "$LOOT_DIR/web/sqlmap_urls_http-$TARGET-$PORT.txt"
echo -e "$OKGREEN + -- --=[SQLMap scan complete for http://$TARGET:$PORT. Output saved to $SQLMAP_OUTPUT_DIR $RESET"
fi
if [[ "$FOUND_URLS_FOR_SQLMAP" -eq 0 ]]; then
echo -e "$OKORANGE + -- --=[No URLs with parameters found for SQLMap in http://$TARGET:$PORT $RESET"
fi
fi
echo -e "${OKGREEN}====================================================================================${RESET}•x${OKGREEN}[`date +"%Y-%m-%d](%H:%M)"`${RESET}x•"
if [[ "$CLUSTERD" == "1" ]]; then
echo -e "${OKGREEN}====================================================================================${RESET}•x${OKGREEN}[`date +"%Y-%m-%d](%H:%M)"`${RESET}x•"
echo -e "$OKRED ENUMERATING WEB SOFTWARE $RESET"
@ -347,7 +469,25 @@ if [[ "$MODE" = "webporthttp" ]]; then
echo -e "${OKGREEN}====================================================================================${RESET}•x${OKGREEN}[`date +"%Y-%m-%d](%H:%M)"`${RESET}x•"
echo -e "$OKRED RUNNING NUCLEI SCAN $RESET"
echo -e "${OKGREEN}====================================================================================${RESET}•x${OKGREEN}[`date +"%Y-%m-%d](%H:%M)"`${RESET}x•"
nuclei -silent -t /root/nuclei-templates/ -c $THREADS -target http://$TARGET:${PORT} -o $LOOT_DIR/web/nuclei-http-${TARGET}-port${PORT}.txt
NUCLEI_GENERAL_TEMPLATES_DIR="/root/nuclei-templates/"
# Users can place custom SSTI Nuclei templates in $NUCLEI_USER_TEMPLATES_DIR/custom/ssti/
# For Sn1per, NUCLEI_USER_TEMPLATES_DIR is assumed to be /root/nuclei-templates/
NUCLEI_CUSTOM_SSTI_TEMPLATES_DIR="/root/nuclei-templates/custom/ssti/"
NUCLEI_TEMPLATES_TO_RUN="-t $NUCLEI_GENERAL_TEMPLATES_DIR"
if [ -d "$NUCLEI_CUSTOM_SSTI_TEMPLATES_DIR" ]; then
if [ -n "$(ls -A $NUCLEI_CUSTOM_SSTI_TEMPLATES_DIR/*.yaml 2>/dev/null)" ]; then
echo -e "$OKORANGE + -- --=[Found custom SSTI Nuclei templates. Adding to scan...$RESET"
NUCLEI_TEMPLATES_TO_RUN="$NUCLEI_TEMPLATES_TO_RUN -t $NUCLEI_CUSTOM_SSTI_TEMPLATES_DIR"
else
echo -e "$OKORANGE + -- --=[Custom SSTI template directory '$NUCLEI_CUSTOM_SSTI_TEMPLATES_DIR' is empty. Skipping custom SSTI scan.$RESET"
fi
else
echo -e "$OKORANGE + -- --=[Custom SSTI template directory '$NUCLEI_CUSTOM_SSTI_TEMPLATES_DIR' not found. Skipping custom SSTI scan.$RESET"
echo -e "$OKORANGE + -- --=[To enable, create this directory and add your SSTI .yaml template files.$RESET"
fi
nuclei -silent $NUCLEI_TEMPLATES_TO_RUN -c $THREADS -target http://$TARGET:${PORT} -o $LOOT_DIR/web/nuclei-http-${TARGET}-port${PORT}.txt
fi
SSL="false"
source $INSTALL_DIR/modes/web_autopwn.sh

View File

@ -290,6 +290,120 @@ if [[ "$MODE" = "webporthttps" ]]; then
sort -u $LOOT_DIR/web/webbrute-$TARGET-*.txt 2> /dev/null > $LOOT_DIR/web/webbrute-$TARGET.txt 2> /dev/null
fi
wget --connect-timeout=5 --read-timeout=10 --tries=1 https://$TARGET:${PORT}/robots.txt -O $LOOT_DIR/web/robots-$TARGET:${PORT}-https.txt 2> /dev/null
echo -e "${OKGREEN}====================================================================================${RESET}•x${OKGREEN}[`date +"%Y-%m-%d](%H:%M)"`${RESET}x•"
echo -e "$OKRED RUNNING KITERUNNER API DISCOVERY $RESET"
echo -e "${OKGREEN}====================================================================================${RESET}•x${OKGREEN}[`date +"%Y-%m-%d](%H:%M)"`${RESET}x•"
KITERUNNER_PATH=$(command -v kr)
if [ -z "$KITERUNNER_PATH" ]; then
echo -e "${OKRED}Kiterunner (kr) not found. Attempting to install...${RESET}"
if command -v go &> /dev/null; then
go install github.com/assetnote/kiterunner/cmd/kr@latest
KITERUNNER_PATH=$(command -v kr)
if [ -z "$KITERUNNER_PATH" ]; then
KITERUNNER_PATH="$HOME/go/bin/kr"
fi
else
echo -e "${OKRED}Go is not installed. Cannot install Kiterunner automatically. Please install Kiterunner manually.${RESET}"
fi
fi
if [ -f "$KITERUNNER_PATH" ]; then
echo -e "$OKORANGE + -- --=[Running Kiterunner on https://$TARGET:$PORT...$RESET"
"$KITERUNNER_PATH" scan https://$TARGET:$PORT -A=routes-large.kite --fail-status-codes 400,401,403,404,405,500 -x 10 --ignore-length 0 -o json > "$LOOT_DIR/web/kiterunner-$TARGET-$PORT-https.json" 2>/dev/null
if [ -f "$LOOT_DIR/web/kiterunner-$TARGET-$PORT-https.json" ]; then
cat "$LOOT_DIR/web/kiterunner-$TARGET-$PORT-https.json" | jq -r '.[] | .url' 2>/dev/null > "$LOOT_DIR/web/kiterunner_urls_https-$TARGET-$PORT.txt"
echo -e "$OKGREEN + -- --=[Kiterunner scan complete for https://$TARGET:$PORT. Output saved to $LOOT_DIR/web/kiterunner_urls_https-$TARGET-$PORT.txt $RESET"
else
echo -e "$OKRED + -- --=[Kiterunner did not produce an output file for https://$TARGET:$PORT $RESET"
fi
else
echo -e "${OKRED}Kiterunner (kr) still not found or installation failed. Skipping Kiterunner API discovery.${RESET}"
echo -e "${OKRED}Please ensure Kiterunner is installed and in your PATH or $HOME/go/bin.${RESET}"
fi
echo -e "${OKGREEN}====================================================================================${RESET}•x${OKGREEN}[`date +"%Y-%m-%d](%H:%M)"`${RESET}x•"
# Users can place custom API Nuclei templates in /root/nuclei-templates/custom/api/
NUCLEI_CUSTOM_API_TEMPLATES_DIR="/root/nuclei-templates/custom/api/"
if [ -d "$NUCLEI_CUSTOM_API_TEMPLATES_DIR" ] && [ -n "$(ls -A $NUCLEI_CUSTOM_API_TEMPLATES_DIR/*.yaml 2>/dev/null)" ]; then
if [ -f "$LOOT_DIR/web/kiterunner_urls_https-$TARGET-$PORT.txt" ] && [ -s "$LOOT_DIR/web/kiterunner_urls_https-$TARGET-$PORT.txt" ]; then
echo -e "${OKGREEN}====================================================================================${RESET}•x${OKGREEN}[`date +"%Y-%m-%d](%H:%M)"`${RESET}x•"
echo -e "$OKRED RUNNING NUCLEI SCAN ON DISCOVERED API ENDPOINTS (HTTPS) $RESET"
echo -e "${OKGREEN}====================================================================================${RESET}•x${OKGREEN}[`date +"%Y-%m-%d](%H:%M)"`${RESET}x•"
echo -e "$OKORANGE + -- --=[Found custom API Nuclei templates and Kiterunner output. Starting API scan...$RESET"
API_NUCLEI_OUTPUT_DIR_HTTPS="$LOOT_DIR/web/nuclei_api_scans_https-$TARGET-$PORT/"
mkdir -p "$API_NUCLEI_OUTPUT_DIR_HTTPS" 2>/dev/null
while IFS= read -r api_url; do
safe_filename=$(echo "$api_url" | sed 's|http[s]*://||g' | sed 's|/|_|g' | sed 's|[^a-zA-Z0-9_-]||g')
if [ -z "$safe_filename" ]; then
safe_filename="api_endpoint_$(date +%s%N)"
fi
echo -e "$OKORANGE + -- --=[Scanning API endpoint: $api_url $RESET"
nuclei -silent -t "$NUCLEI_CUSTOM_API_TEMPLATES_DIR" -c "$THREADS" -target "$api_url" -o "$API_NUCLEI_OUTPUT_DIR_HTTPS/nuclei_api_scan_$(echo $TARGET)_$(echo $PORT)_${safe_filename}.txt" 2>/dev/null
done < "$LOOT_DIR/web/kiterunner_urls_https-$TARGET-$PORT.txt"
echo -e "$OKGREEN + -- --=[Nuclei API scan complete for https://$TARGET:$PORT. Output saved to $API_NUCLEI_OUTPUT_DIR_HTTPS $RESET"
else
echo -e "$OKORANGE + -- --=[Custom API Nuclei templates found, but no Kiterunner API endpoints discovered for https://$TARGET:$PORT. Skipping Nuclei API scan.$RESET"
fi
else
echo -e "$OKORANGE + -- --=[Custom API Nuclei template directory '$NUCLEI_CUSTOM_API_TEMPLATES_DIR' not found or is empty.$RESET"
echo -e "$OKORANGE + -- --=[To enable API scanning with Nuclei, create this directory and add your API-specific .yaml template files.$RESET"
fi
echo -e "${OKGREEN}====================================================================================${RESET}•x${OKGREEN}[`date +"%Y-%m-%d](%H:%M)"`${RESET}x•"
# TODO: Make SQLMap options configurable via sniper.conf (e.g., SQLMAP_ENABLE, SQLMAP_LEVEL, SQLMAP_RISK, SQLMAP_TAMPERS)
echo -e "${OKGREEN}====================================================================================${RESET}•x${OKGREEN}[`date +"%Y-%m-%d](%H:%M)"`${RESET}x•"
echo -e "$OKRED RUNNING SQLMAP SCAN $RESET"
echo -e "${OKGREEN}====================================================================================${RESET}•x${OKGREEN}[`date +"%Y-%m-%d](%H:%M)"`${RESET}x•"
if ! command -v sqlmap &> /dev/null; then
echo -e "${OKRED}SQLMap not found. Skipping SQLMap scan. Please install it first.${RESET}"
else
echo -e "$OKORANGE + -- --=[Searching for URLs with parameters for SQLMap...$RESET"
SQLMAP_TARGET_DIR_HOST=$(echo "$TARGET" | sed -e 's|^[^/]*//||' -e 's|/.*$||')
SQLMAP_OUTPUT_DIR="$LOOT_DIR/web/sqlmap/$SQLMAP_TARGET_DIR_HOST-$PORT"
mkdir -p "$SQLMAP_OUTPUT_DIR" 2> /dev/null
FOUND_URLS_FOR_SQLMAP=0
# Collect URLs from spider results
if [[ -f "$LOOT_DIR/web/spider-$TARGET.txt" ]]; then
grep '?' "$LOOT_DIR/web/spider-$TARGET.txt" | grep "https://" | sort -u > "$LOOT_DIR/web/sqlmap_urls_https_temp.txt"
else
touch "$LOOT_DIR/web/sqlmap_urls_https_temp.txt" # ensure file exists for cat
fi
# Consider URLs from dirsearch/gobuster if they exist and might have params (less common)
# For dirsearch (ensure it's the final processed file, not the raw output)
if [[ -f "$LOOT_DIR/web/dirsearch-$TARGET.txt" ]]; then
grep '?' "$LOOT_DIR/web/dirsearch-$TARGET.txt" | grep "https://" | sort -u >> "$LOOT_DIR/web/sqlmap_urls_https_temp.txt"
fi
# For gobuster (usually no params, but added for completeness if format changes)
if [[ -f "$LOOT_DIR/web/webbrute-$TARGET.txt" ]]; then
grep '?' "$LOOT_DIR/web/webbrute-$TARGET.txt" | grep "https://" | sort -u >> "$LOOT_DIR/web/sqlmap_urls_https_temp.txt"
fi
sort -u "$LOOT_DIR/web/sqlmap_urls_https_temp.txt" > "$LOOT_DIR/web/sqlmap_urls_https-$TARGET-$PORT.txt"
rm -f "$LOOT_DIR/web/sqlmap_urls_https_temp.txt"
if [[ -s "$LOOT_DIR/web/sqlmap_urls_https-$TARGET-$PORT.txt" ]]; then
FOUND_URLS_FOR_SQLMAP=1
echo -e "$OKORANGE + -- --=[Found $(wc -l < "$LOOT_DIR/web/sqlmap_urls_https-$TARGET-$PORT.txt") unique URLs with parameters. Starting SQLMap...$RESET"
while IFS= read -r url; do
echo -e "$OKORANGE + -- --=[Running SQLMap on: $url$RESET"
# Ensure URL is properly quoted for sqlmap command
sqlmap -u "$url" --batch --random-agent --level=2 --risk=1 --tamper=space2comment,randomcase --output-dir="$SQLMAP_OUTPUT_DIR" --hostname --threads=5 2>/dev/null
done < "$LOOT_DIR/web/sqlmap_urls_https-$TARGET-$PORT.txt"
echo -e "$OKGREEN + -- --=[SQLMap scan complete for https://$TARGET:$PORT. Output saved to $SQLMAP_OUTPUT_DIR $RESET"
fi
if [[ "$FOUND_URLS_FOR_SQLMAP" -eq 0 ]]; then
echo -e "$OKORANGE + -- --=[No URLs with parameters found for SQLMap in https://$TARGET:$PORT $RESET"
fi
fi
echo -e "${OKGREEN}====================================================================================${RESET}•x${OKGREEN}[`date +"%Y-%m-%d](%H:%M)"`${RESET}x•"
if [[ "$CLUSTERD" == "1" ]]; then
echo -e "${OKGREEN}====================================================================================${RESET}•x${OKGREEN}[`date +"%Y-%m-%d](%H:%M)"`${RESET}x•"
echo -e "$OKRED ENUMERATING WEB SOFTWARE $RESET"
@ -356,7 +470,25 @@ if [[ "$MODE" = "webporthttps" ]]; then
echo -e "${OKGREEN}====================================================================================${RESET}•x${OKGREEN}[`date +"%Y-%m-%d](%H:%M)"`${RESET}x•"
echo -e "$OKRED RUNNING NUCLEI SCAN $RESET"
echo -e "${OKGREEN}====================================================================================${RESET}•x${OKGREEN}[`date +"%Y-%m-%d](%H:%M)"`${RESET}x•"
nuclei -silent -t /root/nuclei-templates/ -c $THREADS -target https://$TARGET:${PORT} -o $LOOT_DIR/web/nuclei-https-${TARGET}-port${PORT}.txt
NUCLEI_GENERAL_TEMPLATES_DIR="/root/nuclei-templates/"
# Users can place custom SSTI Nuclei templates in $NUCLEI_USER_TEMPLATES_DIR/custom/ssti/
# For Sn1per, NUCLEI_USER_TEMPLATES_DIR is assumed to be /root/nuclei-templates/
NUCLEI_CUSTOM_SSTI_TEMPLATES_DIR="/root/nuclei-templates/custom/ssti/"
NUCLEI_TEMPLATES_TO_RUN="-t $NUCLEI_GENERAL_TEMPLATES_DIR"
if [ -d "$NUCLEI_CUSTOM_SSTI_TEMPLATES_DIR" ]; then
if [ -n "$(ls -A $NUCLEI_CUSTOM_SSTI_TEMPLATES_DIR/*.yaml 2>/dev/null)" ]; then
echo -e "$OKORANGE + -- --=[Found custom SSTI Nuclei templates. Adding to scan...$RESET"
NUCLEI_TEMPLATES_TO_RUN="$NUCLEI_TEMPLATES_TO_RUN -t $NUCLEI_CUSTOM_SSTI_TEMPLATES_DIR"
else
echo -e "$OKORANGE + -- --=[Custom SSTI template directory '$NUCLEI_CUSTOM_SSTI_TEMPLATES_DIR' is empty. Skipping custom SSTI scan.$RESET"
fi
else
echo -e "$OKORANGE + -- --=[Custom SSTI template directory '$NUCLEI_CUSTOM_SSTI_TEMPLATES_DIR' not found. Skipping custom SSTI scan.$RESET"
echo -e "$OKORANGE + -- --=[To enable, create this directory and add your SSTI .yaml template files.$RESET"
fi
nuclei -silent $NUCLEI_TEMPLATES_TO_RUN -c $THREADS -target https://$TARGET:${PORT} -o $LOOT_DIR/web/nuclei-https-${TARGET}-port${PORT}.txt
fi
cd $INSTALL_DIR
SSL="true"