Skip to content

Instantly share code, notes, and snippets.

@Braunson
Created June 27, 2024 03:44
Show Gist options
  • Select an option

  • Save Braunson/380aa48dcbb9d6826a59184d00416aa1 to your computer and use it in GitHub Desktop.

Select an option

Save Braunson/380aa48dcbb9d6826a59184d00416aa1 to your computer and use it in GitHub Desktop.
Global scanner for suspicious PHP patterns (web shells, backdoors, etc.)
#!/usr/bin/bash
# Default base directory to scan
BASE_DIR="/var/www/html"
SHOW_NOTIFY=true
SHOW_WARNING=true
SHOW_DANGER=true
# Patterns of suspicious content categorized by severity
DANGER_PATTERNS=(
'<?php eval'
'.*=base64_decode'
'[A-Za-z0-9/+]{26,}'
'file_get_contents\(\$_POST\['
'file_get_contents\(\$_GET\['
'system\('
'shell_exec\('
'doced_46esab'
)
WARNING_PATTERNS=(
'gzinflate\('
'application/x-httpd-php'
'[^a-z]+shell'
'create_function\('
'.*=.*base64_decode'
'passthru'
'[^:_>]exec\('
)
NOTIFY_PATTERNS=(
'\eval\('
)
# Colors for highlighting
COLOR_RESET="\033[0m"
COLOR_FILENAME="\033[1;34m" # Bold blue
COLOR_LINENUM="\033[1;33m" # Bold yellow
COLOR_DANGER="\033[1;31m" # Bold red
COLOR_WARNING="\033[1;35m" # Bold magenta
COLOR_NOTIFY="\033[1;32m" # Bold green
# Function to scan files with given patterns
scan_files() {
local dir="$1"
local patterns=("${!2}")
local severity="$3"
local color="$4"
for pattern in "${patterns[@]}"; do
while IFS= read -r match; do
local filename=$(echo "$match" | awk -F: '{print $1}')
local linenum=$(echo "$match" | awk -F: '{print $2}')
local linecontent=$(echo "$match" | awk -F: '{$1=$2=""; print $0}')
echo -e "${color}[$severity] ${COLOR_FILENAME}${filename}${COLOR_RESET}:${COLOR_LINENUM}${linenum}${COLOR_RESET} ${linecontent}${COLOR_RESET}"
done < <(find "$dir" -type f -name "*.php" -exec grep -PnH -- "$pattern" {} +)
done
}
# Main scan function
scan_all_dirs() {
find "$BASE_DIR" -mindepth 1 -maxdepth 1 -type d | while read -r dir; do
echo -e "\nScanning directory: $dir"
if [ "$SHOW_DANGER" = true ]; then
scan_files "$dir" DANGER_PATTERNS[@] "DANGER" "$COLOR_DANGER"
fi
if [ "$SHOW_WARNING" = true ]; then
scan_files "$dir" WARNING_PATTERNS[@] "WARNING" "$COLOR_WARNING"
fi
if [ "$SHOW_NOTIFY" = true ]; then
scan_files "$dir" NOTIFY_PATTERNS[@] "NOTIFY" "$COLOR_NOTIFY"
fi
done
}
# Parse command-line arguments
for arg in "$@"; do
case $arg in
--path=*)
BASE_DIR="${arg#*=}"
shift
;;
--level=notify)
SHOW_NOTIFY=true
SHOW_WARNING=false
SHOW_DANGER=false
shift
;;
--level=warning)
SHOW_NOTIFY=true
SHOW_WARNING=true
SHOW_DANGER=false
shift
;;
--level=danger)
SHOW_NOTIFY=true
SHOW_WARNING=true
SHOW_DANGER=true
shift
;;
esac
done
# Run the scan
if [ -d "$BASE_DIR" ]; then
echo "Scanning base directory: $BASE_DIR"
if [ "$SHOW_DANGER" = true ]; then
scan_files "$BASE_DIR" DANGER_PATTERNS[@] "DANGER" "$COLOR_DANGER"
fi
if [ "$SHOW_WARNING" = true ]; then
scan_files "$BASE_DIR" WARNING_PATTERNS[@] "WARNING" "$COLOR_WARNING"
fi
if [ "$SHOW_NOTIFY" = true ]; then
scan_files "$BASE_DIR" NOTIFY_PATTERNS[@] "NOTIFY" "$COLOR_NOTIFY"
fi
else
scan_all_dirs
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment