Skip to content

Commit

Permalink
Merge pull request #909 from blacklanternsecurity/ajaxpro
Browse files Browse the repository at this point in the history
New Module: Ajaxpro
  • Loading branch information
liquidsec authored Dec 19, 2023
2 parents 8137736 + c8eb6e0 commit f3e8507
Show file tree
Hide file tree
Showing 2 changed files with 107 additions and 0 deletions.
51 changes: 51 additions & 0 deletions bbot/modules/ajaxpro.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import re
from bbot.modules.base import BaseModule


class ajaxpro(BaseModule):
"""
Reference: https://mogwailabs.de/en/blog/2022/01/vulnerability-spotlight-rce-in-ajax.net-professional/
"""

ajaxpro_regex = re.compile(r'<script.+src="([\/a-zA-Z0-9\._]+,[a-zA-Z0-9\._]+\.ashx)"')
watched_events = ["HTTP_RESPONSE", "URL"]
produced_events = ["VULNERABILITY", "FINDING"]
flags = ["active", "safe", "web-thorough"]
meta = {"description": "Check for potentially vulnerable Ajaxpro instances"}

async def handle_event(self, event):
if event.type == "URL":
if "dir" not in event.tags:
return False
probe_url = f"{event.data}ajaxpro/whatever.ashx"
probe = await self.helpers.request(probe_url)
if probe:
if probe.status_code == 200:
probe_confirm = await self.helpers.request(f"{event.data}a/whatever.ashx")
if probe_confirm:
if probe_confirm.status_code != 200:
self.emit_event(
{
"host": str(event.host),
"url": event.data,
"description": f"Ajaxpro Detected (Version Unconfirmed) Trigger: [{probe_url}]",
},
"FINDING",
event,
)

elif event.type == "HTTP_RESPONSE":
resp_body = event.data.get("body", None)
if resp_body:
ajaxpro_regex_result = self.ajaxpro_regex.search(resp_body)
if ajaxpro_regex_result:
ajax_pro_path = ajaxpro_regex_result.group(0)
self.emit_event(
{
"host": str(event.host),
"url": event.data["url"],
"description": f"Ajaxpro Detected (Version Unconfirmed) Trigger: [{ajax_pro_path}]",
},
"FINDING",
event,
)
56 changes: 56 additions & 0 deletions bbot/test/test_step_2/module_tests/test_module_ajaxpro.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
from .base import ModuleTestBase


class TestAjaxpro(ModuleTestBase):
targets = ["http://127.0.0.1:8888"]
modules_overrides = ["httpx", "ajaxpro"]

http_response_data = """
<script src="ajax/AMBusinessFacades.AjaxUtils,AMBusinessFacades.ashx" type="text/javascript"></script><script type='text/javascript'>$(document).ready(function(){if (!(top.hasTouchScreen || (top.home && top.home.hasTouchScreen))){$('#ctl01_userid').trigger('focus').trigger('select');}});</script>
<script type="text/javascript">
if(typeof AjaxPro != "undefined") AjaxPro.noUtcTime = true;
</script>
<script type="text/javascript" src="/AcmeTest/ajax/AMBusinessFacades.NotificationsAjax,AMBusinessFacades.ashx"></script>
<script type="text/javascript" src="/AcmeTest/ajax/AMBusinessFacades.ReportingAjax,AMBusinessFacades.ashx"></script>
<script type="text/javascript" src="/AcmeTest/ajax/AMBusinessFacades.UsersAjax,AMBusinessFacades.ashx"></script>
<script type="text/javascript" src="/AcmeTest/ajax/FAServerControls.FAPage,FAServerControls.ashx"></script>
"""

async def setup_before_prep(self, module_test):
# Simulate ajaxpro URL probe positive
expect_args = {"method": "GET", "uri": "/ajaxpro/whatever.ashx"}
respond_args = {"status": 200}
module_test.set_expect_requests(expect_args=expect_args, respond_args=respond_args)

# Simulate ajaxpro URL probe negative
expect_args = {"method": "GET", "uri": "/a/whatever.ashx"}
respond_args = {"status": 404}
module_test.set_expect_requests(expect_args=expect_args, respond_args=respond_args)

# Simulate HTTP_RESPONSE detection
expect_args = {"method": "GET", "uri": "/"}
respond_args = {"response_data": self.http_response_data}
module_test.set_expect_requests(expect_args=expect_args, respond_args=respond_args)

def check(self, module_test, events):
ajaxpro_url_detection = False
ajaxpro_httpresponse_detection = False

for e in events:
if (
e.type == "FINDING"
and "Ajaxpro Detected (Version Unconfirmed) Trigger: [http://127.0.0.1:8888/ajaxpro/whatever.ashx]"
in e.data["description"]
):
ajaxpro_url_detection = True
continue
if (
e.type == "FINDING"
and 'Ajaxpro Detected (Version Unconfirmed) Trigger: [<script src="ajax/AMBusinessFacades.AjaxUtils,AMBusinessFacades.ashx"]'
):
ajaxpro_httpresponse_detection = True
continue

assert ajaxpro_url_detection, "Ajaxpro URL probe detection failed"
assert ajaxpro_httpresponse_detection, "Ajaxpro HTTP_RESPONSE detection failed"

0 comments on commit f3e8507

Please sign in to comment.