From 0031036f3d72bd83306c1cdc1c5e94f75b3040a9 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Sun, 25 May 2025 13:49:10 +0000 Subject: [PATCH] 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. --- modes/javascript-analysis.sh | 93 +++++++++++++++++++++++ modes/webporthttp.sh | 142 ++++++++++++++++++++++++++++++++++- modes/webporthttps.sh | 134 ++++++++++++++++++++++++++++++++- 3 files changed, 367 insertions(+), 2 deletions(-) diff --git a/modes/javascript-analysis.sh b/modes/javascript-analysis.sh index e9db49e5..02cc4bb0 100644 --- a/modes/javascript-analysis.sh +++ b/modes/javascript-analysis.sh @@ -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" diff --git a/modes/webporthttp.sh b/modes/webporthttp.sh index 8ed19fef..6ac693e5 100644 --- a/modes/webporthttp.sh +++ b/modes/webporthttp.sh @@ -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 diff --git a/modes/webporthttps.sh b/modes/webporthttps.sh index 49d6a36c..8bffbca4 100644 --- a/modes/webporthttps.sh +++ b/modes/webporthttps.sh @@ -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"