Skip to content

Instantly share code, notes, and snippets.

@ndsamuelson
Last active May 1, 2024 07:04
Show Gist options
  • Save ndsamuelson/3c83f38ae470c82ff87d2653af11716b to your computer and use it in GitHub Desktop.
Save ndsamuelson/3c83f38ae470c82ff87d2653af11716b to your computer and use it in GitHub Desktop.
Tor Authentication via Control Port

Authentication to Tor via ControlPort

I'm using cookie authentication


Cookie authentication simply means that your credential is the content of a file in Tor's DataDirectory. You can learn information about Tor's method of authentication (including the cookie file's location) by calling PROTOCOLINFO.

  % cat ~/.tor/torrc
  ControlPort 9051
  CookieAuthentication 1

  % telnet localhost 9051
  Trying 127.0.0.1...
  Connected to localhost.
  Escape character is '^]'.
  PROTOCOLINFO
  250-PROTOCOLINFO 1
  250-AUTH METHODS=COOKIE,SAFECOOKIE COOKIEFILE="/home/atagar/.tor/control_auth_cookie"
  250-VERSION Tor="0.2.5.1-alpha-dev"
  250 OK

Cookie authentication has two flavors: COOKIE and SAFECOOKIE. First we will demonstrate COOKIE authentication which is quite a bit simpler, though Stem supports both transparently.

To get the credential for your AUTHENTICATE command we will use hexdump.

  % hexdump -e '32/1 "%02x""\n"' /home/atagar/.tor/control_auth_cookie
  be9c9e18364e33d5eb8ba820d456aa2bc03444c0420f089ba4569b6aeecc6254

  % telnet localhost 9051
  Trying 127.0.0.1...
  Connected to localhost.
  Escape character is '^]'.
  AUTHENTICATE be9c9e18364e33d5eb8ba820d456aa2bc03444c0420f089ba4569b6aeecc6254
  250 OK
  GETINFO version
  250-version=0.2.5.1-alpha-dev (git-245ecfff36c0cecc)
  250 OK
  QUIT
  250 closing connection
  Connection closed by foreign host.

I'm using safe cookie authentication


Password and cookie authentication both disclose your credential. This makes you vulnerable to replay attacks if you accidently connect to a malicious port or have a man-in-the-middle. SAFECOOKIE authentication avoids this through a two way handshake, but authenticating by hand requires some extra work.

This demonstration will use xxd for hex conversion and openssl for crypto. First we need to call AUTHCHALLENGE with a random one-time token...

  % CookieString="$(xxd -u -p -c32 < /home/atagar/.tor/control_auth_cookie)"
  % ClientNonce="$(xxd -u -p -l32 -c32 < /dev/urandom)"
  % printf '%s\n' "${ClientNonce}"
  9C653314CC4CC2C695999CE84EB1B0045E3D59B6AFFE615D624DB4870DD7041E

  % telnet localhost 9051
  Trying 127.0.0.1...
  Connected to localhost.
  Escape character is '^]'.
  AUTHCHALLENGE SAFECOOKIE 9C653314CC4CC2C695999CE84EB1B0045E3D59B6AFFE615D624DB4870DD7041E
  250 AUTHCHALLENGE SERVERHASH=16274D83FC2240DF9D50D74009D9AE107B77EA317F0034D3638C7942F350D1F9
                    SERVERNONCE=1C2E73C41FA8537FDD3A59C2ECBE26DFC85E0A05389373AD8C130C0F5795A036

In another terminal prompt next combine the server challenge with our cookie
content. This token will prove to Tor that we have our authentication cookie
without divulging its content...

```python
  % ServerNonce="1C2E73C41FA8537FDD3A59C2ECBE26DFC85E0A05389373AD8C130C0F5795A036"
  % printf '%s%s%s\n' "${CookieString}" "${ClientNonce}" "${ServerNonce}" | xxd -r -p \
  > | openssl dgst -sha256 -binary -hmac "Tor safe cookie authentication controller-to-server hash" \
  > | xxd -p -u -c32
  A733E09A65E2A6030BF6710D800370FC3AD28E1D2545E1692D160545D93CEE68

We can now authenticate using this token.

  AUTHENTICATE A733E09A65E2A6030BF6710D800370FC3AD28E1D2545E1692D160545D93CEE68
  250 OK
  GETINFO version
  250-version=0.2.5.1-alpha-dev (git-245ecfff36c0cecc)
  250 OK
  QUIT
  250 closing connection
  Connection closed by foreign host.

I'm using password authentication


Tor's other method of authentication is a credential you know. To use it ask Tor to hash your password, then use that in your torrc...

  % tor --hash-password "my_password"
  16:E600ADC1B52C80BB6022A0E999A7734571A451EB6AE50FED489B72E3DF

Authenticating with this simply involves giving Tor the credential...

  % cat ~/.tor/torrc
  ControlPort 9051
  HashedControlPassword 16:E600ADC1B52C80BB6022A0E999A7734571A451EB6AE50FED489B72E3DF

  % telnet localhost 9051
  Trying 127.0.0.1...
  Connected to localhost.
  Escape character is '^]'.
  AUTHENTICATE "my_password"
  250 OK
  GETINFO version
  250-version=0.2.5.1-alpha-dev (git-245ecfff36c0cecc)
  250 OK
  QUIT
  250 closing connection
  Connection closed by foreign host.
@rbroggi
Copy link

rbroggi commented Jun 27, 2023

thx @ndsamuelson for this gist, sometimes we land in a page searching for information about something and learning something even more interesting, that was my case: I did not realise before that we could connect and issue commands to tor using telnet. That is awesome! ❤️

@dehghani-mehdi
Copy link

dehghani-mehdi commented May 1, 2024

@ndsamuelson How can I do the same as hexdump -e '32/1 "%02x""\n"' in Windows?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment