Sending POST request with python to private OnionShare server in receive mode

54 Views Asked by At

Im trying to send data to a private onionshare server in receive mode with this simple program:

import socket
import requests

s = requests.session()
s.proxies['http'] = 'socks5h://127.0.0.1:9060'
s.proxies['https'] = 'socks5h://127.0.0.1:9060'

print(s.proxies)

url = 'http://*redacted*.onion'

headers = {
    'Content-Type': 'application/json'
}

data = {
    'key':'*redacted*'
}

try:
    r = s.post(url, headers=headers, json=data, proxies=s.proxies)
    print(r.text)
except Exception as e:
    print(e)

I keep on getting this error:

SOCKSHTTPConnectionPool(host='*redacted*.onion', port=80): Max retries exceeded with url: / (Caused by NewConnectionError('<urllib3.contrib.socks.SOCKSConnection object at 0x7fdf710c5a50>: Failed to establish a new connection: 0x01: General SOCKS server failure'))

Tried the following:

  • Tried changing the request to get. Got the same error message
  • Tried connecting to a known onion address:

https://www.facebookwkhpilnemxj7asaniu7vnjjbiltxjqhye3mhbshg7kx5tfyd.onion/

This worked. Same thing with just curling it.

  • Tried changing the port values in torrc, thats why the ports are 9060.
  • Tried using the stem library to control the tor process. This gave me similar errors. Based on what ive read about stem I feel like its the way to go, but Unfortunately I havent had much luck with it yet.
  • Tried making the onionshare public and sending a get request to it. This worked, so it seems like the problem has to do with the client authorization when the onionshare service is private.
  • Tried adding ClientOnionAuthDir with a dir to the torrc file. I created a .auth_private file for the onionshare service with the onion address and private key with the format <onion addr without .onion>:x25519:< private key >. (I restarted tor as a service after changing the torrc file). After adding this to the torrc file i got the following from notices.log when trying to access the service both with the original program and through stem:
[notice] Fail to decrypt descriptor for requested onion address. It is likely requiring client authorization.

Note that im not sure what Content-Type the OnionShare server expects. Unfortunately I found very little on the matter when looking in their docs.

1

There are 1 best solutions below

0
Curliness7530 On

I fixed the problem with client authorization. The issue was the format in my .auth_private file. I was missing 'descriptor' in between the onion address and the x25519. I also changed the program quite a bit, and started using stem. With these changes i managed to get the html from the onionshare page through a get request. After this i changed the code to make a post request with a message to the onionshare service. This worked.

from stem import Signal
from stem.control import Controller
import requests

files = {'text':(None,'test')}

def request_over_tor(url):
    with Controller.from_port(port = 9061) as controller:
        # Provide your authentication here if needed
        # Signal Tor for a new circuit
        controller.authenticate(password='*redacted*')
        controller.signal(Signal.NEWNYM)
        
        proxies = {
            'http': 'socks5h://127.0.0.1:9060',
            'https': 'socks5h://127.0.0.1:9060',
        }
       
        response = requests.post(url, proxies=proxies, files=files)
        return response.text

hidden_service_url = 'http://*redacted*.onion/upload'
response_content = request_over_tor(hidden_service_url)
print(response_content)