Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save skanga/8496b942949a0a8979eab6b1fcc9f4cd to your computer and use it in GitHub Desktop.
Save skanga/8496b942949a0a8979eab6b1fcc9f4cd to your computer and use it in GitHub Desktop.

Setup TOR on Ubuntu

# Install TOR and some other needed dependencies:
sudo apt-get install -y tor curl netcat

# Stop service (if running):
/etc/init.d/tor stop

# Create torrc file
cat << ENDSCRIPT > ./torrc

# Upstream proxy server (if any)
#HTTPSProxy www-proxy.company.com:80
# Generate this password hash by running
# tor --quiet --hash-password S0m3R4ndomP455w0rd
HashedControlPassword "16:270CC23D19E82BA760416A3CEBC4BA1270AD8A1C39D25ADF0D1483D01C"
# Listen for incoming socks connections on this port
SocksPort 1080
# Allow only local connections
SocksPolicy accept 127.0.0.1
SocksPolicy reject *
# Telnet port to control tor
ControlPort 1081
# Log "notice" messages to stdout
Log notice stdout
# Try for at most NUM seconds when building circuits. If the circuit isn't open in that time, give up on it.
CircuitBuildTimeout 5
# Send a padding cell every N seconds to keep firewalls from closing connections while Tor is not in use
KeepalivePeriod 60
# Force Tor to consider whether to build a new circuit every NUM seconds.
NewCircuitPeriod 200
# How many entry guards should we keep at a time?
NumEntryGuards 8
DirReqStatistics 0
AvoidDiskWrites 1

ENDSCRIPT

# Create tornewip script
cat << ENDSCRIPT > ./tornewip
(
nc localhost 1081 <<EOF
authenticate "S0m3R4ndomP455w0rd"
signal newnym
quit
EOF
) >/dev/null || echo "Connection failed." >&2

curl -x socks5h://localhost:1080 https://ipinfo.io/ip
ENDSCRIPT

# Make it executable
chmod +x tornewip

# Alternate tornewip script
(echo authenticate '"S0m3R4ndomP455w0rd"'; echo signal newnym; echo quit) | nc localhost 9051
(echo authenticate '"S0m3R4ndomP455w0rd"'; echo GETINFO circuit-status; echo quit) | nc localhost 9051


# Run TOR
tor -f torrc

# Force IP Change
./tornewip

Setup TOR on Windows

Download and install Tor browser bundle
https://deepdarkweb.github.io/how-to-install-tor-on-windows-without-the-tor-browser-running-tutorial/
https://miloserdov.org/?p=1839
Download nc64.exe from
https://github.com/int0x33/nc.exe/raw/master/nc64.exe

Set TOR_HOME in system environment to install dir - for example:
set TOR_HOME=c:\bin\TorBro~1\Browser\TorBrowser\Tor 

Create torrc file as shown

# Upstream proxy server (if any)
#HTTPSProxy www-proxy.company.com:80
# Generate this password hash by running
# tor --quiet --hash-password S0m3R4ndomP455w0rd
HashedControlPassword "16:270CC23D19E82BA760416A3CEBC4BA1270AD8A1C39D25ADF0D1483D01C"
# Listen for incoming socks connections on this port
SocksPort 1080
# Allow only local connections
SocksPolicy accept 127.0.0.1
SocksPolicy reject *
# Telnet port to control tor
ControlPort 1081
# Log "notice" messages to stdout
Log notice stdout
# Try for at most NUM seconds when building circuits. If the circuit isn't open in that time, give up on it.
CircuitBuildTimeout 5
# Send a padding cell every N seconds to keep firewalls from closing connections while Tor is not in use
KeepalivePeriod 60
# Force Tor to consider whether to build a new circuit every NUM seconds.
NewCircuitPeriod 200
# How many entry guards should we keep at a time?
NumEntryGuards 8
DirReqStatistics 0
AvoidDiskWrites 1

Create tornewip.bat

@echo off

REM Create file with control commands
echo AUTHENTICATE "S0m3R4ndomP455w0rd"> commands.txt
echo SIGNAL NEWNYM>> commands.txt
echo QUIT>> commands.txt

REM Connect to control port and issue commands
nc64 localhost 1081 < commands.txt

REM Delete commands file
del /Q commands.txt

Create torkill.bat

taskkill /f /im tor.exe

Create torrun.bat

set TOR_HOME=<location where you installed Tor Browser>
REM If directory has spaces then use short form - for example
REM set TOR_HOME=c:\Progra~1\TorBro~1\Browser\TorBrowser\Tor\
REM %TOR_HOME%\tor.exe --quiet --hash-password S0m3R4ndomP455w0rd | more
REM 16:270CC23D19E82BA760416A3CEBC4BA1270AD8A1C39D25ADF0D1483D01C

start %TOR_HOME%\tor.exe -f torrc

Test Socks Proxy (Multiple calls should change IP)

curl -x socks5h://localhost:1080 https://ipinfo.io/ip
tornewip
curl -x socks5h://localhost:1080 https://ipinfo.io/ip

Create a Java wrapper for the Tor proxy.

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.Socket;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;

public class TorGet
{
    private static final String socksHost = "127.0.0.1";
    private static final String httpsProxy = "";
    private static final String torDir = "/usr/bin/";    // CHANGE ON WINDOWS TO LOCATION OF TOR
    private static final String httpsProxy = "";         // SET IF NEEDED
    private static final String torPassword = "S0m3R4ndomP455w0rd";

    private static final int torDelay = 5000;       // sleep 5 seconds for new Tor circuit creation
    private static final int socksPort = 1080;      // Tor listen port for Socks proxy
    private static final int controlPort = 15000;   // Tor listen port for Control commands
    private static final int newCircuitEvery = 200; // Tor auto create new circuit after (in seconds)

    // https://iphelix.medium.com/hacking-the-tor-control-protocol-fb844db6a606

    public static void main(String... args) throws IOException, InterruptedException
    {
        if((args.length == 1) || (args.length == 2))
        {
            torStart();
            byte[] fileBytes = torGet(args[0]).responseBody;
            if(args.length == 1)
                System.out.println(bytesToString(fileBytes));
            else
                bytesToFile(fileBytes, args[1]);
            torStop();
        }
        else
        {
            System.out.println("USAGE: TorGet <get-url> [file-name]");
        }
    }

    public static void torNewIP() throws IOException, InterruptedException
    {
        String quotedPassword = '"' + torPassword + '"';
        Socket clientSocket = new Socket(socksHost, controlPort);
        PrintWriter outWriter = new PrintWriter(clientSocket.getOutputStream(), true);
        BufferedReader inReader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
        String[] newIPCommands = {"AUTHENTICATE " + quotedPassword, "SIGNAL NEWNYM", "QUIT"};
        for(String currCommand : newIPCommands)
        {
            outWriter.println(currCommand);
            //System.out.println(in.readLine());
        }
        inReader.close();
        outWriter.close();
        clientSocket.close();
        Thread.sleep(torDelay); //Give it some time to create a new circuit
    }

    /**
     * Spawns the Tor proxy process.
     *
     */
    public static void torStart() throws InterruptedException
    {
        taskKill(getTorExecutable());
        String passwordHash = passHash();

        if(System.getProperty("os.name").startsWith("Windows"))
            passwordHash = '"' + passwordHash.trim() + '"';
        else
            passwordHash = passwordHash.trim();

        String fullCommand = getTorExecutable() +
            //" -f " +  System.getProperty("user.dir") + File.separator + "torrc" +
            (httpsProxy.equals("") ? "" : " --HTTPSProxy " + httpsProxy) +
            " --SocksPort " + socksPort +
            " --ControlPort " + controlPort +
            " --HashedControlPassword " + passwordHash +
            " --NewCircuitPeriod " + newCircuitEvery +
            " --quiet --CircuitBuildTimeout 5 --KeepalivePeriod 60" +
            //" --SocksPolicy \"accept 127.0.0.1\" --SocksPolicy \"reject *\"";  // Fails on Linux
            " --NumEntryGuards 8 --DirReqStatistics 0 --AvoidDiskWrites 1";

        if(System.getProperty("os.name").startsWith("Windows"))
            runCommandWrapped(false, torDir, fullCommand);
        else
            runCommandFull(false, torDir, fullCommand);
        Thread.sleep(torDelay); //Give it some time to create a circuit
    }

    // Get the hashed version or the tor password
    public static String passHash()
    {
        if(System.getProperty("os.name").startsWith("Windows"))
            return runCommandWrapped(true, torDir, getTorExecutable() + " --quiet --hash-password " + torPassword);
        else
            return runCommandFull(true, torDir, getTorExecutable() + " --quiet --hash-password " + torPassword);
    }

    // Kill an OS process by name
    public static void taskKill(String strProcessName)
    {
        runCommandFull(true, null, getKillCommand() + strProcessName);
    }

    public static String getKillCommand()
    {
        if(System.getProperty("os.name").startsWith("Windows"))
            return "taskkill /f /im ";
        else
            return "pkill -f ";
    }

    public static String getTorExecutable()
    {
        if(System.getProperty("os.name").startsWith("Windows"))
            return "tor.exe";
        else
            return "/usr/bin/tor";
    }

    public static void torStop()
    {
        taskKill(getTorExecutable());
    }

    public static String runCommandWrapped(boolean readOutput, String workingDir, String fullCommand)
    {
        if(System.getProperty("os.name").startsWith("Windows"))
            fullCommand = "cmd.exe /c " + fullCommand;
        else
            fullCommand = "/bin/sh -c " + fullCommand;
        return runCommand(readOutput, workingDir, fullCommand.split(" "));
    }

    public static String runCommandFull(boolean readOutput, String workingDir, String fullCommand)
    {
        return runCommand(readOutput, workingDir, fullCommand.split(" "));
    }

    public static String runCommand(boolean readOutput, String workingDir, String... commandParts)
    {
        ProcessBuilder processBuilder = new ProcessBuilder().command(commandParts);
        if(workingDir != null) processBuilder.directory(new File(workingDir));

        try
        {
            Process process = processBuilder.start();

            if(readOutput)
            {
                StringBuilder resultBuilder = new StringBuilder();
                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
                String currLine;
                while((currLine = bufferedReader.readLine()) != null)
                {
                    resultBuilder.append(currLine).append(System.getProperty("line.separator"));
                }

                //wait for the process to complete
                process.waitFor();
                //close the resources
                bufferedReader.close();
                process.destroy();
                return resultBuilder.toString();
            }
        }
        catch(IOException | InterruptedException e)
        {
            e.printStackTrace();
        }
        return "";
    }

    // Save a byte array to a file
    public static void bytesToFile(byte[] inputBytes, String fileName) throws IOException
    {
        Path filePath = Paths.get(fileName);
        Files.write(filePath, inputBytes);
    }

    public static String bytesToString(byte[] inputBytes)
    {
        return new String(inputBytes, StandardCharsets.UTF_8);
    }

    public static HttpResponse torGet(String urlString) throws IOException
    {
        return torGet(urlString, socksHost, socksPort);
    }
    public static HttpResponse torGet(String urlString, String socksHost, int socksPort) throws IOException
    {
        // We can also use Proxy.Type.HTTP for HTTP proxies but for now SOCKS is enough
        Proxy socksProxy = new Proxy(Proxy.Type.SOCKS, new InetSocketAddress(socksHost, socksPort));
        return torGet(urlString, socksProxy);
    }

    public static HttpResponse torGet(String urlString, Proxy socksProxy) throws IOException
    {
        URL httpUrl = new URL(urlString);
        HttpURLConnection urlConnection = (HttpURLConnection) httpUrl.openConnection(socksProxy);
        urlConnection.setRequestMethod("GET");
        HttpResponse httpResponse = new HttpResponse();
        int responseCode = urlConnection.getResponseCode();
        httpResponse.responseCode = responseCode;
        InputStream inputStream;

        if(responseCode > 299)
        {
            inputStream = urlConnection.getErrorStream();
        }
        else
        {
            inputStream = urlConnection.getInputStream();
        }

        for(int i = 0; ; i++)
        {
            String headerName = urlConnection.getHeaderFieldKey(i);
            String headerValue = urlConnection.getHeaderField(i);
            if(headerName == null && headerValue == null)
                break;
            if(headerName == null)
            {
                String[] statusParts = headerValue.split(" ");
                httpResponse.httpVersion = statusParts[0];
                httpResponse.responseCode = Integer.parseInt(statusParts[1]);
                httpResponse.responseMessage = statusParts[2];
            }
            else
                httpResponse.responseHeaders.put(headerName, headerValue);
        }
        httpResponse.responseBody = readInputStream(inputStream);
        inputStream.close();
        urlConnection.disconnect();
        return httpResponse;
    }

    public static byte[] readInputStream(InputStream inputStream) throws IOException
    {
        BufferedInputStream inStream = new BufferedInputStream(inputStream);
        ByteArrayOutputStream outStream = new ByteArrayOutputStream();
        for(int nextByte = inStream.read(); nextByte != -1; nextByte = inStream.read())
        {
            outStream.write((byte) nextByte);
        }
        return outStream.toByteArray();
    }

    public static class HttpResponse
    {
        HashMap <String, String> responseHeaders = new HashMap <>();
        String httpVersion;
        int responseCode;
        String responseMessage;
        public byte[] responseBody;
    }
}

Test the Java wrapper for the Tor proxy.

import java.io.IOException;

public class TorGetNewIPTest
{
    public static void main(String... args) throws IOException, InterruptedException
    {
        TorGet.torStart();
        System.out.println("ipinfo.io -> " + TorGet.bytesToString(TorGet.torGet("https://ipinfo.io/ip").responseBody));
        System.out.println("ipify.org -> " + TorGet.bytesToString(TorGet.torGet("http://api.ipify.org").responseBody));
        System.out.println("ident.me -> " + TorGet.bytesToString(TorGet.torGet("http://ident.me").responseBody));
        System.out.println("icanhazip -> " + TorGet.bytesToString(TorGet.torGet("http://icanhazip.com").responseBody));
        System.out.println("dyndns.org -> " + TorGet.bytesToString(TorGet.torGet("http://checkip.dyndns.org").responseBody));

        TorGet.torNewIP();

        System.out.print("1. HTTP -> " + TorGet.bytesToString(TorGet.torGet("http://icanhazip.com").responseBody));
        System.out.print("1. HTTPS -> " + TorGet.bytesToString(TorGet.torGet("https://icanhazip.com").responseBody));

        TorGet.torNewIP();

        System.out.print("2. HTTP -> " + TorGet.bytesToString(TorGet.torGet("http://icanhazip.com").responseBody));
        System.out.print("2. HTTPS -> " + TorGet.bytesToString(TorGet.torGet("https://icanhazip.com").responseBody));

        TorGet.torNewIP();

        System.out.println("Onion -> " + TorGet.bytesToString(TorGet.torGet("http://p53lf57qovyuvwsc6xnrppyply3vtqm7l6pcobkmyqsiofyeznfu5uqd.onion").responseBody));

        TorGet.torStop();
    }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment