Proxy managed by enterprise? No problem! Abusing PAC and the registry to get burpin’

As penetration testers, we sometimes have to perform web application security assessments from our customer’s computers instead of our beloved machines. When this happens, we can face different challenges in order to have a working test setup. We will most probably have very limited permissions, which can block us from installing applications or modifying proxy settings. We recently encountered such a situation during an engagement and we wanted to share our solution.

This blog post shows how you can still proxy a target application through Burp even if the proxy settings are managed by the enterprise.

That’s easy! We just use Burp’s internal browser!

You are absolutely correct! Burp introduced an internal browser in 2020 which is automatically preconfigured with the correct proxy settings. Problem solved! Install Burp, launch the browser and you’re good to go.

However, what if that’s not possible? When you receive a customer’s computer, you can be pretty sure you won’t be able to install Burp through the installer since you’re typically not allowed to run executables or to install applications. Luckily, Burp has a standalone version as well, which only requires Java. So a quick Java check later, and we’re good to go, right?

Checking Java Version

Well, no. In this case, Java is installed, but the Java version is too old to support a recent version of Burp with a built-in browser. We can still use an older version of Burp, but we will have to find an alternative solution to our proxy settings problem. There are various ways to configure a proxy, so let’s take a look.

Common proxy settings

Several possibilities exist to proxy traffic through Burp. Normally, you could simply modify the system’s proxy settings and these settings would automatically be picked up by Edge and Chrome. However, in our setup, this is unfortunately not possible because the settings are managed by the enterprise:

System Proxy Settings

The proxy settings are set in the Automatic proxy setup section, by using a PAC setup script. As the proxy settings are managed by the organization, we cannot edit them, and without admin privileges we cannot modify the local group policy to grant us access to the system proxy settings.

An alternative solution is to use Firefox’s built-in proxy settings. Firefox actually has their own settings panel where you can choose to either use system settings or configure a proxy yourself. Firefox was installed on the system, so we thought the end was in sight:

Greyed-Out Firefox Proxy Settings

Weirdly enough, Firefox doesn’t allow us to modify the proxy settings either. It appears it is possible to limit access to some Firefox settings by making use of a lock preferences file, located in the installation folder for Firefox:

Firefox Local Settings Location
local-settings.js Content
Snapshot of mozilla.cfg

As these files are all located in the installation folder of Firefox, in Program Files, admin privileges are required to edit these settings. Again, we ended up blocked and unable to change any of the proxy settings, either system wide or in Firefox itself.

Un-PAC-ing the mystery behind system proxy settings

As these two easy solutions were unsuccessful, let’s analyze more in depth how the actual system proxy settings work and what could possibly go wrong with it.

In the system proxy settings, we had seen it was using Automatic proxy setup, delivered via a PAC file through HTTP. What if we manage to deliver a modified PAC file, one with our own proxy settings?
First things first, let’s download the original PAC file and take a look. The PAC file is a simple text file and we can change the default proxy settings to our Burp IP and port:

Altered PAC File

We now need to make the system download our PAC file instead of the one set by the organization.

The URL for the PAC file is shown in the system proxy settings, but where is this URL actually stored? Most probably in a registry key! By searching for the URL of the PAC file inside the registry editor, we can see some hits. One of the hits was found in the Internet Settings, which seems like a very good candidate. And even better, these keys can be edited without admin rights! This means we can modify it to anything we want, so why not setting it to something like file://C:\temp\BR-Proxy.pac?

Some online research showed it would not be handled by the Internet Settings. It appears Internet Settings are using WinHttp proxy service to retrieve the file stored at the AutoConfigURL, which means protocols such as ftp:// or file:// are not supported. Therefore, only http:// or https:// protocols can be used.

So let’s set the variable to a local address, such as http꞉//127.0.0.1:8080/BE-Proxy.pac.

PAC File URL Registry Key

As a result of this modification, we can now see the system proxy has a script address set to the one we have set in the registry key:

Altered System Proxy Settings

We have changed the URL of the automatic setup to a URL we can potentially control. We now need a local server that will deliver our custom PAC over HTTP. As Java is installed on the system, a quick online search gives us a simple HTTP Java WebServer (https://github.com/pciporin25/Simple-HTTP-Server/blob/master/WebServer.java) to serve our PAC file on http꞉//127.0.0.1:8080:

import java.net.*;
import java.io.*;
import java.nio.file.*;
import java.nio.charset.*;

public class WebServer {
public static void main (String args[])
{
        try{
                int serverPort = 8080;
                ServerSocket listenSocket = new ServerSocket(serverPort);

                System.out.println("Server listening on port 6880...");

                while(true) {
                        Socket clientSocket = listenSocket.accept();
                        InputStream input = clientSocket.getInputStream();
                        BufferedReader br = new BufferedReader(new InputStreamReader(input));

                        String request = br.readLine();
                        String[] reqArray = request.split(" "); // ['GET', 'index.html', 'HTTP/1.1']

                        String filePath = reqArray[1].substring(1); // index.html (or other path): remove the '/'
                        //System.out.println("request[0]: " + request[0] + " request[1]: " + request[1] + " nextline: " + nextLine);
                        if (filePath!=null)
                                loadPage(clientSocket, filePath, br);
                        //break;
                }
        }
        catch(IOException e) {
                System.out.println("Listen :"+e.getMessage());
        }
}

public static void loadPage(Socket clientSocket, String filePath, BufferedReader br) {
        try {

                PrintWriter output = new PrintWriter(clientSocket.getOutputStream());
                File file = new File(filePath);
                if (!file.exists()) {
                    output.write("HTTP/1.1 404 Not Found\r\n" + "Content-Type: text/html" + "\r\n\r\n");
                        System.out.println("File does not exist.  Client requesting file at : " + filePath);
                        output.close();
                }

                else {
                        output.write("HTTP/1.1 200 OK\r\n" + "Content-Type: text/html" + "\r\n\r\n");
                        byte[] fileBytes = Files.readAllBytes(Paths.get(filePath));
                        String fileString = new String(fileBytes, StandardCharsets.UTF_8);
                        output.write(fileString);

                        System.out.println("Finished writing content to output");
                        //brFile.close();
                        //br.close();
                        output.close();

                }


        }
        catch(IOException e) {
                System.out.println("Connection: " + e.getMessage());
        }
}
}

With this setup, the system will now retrieve the PAC file to check which system proxy to apply, and it will then proxy the traffic through our Burp.

As a last step for the setup to fully work, we need to put an upstream proxy server in Burp which will forward the traffic to the initial default proxy defined in the original PAC file.

The traffic will now pass through Burp, up to the real enterprise proxy, and we finally can proceed with the actual assessment!

Conclusion

The main enabler allowing us to set up the proxy as we wanted was the registry key handling the PAC file URL being writable without elevated privileges.

To forbid such setup, we recommend ensuring the script address registry key cannot be edited by low-privilege accounts, as it allows to bypass the enterprise proxy settings. Moreover, we recommend delivering the PAC file over HTTPS instead of HTTP, as the latter could be exploited in a Man-in-the-Middle attack, to alter the content of the PAC file without having to change the script address registry key value.

Thomas Grimée
Thomas Grimée

Thomas Grimée is a Senior Security Consultant in the NVISO Software and Security Assessment team. He is managing different penetration testing projects for various customers, and mainly performs web application and red teaming engagements.

Leave a Reply