0

I made a script in python, which allows me to change the Public IP using stem. The script had no problem, but the thing is that the script needs the hashed password in /etc/tor/torrc to authenticate. I want all the others to use my script, but they would need to put their hashed password in the script manually. So, is there a python script that can get the hashed password automatically?

(Please no tor --hash-password my_password, since the password also has to be stored in torrc.)

Helps will be appreciated a lot, thank you.

  • No one? : ( I am desperate..... –  Jan 02 '18 at 14:18
  • Use CookieAuthentication instead? The hashed password is a one-way hash so there's no way to "get" the hashed password without knowing it or breaking it. – drew010 Jan 03 '18 at 20:19
  • Then is there a way to get it working without the hashed password? What is it? –  Jan 04 '18 at 00:20
  • Or is there a way that a script goes in the torrc file and reads the hashed password? I think that is possible, but I don't know how. –  Jan 04 '18 at 00:21

2 Answers2

1

In connection with the fact that in Python 2 os.random return a str, and in Python 3 os.random return a bytes, the code needs to be changed a little

import os, hashlib, binascii, codecs

def getTorPassHashv03(sectretPassword='passw0rd'):
    #python v3  working
    # static 'count' value later referenced as "c"
    indicator = chr(96)
    # generate salt and append indicator value so that it
    salt = "%s%s" % (os.urandom(8), indicator)  #this will be working
    c = ord(indicator)
    #salt = "%s%s" % (codecs.encode(os.urandom(4), 'hex').decode(), indicator) #this will be working
    #c = ord(salt[8])
    #salt = "%s%s" % (codecs.encode(os.urandom(8), 'hex').decode(), indicator) #this will be working
    #c = ord(salt[16])  
    # generate an even number that can be divided in subsequent sections. (Thanks Roman)
    EXPBIAS = 6
    count = (16+(c&15)) << ((c>>4) + EXPBIAS)
    d = hashlib.sha1()
    # take the salt and append the password
    tmp = salt[:8] + sectretPassword
    # hash the salty password
    slen = len(tmp)
    while count:
        if count > slen:
            d.update(tmp.encode('utf-8'))
            count -= slen
        else:
            d.update(tmp[:count].encode('utf-8'))
            count = 0
    hashed = d.digest()
    saltRes = binascii.b2a_hex(salt[:8].encode('utf-8')).upper().decode()
    indicatorRes = binascii.b2a_hex(indicator.encode('utf-8')).upper().decode()
    torhashRes = binascii.b2a_hex(hashed).upper().decode()
    hashedControlPassword = '16:' + str(saltRes) + str(indicatorRes) + str(torhashRes)
    return hashedControlPassword

Also, obtaining a hash by the method of generating a Tor binary (on windows), code need to change it like this

import subprocess, re

def genTorPassHashV00(sectretPassword='passw0rd'):
    """ Launches a subprocess of tor to generate a hashed <password>"""
    print('Generating a hashed password')
    torP = subprocess.Popen(['tor.exe', '--hash-password', sectretPassword], stdout=subprocess.PIPE)
    out, err = torP.communicate()
    resultString = str(out)
    match = re.search(r'(\\r\\n16:.{58})', resultString)
    hashedControlPassword = re.sub(r'(\\r\\n)', "", match.group(0))
    return hashedControlPassword
0

Authenticating a Controller with a Tor subprocess using Stem

I made this script that uses tor --hash-password and stem.process.launch_tor_with_config to use the hashed password.

from stem.process import launch_tor_with_config
from stem.control import Controller

from subprocess import Popen, PIPE
import logging

def genTorPassHash(password):
    """ Launches a subprocess of tor to generate a hashed <password> """
    logging.info("Generating a hashed password")
    torP = Popen(
            ['tor', '--hush', '--hash-password', str(password)],
            stdout=PIPE,
            bufsize=1
            )
    try:
        with torP.stdout:
            for line in iter(torP.stdout.readline, b''):
                line = line.strip('\n')
                if "16:" not in line:
                    logging.debug(line)
                else:
                    passhash = line
        torP.wait()
        logging.info("Got hashed password")
        return passhash
    except Exception:
        raise

def startTor(controlPass, config):
    """
    Starts tor subprocess using a custom <config>,
    returns Popen and connected controller.
    """
    try:
        # start tor
        logging.info("Starting tor subprocess")
        process = launch_tor_with_config(
                config=config, 
                tor_cmd='tor', 
                completion_percent=50, 
                timeout=60, 
                take_ownership=True
                )
        logging.info("Connecting controller")
        # create controller
        control = Controller.from_port(
                address="127.0.0.1", 
                port=int(config['ControlPort'])
                )
        # auth controller
        control.authenticate(password=controlPass)
        logging.info("Connected to tor process")
        return process, control
    except Exception as e:
        logging.exception(e)
        raise e

if __name__ == "__main__":
    logging.basicConfig(format='[%(asctime)s] %(message)s', datefmt="%H:%M:%S", level=logging.DEBUG)
    password = raw_input('password: ')
    password_hash = genTorPassHash(password)
    config = { 
        'ClientOnly': '1',
        'ControlPort': '9051',
        'DataDirectory': '~/.tor/temp',
        'Log': ['DEBUG stdout', 'ERR stderr' ],
        'HashedControlPassword' : password_hash }

    torProcess, torControl = startTor(password, config)

And here is how to do it without using tor (original found here):


from os import urandom
from binascii import b2a_hex
from hashlib import sha1

def getTorPassHash(secret='password'):
    '''
    https://gist.github.com/jamesacampbell/2f170fc17a328a638322078f42e04cbc
    '''
    # static 'count' value later referenced as "c"
    indicator = chr(96)
    # generate salt and append indicator value so that it
    salt = "%s%s" % (urandom(8), indicator)
    c = ord(salt[8])
    # generate an even number that can be divided in subsequent sections. (Thanks Roman)
    EXPBIAS = 6
    count = (16+(c&15)) << ((c>>4) + EXPBIAS)
    d = sha1()
    # take the salt and append the password
    tmp = salt[:8]+secret
    # hash the salty password
    slen = len(tmp)
    while count:
        if count > slen:
            d.update(tmp)
            count -= slen
        else:
            d.update(tmp[:count])
            count = 0
    hashed = d.digest()
    # Put it all together into the proprietary Tor format.
    return '16:%s%s%s' % (b2a_hex(salt[:8]).upper(),
                          b2a_hex(indicator),
                          b2a_hex(hashed).upper())

if __name__ == '__main__':
    password = raw_input("password: ")
    password_hash = getTorPassHash(password)
    config = { 
            'ClientOnly': '1',
            'ControlPort': '9051',
            'DataDirectory': '~/.tor/temp',
            'Log': ['DEBUG stdout', 'ERR stderr' ],
            'HashedControlPassword' : password_hash }

    torProcess, torControl = startTor(password, config)
s4w3d0ff
  • 1,091
  • 10
  • 24