2009-12-26 20 views
32

Sto cercando di usare Tor-server come proxy in HttpWebRequest, il mio codice simile a questo:usando Tor come proxy

HttpWebRequest request; 
HttpWebResponse response; 

request = (HttpWebRequest)WebRequest.Create("http://www.google.com"); 
request.Proxy = new WebProxy("127.0.0.1:9051"); 

response = (HttpWebResponse)request.GetResponse(); 
response.Close(); 

funziona perfettamente con i "normali", ma con i proxy Tor sto ottenendo eccezioni durante la chiamata

GetResponse() with Status = ServerProtocolViolation. The message is (in German...):Message = "Der Server hat eine Protokollverletzung ausgeführt.. Section=ResponseStatusLine"

risposta

22

Tor è non un proxy HTTP. È un proxy SOCKS. È possibile utilizzare un proxy HTTP che supporta l'inoltro su SOCKS (come Privoxy) e collegarsi a tale tramite codice invece.

+0

Argh ... giusto. così posso usarlo * in qualche modo * per fare una richiesta? – Lay

+2

Lay: niente è costruito in .NET per inoltrare materiale HTTP tramite un proxy SOCKS. –

34

Se avete privoxy installato e funzionante si può fare

request.Proxy = new WebProxy("127.0.0.1:8118"); // default privoxy port 

che vi permetterà di effettuare le richieste usando Tor

+0

Ma penso che questo storni DNS – Para

+0

Vidalia sia stato rimosso dal pacchetto Tor. –

0

È necessario "estrarre" un flusso dai calzini ...

Imports System.IO 
Imports System.Net 
Imports System.Net.Sockets 
Imports System.Text 
Imports System.Runtime.CompilerServices 

Public Class Form1 

    Sub Form1_Load() Handles Me.Load 

     Dim Host As String = "google.com" 

     Dim P As New SocksProxy("localhost", 64129) 'Set your socks proxy here 
     Dim Stream As NetworkStream = P.GetStream(Host, 80) 
     Dim buffer As Byte() = Download(Stream, Host, "") 

     My.Computer.FileSystem.WriteAllBytes("C:\webpage.html", buffer, False) 

     MsgBox("ok") 
    End Sub 

    Function Download(Stream As NetworkStream, Host As String, Resource As String) As Byte() 

     Using writer = New StreamWriter(Stream) 
      writer.Write(String.Format("GET /{2} HTTP/1.1{0}Host: {1}{0}{0}", vbCrLf, Host, Resource)) 
      writer.Flush() 

      Dim byteList As New List(Of Byte) 
      Dim bufferSize As Integer = 4096 
      Dim buffer(bufferSize - 1) As Byte 

      Do 
       Dim bytesRead As Integer = Stream.Read(buffer, 0, bufferSize) 
       byteList.AddRange(buffer.Take(bytesRead)) 
      Loop While Stream.DataAvailable 

      Return byteList.ToArray 
     End Using 

    End Function 
End Class 


Public Class SocksProxy 

    Private _SocksHost As String 
    Private _SocksPort As Integer 

    Sub New(SocksHost As String, SocksPort As Integer) 
     _SocksHost = SocksHost 
     _SocksPort = SocksPort 
    End Sub 

    Function GetStream(HostDest As String, PortDest As Short) As NetworkStream 

     Dim client As TcpClient = New TcpClient() 
     client.Connect(_SocksHost, _SocksPort) 

     Dim stream As NetworkStream = client.GetStream() 
     'Auth 
     Dim buf = New Byte(299) {} 
     buf(0) = &H5 
     buf(1) = &H1 
     buf(2) = &H0 
     stream.Write(buf, 0, 3) 

     ReadExactSize(stream, buf, 0, 2) 
     If buf(0) <> &H5 Then 
      Throw New IOException("Invalid Socks Version") 
     End If 
     If buf(1) = &HFF Then 
      Throw New IOException("Socks Server does not support no-auth") 
     End If 
     If buf(1) <> &H0 Then 
      Throw New Exception("Socks Server did choose bogus auth") 
     End If 

     buf(0) = &H5 
     buf(1) = &H1 
     buf(2) = &H0 
     buf(3) = &H3 
     Dim domain = Encoding.ASCII.GetBytes(HostDest) 
     buf(4) = CByte(domain.Length) 
     Array.Copy(domain, 0, buf, 5, domain.Length) 
     Dim port = BitConverter.GetBytes(IPAddress.HostToNetworkOrder(CShort(PortDest))) 
     buf(5 + domain.Length) = port(0) 
     buf(6 + domain.Length) = port(1) 
     stream.Write(buf, 0, domain.Length + 7) 


     ' Reply 
     ReadExactSize(stream, buf, 0, 4) 
     If buf(0) <> &H5 Then 
      Throw New IOException("Invalid Socks Version") 
     End If 
     If buf(1) <> &H0 Then 
      Throw New IOException(String.Format("Socks Error {0:X}", buf(1))) 
     End If 
     Dim rdest = String.Empty 
     Select Case buf(3) 
      Case &H1 
       ' IPv4 
       ReadExactSize(stream, buf, 0, 4) 
       Dim v4 = BitConverter.ToUInt32(buf, 0) 
       rdest = New IPAddress(v4).ToString() 
       Exit Select 
      Case &H3 
       ' Domain name 
       ReadExactSize(stream, buf, 0, 1) 
       If buf(0) = &HFF Then 
        Throw New IOException("Invalid Domain Name") 
       End If 
       ReadExactSize(stream, buf, 1, buf(0)) 
       rdest = Encoding.ASCII.GetString(buf, 1, buf(0)) 
       Exit Select 
      Case &H4 
       ' IPv6 
       Dim octets = New Byte(15) {} 
       ReadExactSize(stream, octets, 0, 16) 
       rdest = New IPAddress(octets).ToString() 
       Exit Select 
      Case Else 
       Throw New IOException("Invalid Address type") 
     End Select 
     ReadExactSize(stream, buf, 0, 2) 
     Dim rport = CUShort(IPAddress.NetworkToHostOrder(CShort(BitConverter.ToUInt16(buf, 0)))) 

     Return stream 
    End Function 

    Private Sub ReadExactSize(stream As NetworkStream, buffer As Byte(), offset As Integer, size As Integer) 
     While size <> 0 
      Dim read = stream.Read(buffer, offset, size) 
      If read < 0 Then 
       Throw New IOException("Premature end") 
      End If 
      size -= read 
      offset += read 
     End While 
    End Sub 

End Class 
4

Utilizzare la libreria "SocksWebProxy". È possibile utilizzarlo con WebClient & WebRequest (Assegnare semplicemente un nuovo SocksWebProxy all'attributo * .Proxy). Non c'è bisogno di Privoxy o servizio simile per tradurre il traffico http in tor.

https://github.com/Ogglas/SocksWebProxy

ho fatto alcune estensioni ad esso pure abilitando la porta di controllo. Ecco come si potrebbe avere Tor in esecuzione in background senza Tor Browser Bundle avviato e per controllare Tor possiamo usare Telnet o inviare comandi programmaticamente tramite Socket.

Socket server = null; 

//Authenticate using control password 
IPEndPoint endPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 9151); 
server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 
server.Connect(endPoint); 
server.Send(Encoding.ASCII.GetBytes("AUTHENTICATE \"your_password\"" + Environment.NewLine)); 
byte[] data = new byte[1024]; 
int receivedDataLength = server.Receive(data); 
string stringData = Encoding.ASCII.GetString(data, 0, receivedDataLength); 

//Request a new Identity 
server.Send(Encoding.ASCII.GetBytes("SIGNAL NEWNYM" + Environment.NewLine)); 
data = new byte[1024]; 
receivedDataLength = server.Receive(data); 
stringData = Encoding.ASCII.GetString(data, 0, receivedDataLength); 
if (!stringData.Contains("250")) 
{ 
    Console.WriteLine("Unable to signal new user to server."); 
    server.Shutdown(SocketShutdown.Both); 
    server.Close(); 
} 
else 
{ 
    Console.WriteLine("SIGNAL NEWNYM sent successfully"); 
} 

passaggi per configurare Tor:

  1. Copia torrc-defaults nella directory in cui è tor.exe. La directory predefinita se si utilizza Tor browser è: "~ \ Tor Browser \ Browser \ TorBrowser \ Data \ Tor"
  2. Aprire una finestra del prompt di cmd
  3. chdir nella directory in cui è tor.exe. La directory predefinita se si utilizza il browser Tor è: "~ \ Tor Browser \ Browser \ TorBrowser \ Tor \"
  4. Generare una password per l'accesso alla porta di controllo Tor. tor.exe --hash-password “your_password_without_hyphens” | more
  5. Aggiungere la password hash della password a torrc-defaults in ControlPort 9151. Dovrebbe essere simile a questa: hashedControlPassword 16:3B7DA467B1C0D550602211995AE8D9352BF942AB04110B2552324B2507. Se accetti la tua password come "password", puoi copiare la stringa qui sopra.
  6. Ora è possibile accedere al controllo Tor tramite Telnet una volta avviato. Ora il codice può essere eseguito, basta modificare il percorso in cui si trovano i file Tor nel programma. test modificando Tor via Telnet:
  7. tor Inizia con il seguente comando: tor.exe -f .\torrc-defaults
  8. aprire un altro tipo cmd pronta e: telnet localhost 9151
  9. Se tutto va bene si dovrebbe vedere una schermata completamente nera. Digita "autenticate “your_password_with_hyphens”" Se tutto va bene dovresti vedere "250 OK".
  10. Digita "SIGNAL NEWNYM" e otterrai una nuova rotta, ergo nuovo IP. Se tutto va bene dovresti vedere "250 OK".
  11. tipo "setevents circ" (eventi del circuito) per abilitare l'output su console
  12. Tipo "getinfo circuit-status" per vedere i circuiti di corrente
Problemi correlati