Show Notes

83 - A Flickr CSRF, GitLab, & OMIGOD, Azure again?

When SmugMug bought Flickr from Yahoo they had to move the authentication system away from Yahoo’s authentication. A side-effect of this was that the account deletion process previously had used the Yahoo authentication code as the CSRF token so in the move the token was removed and not replaced with anything functionally equivalent.

I’d imagine this is because the developer would have seen the Yahoo Auth Token as well the Yahoo Auth Token to associate with Yahoo, and not as serving double purpose to prevent CSRF. Its a good reminder to not try and be clever with reusing pieces of information, because later development can pretty easily make mistakes like this.

There are four vulnerabilities in Azure’s Open Management Infrastructure (OMI), one allowing an unauthenticated attacker on the internet to execute code as root, the other three allowing local users of any level to execute code as root.

Unauthenticated Root RCE

This one does require that the OMI management port be exposed which mitigates the risk as for most but not all services with OMI. It is exposed by default on the Configuration Manager and System Center Operation Manager. And as far as vulnerabilities go, by simply not providing the Authorization header the authorization code is never run resulting in the authInfo fields uid and gid never being initalized to non-zero values. Zero being the uid/gid of the root user on most Linux systems.

Local Privileges Escalation (CVE-2021-38648)

Somewhat similar to the prior issue, however taking place in the omicli application which is used to communicate with the omiengine (which processes when necessary, and passes along requests to the omiserver running as root). By capturing a legitimate command execution request from omicli and removing the authentication part omiengine will pass along the authInfo to omiserver with zeroed values, which omiserver has no choice but to trust.

Local Privileges Escalation (CVE-2021-38645)

Unlike the prior two this one is actually a bit of a race condition and improperly trusting incoming messages from the users as server messages. First the authentication process is that omicli sends credentials to omiengine and omiengine sends them to omiserver to be validated. omiserver sends a response back.

An attacker can attempt to race that response, by sending a success message to omiengine before omiserver replies. This does require knowing the connection number for the omicli connection as it is included in the response from omiserver however according to the author this is usually a number less than 10, and I imagine it is an incremental number so it should be fairly predictable, and you can try multiple times.

A WAF bypass by confusing the Adobe Experience Manager Dispatcher (load balancer/waf/etc). Not a crazy idea but I don’t think we’ve covered any WAF bypass quite like this on the podcast before. The goal was to access /bin/querybuilder.json (I’m not sure if the .json was part of the endpoint or part of the confusing the Dispatcher) which would lead to access to the host filesystem. This was done by fuzzing the endpoint with various allowed features and parameters until the Dispatcher send the query through. Resuling in a final path along the lines of /bin/querybuilder.json.;%0aa.css?path=/etc&p.hits=full&p.limit=-1

For a GitLab bug, this one is nice and simple, stored XSS in the “default branch name” field. For a group you can setup what the group’s default branch name should be for any new repositories created. Then when creating a new repository GitLab provides code to be executed that will initalize your repository, this code will reflect the default branch name without any sanitization to whoever is viewing the page.

Its a bit surprising this XSS wasn’t discovered sooner because it is rather straight forward, though in fairness I do believe this feature is relatively new (maybe a year?) and it is a bit of an unseen location.

This is effectively a replay attack. Join a channel you can comment in, place a comment and capture that POST request. Switch to a channel you cannot comment in (but can join) and send that captured POST request. Its interesting that permissions were (apparently) not being checked at the time of sending on the server, also that since no modification of that captured request was necessary Mattermost must be tracking state like which channel is being viewed on the server side rather than including it with the request which makes me suspicious that there would be other state-tracking issues in the application for future bug hunters to find.

Three bugs relating to insecurely configured CloudKit containers, the big one being the accidental deletion of all Apple Shortcuts, but also the ability to delete records on Apple News, and modify data used on the iCrowd+ website.

CloudKit Primer - For the uninitiated, CloudKit is a data storage framework from apple to take an apps data and store it in the cloud. Application developers can create a container, containers have environments with three scopes (Private, Shared, and Public). Public being accessible by anyone with a public API token. Each scope has zones, the default zone being _defaultZone and finally, each zone has Records with Fields which have types and where the data is actually stored.

The author also found that there are atleast three different APIs that communicate with CloudKit in different ways. This becomes important as he switches between the API the application uses and one that is easier to communicate with at points.

iCrowd+ - The website was using the CloudKit API with the API-token provided in a javascript file. Using that same API token they were able to update the data it was fetching from CloudKit. For demonstrating replacing the version information displayed.

Apple News - Took a bit more effort to figure things out here because Apple News used the Protobuf API, ultimately using the API that Apple Notes uses (and changing the container) he was able to see that all News articles and stock information were in the public scope. While most of the methods were not allowed one method forceDelete was, granting the ability to delete any News article or Stock.

Apple Shortcuts - This one caused some drama as the testing became destructive deleting all shared Apple Shortcuts. Essentially shared shortcuts would be moved into the Public envrionment in the _defaultZone. The problem was that a public user could delete the defaultZone.

A rather non-intuitive bug where sending Content-Length: x would result in source disclosure on Apache.

The root of the bug is rather non-intuitive and has its origins in ignoring errors from filters. Naturally one of the HTTP Filters does see the invalid Content-Length header and makes a call to bail_out_on_error to write out the error message and bail. Rather than properly bailing however, the function that triggers the filter chain gets the AP_FILTER_ERROR return code and has a switch statement on it. Which just happens to completely ignore the AP_FILTER_ERROR case allowing the bad request to continue being processed.

Ultimately invoking a “txt/HTML” generator on the PHP file resulting in the PHP’s source code being written as output rather than executing the PHP interpreter. Its not entirely clear from the write-up why “txt/HTML” but my educated guess would be that a later filter in the chain that would normally change the generator and type simply wasn’t executed due to the early error return.

While this bug was silently patched, the security implications were not recognized and so the vulnerability has not (at the time of the presentation) been back ported.