Kyron
Kyron

Reputation: 64

Multiple TOR Exit Nodes - Controller Not Working?

I'm trying to use Multiple TOR exit nodes with Selenium, and I'm trying to create a function that changes the multiple identities. However, it doesn't, and returns no error. I believe there's a problem with my code that I can't quite figure out. Perhaps the controller is failing?

(I have stderr() outputted to a file and I get nothing every time. And I've also killed each process of TOR)

Here's my code:

import socks
import socket
import subprocess
import stem.connection
import stem.socket
from selenium import webdriver
from stem.control import Controller

global requiredTorRelays
global child_pid
global relays
global driver
requiredTorRelays = math.ceil(_.MAX_FBTC_ACCOUNTS_/270)
driver = []
child_pid = []

def initTor(i):
    print("\n[+] TOR NETWORK "+str(i)+" INITIALIZING...")
    print(" - Updating Preferences...")
    ff_prof = webdriver.FirefoxProfile()

    ff_prof.set_preference( "places.history.enabled", False )
    ff_prof.set_preference( "privacy.clearOnShutdown.offlineApps", True )
    ff_prof.set_preference( "privacy.clearOnShutdown.passwords", True )
    ff_prof.set_preference( "privacy.clearOnShutdown.siteSettings", True )
    ff_prof.set_preference( "privacy.sanitize.sanitizeOnShutdown", True )
    ff_prof.set_preference( "signon.rememberSignons", False )
    ff_prof.set_preference( "network.cookie.lifetimePolicy", 2 )
    ff_prof.set_preference( "network.dns.disablePrefetch", True )
    ff_prof.set_preference( "network.http.sendRefererHeader", 0 )

    ff_prof.set_preference( "network.proxy.type", 1 )
    ff_prof.set_preference( "network.proxy.socks_version", 5 )
    ff_prof.set_preference( "network.proxy.socks", '127.0.0.1' )
    ff_prof.set_preference( "network.proxy.socks_port", 9050+i )
    ff_prof.set_preference( "network.proxy.socks_remote_dns", True )
    ff_prof.set_preference( "browser.link.open_newwindow.restriction", 1 )

    ff_prof.set_preference( "javascript.enabled", True )
    ff_prof.update_preferences()
    print(" - Opening Browser...")
    os.environ['DISPLAY'] = ':99'
    driver.extend([webdriver.Firefox(ff_prof)])

    if(i==0):
        j=''
    else:
        j=str(i)

    tor_path = _.TOR_PATH_
    DETACHED_PROCESS = 0x00000008

    print(" - Starting TOR Process...")

    tor_process = subprocess.Popen( '"'+_.TOR_PATH_+'" --RunAsDaemon 1 --CookieAuthentication 1 --HashedControlPassword "'+_.TOR_HASHED_PASS_+'" --ControlPort '+str(9060+i)+' --PidFile tor'+j+'.pid --SocksPort '+str(9050+i)+' --DataDirectory data/tor'+j, creationflags=DETACHED_PROCESS)
    child_pid.extend([tor_process.pid])
    print(" - Starting TOR Controller...")

    C_PORT=int(9060+i)

 ## Function to check how many TOR Configuration Files are present
def checkNoTorFolders():
    torCount = 0
    folders = next(os.walk("data/"))[1]
    for folder in folders:
        if(folder[0:3]=="tor"):
            torCount+=1
    return torCount

## Function to create a new TOR Configuration File
def createNewDataFolder(i):
    if(i==0):
        if(not os.path.exists('data/tor')):
            os.makedirs('data/tor')
    else:
        if(not os.path.exists('data/tor'+str(i))):
            os.makedirs('data/tor'+str(i))


## Function to create new ID
def newID(i):
    with Controller.from_port(port = 9060+int(i)) as controller:
        controller.authenticate(_.TOR_PASS_)
        controller.signal(Signal.NEWNYM)

## Main Process/Call Functions

i=0

if(int(checkNoTorFolders())<requiredTorRelays):
    print("\n[+] CREATING "+str(requiredTorRelays-int(checkNoTorFolders()))+" NEW DATA FOLDERS...")
    while(i<=requiredTorRelays-int(checkNoTorFolders())-1):
        createNewDataFolder(int(checkNoTorFolders()))
        print("- Created Data Folder: "+str(int(checkNoTorFolders())))

for x in range(0,int(checkNoTorFolders())):
    initTor(x)
    driver[x].get("http://wtfismyip.com/text")
    print(' - IP: '+driver[x].find_element_by_tag_name('pre').text)
    ip.extend(driver[x].find_element_by_tag_name('pre').text)

print("\n[+] TESTING NETWORK(S)...")

## Test Identity Changing
for limit in range(0,3):
    for i in range(0,requiredTorRelays):
        print("\n[+] RETRIEVING NEW IDENTITY ["+str(i)+"]...")
        newID(i)
        driver[i].get("http://wtfismyip.com/text")
        print(' - IP: '+driver[i].find_element_by_tag_name('pre').text)

    time.sleep(10)

input()

Upvotes: 1

Views: 1568

Answers (1)

Kyron
Kyron

Reputation: 64

I have re-written the code, as it seems my code was just awful. I'm not sure what the problem was, however, here's the update for anyone trying to do the same:

assert str is not bytes

from lib_socks_proxy_2013_10_03 import monkey_patch as socks_proxy_monkey_patch

socks_proxy_monkey_patch.monkey_patch()

import io
import re

import time

import stem.connection
import stem.socket
import stem.process 
from stem import Signal
from stem.control import Controller
from stem.util import term

from urllib import request as req
from lib_socks_proxy_2013_10_03 import socks_proxy_context

import config

tor_process = []
_ = config.variables

def startTor(i):
    print(" - Starting TOR Process...")    

    tor_process.extend([stem.process.launch_tor_with_config(
        config={
            'SocksPort':str(9050+i),
            'ControlPort':str(9070+i),
            'CookieAuthentication':str(1),
            'HashedControlPassword':str(_.TOR_HASHED_PASS_),
            'DataDirectory':'data/tor'+str(i),
            'PidFile':'tor'+str(i)+'.pid',
                        },
        init_msg_handler = print_bootstrap_lines,
        )])

def print_bootstrap_lines(line):
    if("Bootstrapped " in line):
        print(line)

def checkIP(i):
    print("[+] Checking IP Address...")
    try:
        opener = req.build_opener()

        with socks_proxy_context.socks_proxy_context(proxy_address=('127.0.0.1', 9050+i)):
           res = opener.open('https://internet.yandex.com/get_full_info/', timeout=20.0)

        data = res.read(10000).decode()
        print(data)
    except:
        print(" - Failed.")


def changeIP(i):
    print("[+] Changing IP Address... ["+str(i)+"]")
    with Controller.from_port(port = 9070+i) as controller:
        controller.authenticate(_.TOR_PASS_)
        controller.signal(Signal.NEWNYM)

## Test 3 nodes.

if(__name__=="__main__"):
    for x in range(0,3):
        startTor(x)
        checkIP(x)
    for x in range(0,3):
        changeIP(x)
    for x in range(0,3):
        checkIP(x)
        tor_process[x].kill() 

For anyone planning on using this: don't cycle the TOR servers too fast/too much as it puts strain on the network.

Upvotes: 2

Related Questions