CRover CRover - 14 days ago 6
HTTP Question

Trying to automate Tor to do something on a site and change identity each time. Need some guidance

I really need some help with automating Tor to do something on a site (in this case, check something on a poll) and then restart Tor with a new identity. I have never done anything remotely close to this. I only know HTML, CSS and JS fairly well.

Now, to sum up, I want to make a loop that repeatedly accesses a site on Tor, checks something on that site and then restarts Tor with a new identity.

If anyone could give me some guidance and tell me what I can use, it would be much appreciated. I have the time and patience to learn, so anything works really.

Answer

Here are examples using PHP and Python 3 to accomplish what you want. They're simple starting points for making requests over Tor and changing your identity on demand.

The PHP example uses TorUtils to communicate with the controller and wrap cURL through Tor.

The Python example uses stem to communicate with the controller and Requests for sending requests over Tor's SOCKS proxy.

The examples assume you have Tor working already and the SocksPort set to 9050, and the ControlPort set to 9051 with cookie authentication working, or a controller password of password.

PHP

Set Up

  • Install Composer to install the TorUtils package (you can also download the zipball and extract)
  • Once composer is working, run composer require dapphp/torutils from your project directory to download and install dependencies

Code

<?php

use Dapphp\TorUtils\ControlClient;
use Dapphp\TorUtils\TorCurlWrapper;

require_once 'vendor/autoload.php'; // composer autoloader
// include TorUtils/src/ControlClient.php and TorUtils/src/TorCurlWrapper.php if using without composer

$controller = new ControlClient; // get a new controller object

try {
    $controller->connect('127.0.0.1', 9051); // connect to Tor controller on localhost:9051
    $controller->authenticate('password');   // attempt to authenticate using "password" as password
} catch (\Exception $ex) {
    die("Failed to open connection to Tor controller.  Reason: " . $ex->getMessage() . "\n");
}   

// issue 10 requests, changing identity after each request
for ($i = 0; $i < 10; ++$i) {
    try {
        $curl = new TorCurlWrapper('127.0.0.1', 9050); // connect to Tor SOCKS proxy on localhost:9050
        $curl->httpGet('https://drew-phillips.com/ip-info/'); // issue request
        $body = strip_tags($curl->getResponseBody());

        if (preg_match('/Using Tor:\s*Yes/i', $body)) {
            echo "You appear to be using Tor successfully.  ";
        } else {
            echo "Proxy worked but this Tor IP is not known.  ";
        }

        if (preg_match('/IP Address:\s*(\d+\.\d+\.\d+\.\d+)/i', $body, $ip)) {
            echo "Source IP = {$ip[1]}\n";
        } else {
            echo "Couldn't determine IP!\n";
        }
    } catch (\Exception $ex) {
        echo "HTTP request failed!  " . $ex->getMessage() . "\n";
    }

    // TODO: issue more requests as needed here

    echo "\n";
    sleep(10);

    try {
        // send signal to controller to request new identity (IP)
        $controller->signal(ControlClient::SIGNAL_NEWNYM);
    } catch (\Exception $ex) {
        echo "Failed to issue NEWNYM signal: " . $ex->getMessage() . "\n";
    }
}   

Python 3

Set Up

This example uses Python 3 and assumes you have the Python interpreter up and running and have the following packages installed: requests, requests[socks], socks, urllib3, stem.

On Debian/Ubuntu: sudo -H pip3 install requests requests[socks] socks urllib3 stem

Code

#!/usr/bin/env python3

import requests
from stem.control import Controller, Signal
import time
import sys
import re

# specify Tor's SOCKS proxy for http and https requests
proxies = {
    'http': 'socks5://127.0.0.1:9050',
    'https': 'socks5://127.0.0.1:9050',
}

try:
    controller = Controller.from_port(9051) # try to connect to controller at localhost:9051
except stem.SocketError as exc:
    print("Unable to connect to tor on port 9051: %s" % exc)
    sys.exit(1)

try:
    controller.authenticate('password') # try to authenticate with password "password"
except stem.connection.PasswordAuthFailed:
    print("Unable to authenticate, password is incorrect")
    sys.exit(1)

# issue 10 requests, changing identity after each request
for i in range(1,10):
    # issue request, passing proxies to request
    r = requests.get('https://drew-phillips.com/ip-info/', proxies=proxies)

    #print(r.text)

    m = re.search('<dt>Using Tor:</dt><dd><span[^>]*>Yes', r.text)
    if m:
        print("You appear to be using Tor successfully.  ", end="")
    else:
        print("Proxy worked but this Tor IP is not known.  ", end="")

    m = re.search('<dt>IP Address:</dt><dd>(\d+\.\d+\.\d+\.\d+)</dd>', r.text)
    if m:
        print("Source IP = %s" % m.groups(1))
    else:
        print("Failed to scrape IP from page")

    try:
        # send signal to controller to request new identity (IP)
        controller.signal(Signal.NEWNYM)
    except Exception as ex:
        print("NEWNYM failed: %s" % ex)

    time.sleep(10)