Transmission - RPC DNS Rebinding

EDB-ID:

43665




Platform:

Multiple

Date:

2018-01-11


The transmission bittorrent client uses a client/server architecture, the user interface is the client and a daemon runs in the background managing the downloading, seeding, etc.

Clients interact with the daemon using JSON RPC requests to a web server listening on port 9091. By default, the daemon will only accept requests from localhost.

A sample RPC session looks like this:

```
$ curl -H 'X-Transmission-Session-Id: foo'  -sI '{}' http://localhost:9091/transmission/rpc
HTTP/1.1 409 Conflict
Server: Transmission
X-Transmission-Session-Id: JL641xTn2h53UsN6bVa0kJjRBLA6oX1Ayl06AJwuhHvSgE6H
Date: Wed, 29 Nov 2017 21:37:41 GMT
```

```
$ curl -H 'X-Transmission-Session-Id: JL641xTn2h53UsN6bVa0kJjRBLA6oX1Ayl06AJwuhHvSgE6H'  -d '{"method":"session-set","arguments":{"download-dir":"/home/user"}}' -si http://localhost:9091/transmission/rpc
HTTP/1.1 200 OK
Server: Transmission
Content-Type: application/json; charset=UTF-8
Date: Wed, 29 Nov 2017 21:38:57 GMT
Content-Length: 36

{"arguments":{},"result":"success"}
```

As with all HTTP RPC schemes like this, any website can send requests to the daemon with XMLHttpRequest, but the theory is they will be ignored because requests must read and request a specific header, X-Transmission-Session-Id. Unfortunately, this design doesn't work because of an attack called "dns rebinding". Any website can simply create a dns name that they are authorized to communicate with, and then make it resolve to localhost.

The attack works like this:

1. A user visits http://attacker.com.
2. attacker.com has an <iframe> to attack.attacker.com, and have configured their DNS server to respond alternately with 127.0.0.1 and 123.123.123.123 (an address they control) with a very low TTL.
3. When the browser resolves to 123.123.123.123, they serve HTML that waits for the DNS entry to expire, then they XMLHttpRequest to attack.attacker.com and have permission to read and set headers.

You can test this attack like this, I have a domain I use for testing called rbndr.us, you can use this page to generate hostnames:

https://lock.cmpxchg8b.com/rebinder.html

Here I want to alternate between 127.0.0.1 and 199.241.29.227, so I use 7f000001.c7f11de3.rbndr.us:

```
$ host 7f000001.c7f11de3.rbndr.us
7f000001.c7f11de3.rbndr.us has address 127.0.0.1
$ host 7f000001.c7f11de3.rbndr.us
7f000001.c7f11de3.rbndr.us has address 199.241.29.227
$ host 7f000001.c7f11de3.rbndr.us
7f000001.c7f11de3.rbndr.us has address 127.0.0.1
```

Here you can see the resolution alternates between the two addresses I want (note that depending on caching it might take a while to switch, the TTL is set to minimum but some servers round up).

I just wait for the cached response to expire, and then POST commands to the server.

Exploitation is simple, you could set script-torrent-done-enabled and run any command, or set download-dir to /home/user/ and then upload a torrent for ".bashrc". 

Here is my (simple) demo:

http://lock.cmpxchg8b.com/Asoquu3e.html

See screenshots for how it's supposed to work, I've only tested it on fedora with `yum install transmission-daemon` and all default settings, but this should work on any platform that transmission supports.

EDB Note ~ https://bugs.chromium.org/p/project-zero/issues/detail?id=1447
EDB Note ~ https://github.com/transmission/transmission/pull/468
EDB Note ~ https://github.com/taviso/rbndr/tree/a189ffd9447ba78aa2702c5649d853b6fb612e3b

Download: https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/43665.zip