openkylin-exploit-db/cve/java-spring/2022/CVE-2022-22965/CVE-2022-22965.nse

150 lines
5.7 KiB
Lua

description = [[
Spring Framework 5.2.x / 5.3.x CVE-2022-22965 Remote Code Execution Vulnerability
This script looks the existence of CVE-2022-22965 Spring Framework 5.2.x / 5.3.x RCE
uses a payload "/?class.module.classLoader.definedPackages%5B0%5D=0" through a GET request
looking (400) code as response (NON INTRUSIVE)
Inspired by:
@Twitter thread
https://twitter.com/RandoriAttack/status/1509298490106593283
@ZAP Scan Rule
https://www.zaproxy.org/blog/2022-04-04-spring4shell-detection-with-zap/
Manual inspection:
# curl -i -s -k -X $'GET'
-H $'Host: <target>'
-H $'User-Agent: alex666'
-H $'Connection: close'
$'https://<target>/path/foo/?class.module.classLoader.URLs%5B0%5D=0' | grep -i 400
# curl -i -s -k -X $'GET'
-H $'Host: <target>'
-H $'User-Agent: alex666'
-H $'Connection: close'
$'https://<target>/path/foo/?class.module.classLoader.definedPackages%5B0%5D=0' | grep -i 400
References:
https://github.com/alt3kx/CVE-2022-22965
https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-22965
https://www.lunasec.io/docs/blog/spring-rce-vulnerabilities
https://github.com/BobTheShoplifter/Spring4Shell-POC
https://spring.io/blog/2022/03/31/spring-framework-rce-early-announcement
https://www.rapid7.com/blog/post/2022/03/30/spring4shell-zero-day-vulnerability-in-spring-framework
]]
---
-- @usage
-- nmap -p <port> --script=./CVE-2022-22965.nse [--script-args 'CVE-2022-22965.path=<PATH>,CVE-2022-22965.method=<HTTP METHOD>'] <target>
-- @args CVE-2022-22965.path URI path to test; must be a valid path that accepts one or more parameters using data binding (default: <code>/</code>).
-- @args CVE-2022-22965.method HTTP request method to use (default: <code>GET</code>).
--
-- @examples:
-- nmap -p443,8080 --script=./CVE-2022-22965.nse <target> -Pn
-- nmap -p443,8080 --script=./CVE-2022-22965.nse <target> --script-args 'CVE-2022-22965.path="/path/to/test"' -Pn
-- nmap -p443,8080 --script=./CVE-2022-22965.nse <target> --script-args 'CVE-2022-22965.path="/path/to/test",CVE-2022-22965.method=POST' -Pn
-- nmap -p443,8080 --script=./CVE-2022-22965.nse <target> --script-args=CVE-2022-22965.path="/path/foo/download/" -Pn --script-trace | more
-- nmap -p443,8080 --script=./CVE-2022-22965.nse --script-args=CVE-2022-22965.path="/examples/" -Pn -iL targets.txt
--
-- @output
-- PORT STATE SERVICE
-- 443/tcp open https
-- | CVE-2022-22965:
-- | VULNERABLE:
-- | Spring Framework 5.2.x 5.3.x RCE
-- | State: VULNERABLE (Exploitable)
-- | IDs: CVE:CVE-2022-22965
-- | Within Spring Core, A Spring MVC or Spring WebFlux application running on JDK 9+ may be vulnerable
-- | to remote code execution (RCE) via data binding.
-- | Disclosure date: 2022-03-31
-- | References:
-- |_ https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-22965
author = "Alex Hernandez aka alt3kx <alt3kx@protonmail.com>"
license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
categories = {"vuln", "exploit"}
local shortport = require "shortport"
local http = require "http"
local stdnse = require "stdnse"
local string = require "string"
local vulns = require "vulns"
portrule = shortport.http
local S4S1 = "Tomcat"
local S4S2 = "springframework"
local S4S3 = "Tomcat"
local S4S4 = "Tomcat"
--Payloads:
--GET checker path2 = "/?class.module.classLoader.DefaultAssertionStatus=nosense"
--GET checker path1 = "/?class.module.classLoader.URLs%5B0%5D=0"
local S4S_PAYLOAD = "class.module.classLoader.definedPackages%5B0%5D=0"
action = function(host, port)
local vuln = {
title = "Spring Framework 5.2.x 5.3.x RCE",
state = vulns.STATE.NOT_VULN,
IDS = { CVE = 'CVE-2022-22965' },
description = [[
Within Spring Core, A Spring MVC or Spring WebFlux application running on JDK 9+ may be vulnerable
to remote code execution (RCE) via data binding.]],
references = {
'https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-22965'
},
dates = {
disclosure = {year = '2022', month = '03', day = '31'},
},
}
local report = vulns.Report:new(SCRIPT_NAME, host, port)
local method = string.upper(stdnse.get_script_args("CVE-2022-22965.method") or "GET")
local path = stdnse.get_script_args("CVE-2022-22965.path") or "/"
local options = {header={["Content-Type"]="application/x-www-form-urlencoded"}}
if method == "GET" then
path = path .. "?" .. S4S_PAYLOAD
else
options["content"] = S4S_PAYLOAD
end
local response = http.generic_request(host, port, method, path, options)
if response.status and response.body then
if response.status == 400 and string.find(response.body, S4S1) ~= nil then
stdnse.debug2("Apache Tomcat Spring Framework 5.2.x / 5.3.x returned 400")
vuln.state = vulns.STATE.EXPLOIT
end
--500 Internal Server Error , Spring Framework 5.2.x / 5.3.x Exceptions
if response.status == 500 and string.find(response.body, S4S2) ~= nil then
stdnse.debug2("Apache Tomcat Spring Framework 5.2.x / 5.3.x returned 500")
vuln.state = vulns.STATE.EXPLOIT
end
if response.status == 200 and string.find(response.body, S4S3) ~= nil then
stdnse.debug2("Apache Tomcat Spring Framework 5.2.x / 5.3.x returned 200")
vuln.state = vulns.STATE.NOT_VULN
end
if response.status == 404 and string.find(response.body, S4S4) ~= nil then
stdnse.debug2("Apache Tomcat Spring Framework 5.2.x / 5.3.x returned 404")
vuln.state = vulns.STATE.NOT_VULN
end
else
stdnse.debug2("Apache Tomcat Spring Framework 5.2.x / 5.3.x returned unknow response.")
vuln.state = vulns.STATE.UNKNOWN
end
return report:make_output (vuln)
end