sockshandler.py may need a little update
tigerzhou100800 opened this issue · 14 comments
New Python3
When create opener this way :
import urllib.request as urllib2
import socks
from sockshandler import SocksiPyHandler
opener = urllib2.build_opener(SocksiPyHandler(socks.SOCKS5, "127.0.0.1", 9050))
source code sockshandler.py line 49,
self.sock = ssl.wrap_socket(sock, self.key_file, self.cert_file)
Will cause SNI(server name indication) missing , that cloudflare cdn may 403 error or blank page.
Multi sites host on same ip need SNI to tell apart request to which.
https://docs.python.org/3.7/library/ssl.html#ssl.wrap_socket
Deprecated since version 3.7: Since Python 3.2 and 2.7.9, it is recommended to use the SSLContext.wrap_socket() instead of wrap_socket(). The top-level function is limited and creates an insecure client socket without server name indication or hostname matching.
Hotfix:
mod this class
class SocksiPyConnectionS(httplib.HTTPSConnection):
def __init__(self, proxytype, proxyaddr, proxyport=None, rdns=True, username=None, password=None, *args, **kwargs):
self.proxyargs = (proxytype, proxyaddr, proxyport, rdns, username, password)
httplib.HTTPSConnection.__init__(self, *args, **kwargs)
def connect(self):
sock = socks.socksocket()
sock.setproxy(*self.proxyargs)
if type(self.timeout) in (int, float):
sock.settimeout(self.timeout)
sock.connect((self.host, self.port))
self.sock = ssl.wrap_socket(sock, self.key_file, self.cert_file)
to this
class SocksiPyConnectionS(httplib.HTTPSConnection):
def __init__(self, proxytype, proxyaddr, proxyport=None, rdns=True, username=None, password=None, *args, **kwargs):
self.context = ssl.create_default_context()
self.proxyargs = (proxytype, proxyaddr, proxyport, rdns, username, password)
httplib.HTTPSConnection.__init__(self, *args, **kwargs)
def connect(self):
sock = socks.socksocket()
sock.setproxy(*self.proxyargs)
if type(self.timeout) in (int, float):
sock.settimeout(self.timeout)
sock.connect((self.host, self.port))
self.sock = self.context.wrap_socket(sock,server_hostname=self.host)
Haaa
Sorry, my bad.
sock.setproxy(*self.proxyargs)
equivalent to sock.set_proxy(*self.proxyargs)
in any case,
and
self.proxy =
also equivalent to socksocket.proxy =
if use only one proxy server.
I think you could re-compare original with your patched 1.7.0.
I found a issue, only from python 32 to 36, class HTTPSConnection
has _check_hostname
attribute.
My bad.
I have found the issue, self.proxy =
is not equivalent to socksocket.proxy =
.
import socks
socks.socksocket.proxy = 'something'
sock = socks.socksocket()
print(sock.proxy) # (None, None, None, None, None, None)
In fact, you directed open req
without via proxy server.
I have found the issue,
self.proxy =
is not equivalent tosocksocket.proxy =
.import socks socks.socksocket.proxy = 'something' sock = socks.socksocket() print(sock.proxy) # (None, None, None, None, None, None)In fact, you directed open
req
without via proxy server.
Yes, that two fix I posted before are all wrong.
First one doesn't change any in my proxy setting , because I didn't use keyword args.
Second one as you point out , It just didn't via proxy at all.
Thinking first one changes any , was the socks4 proxy that I used was unstable.
Socks4 with no bug. What I posted before it's mistake. It was all about remote dns.
Here was what happened :
The site I tested is filtered dns resolve by my ISP, direct dns that site will block IP, and via proxy dns also block IP.
I changed my system local hosts file to static resolve that site .
When I use socks.set_default_proxy
It didn't set remote dns to True (whether your set rdns True of
False , doesn't work, see next reply ).
I wrote a socks5 python script , it received host IP addrs when I use socks.set_default_proxy
.
So connected to the test site OK.
When use opener , it realy did remote dns resolve, causing IP blocked by my ISP . So it wasn't PySocks wrong.
When change sockshandler.py rdns to False , socks4 works fine.
And socks5 I tested before , was using my socks5 script , it does dns resolve via dnscrypt, so didn't got blocked.
Didn't test python2, here tested in python3.
import urllib.request as urllib2
import socket
import socks
socks.set_default_proxy(socks.SOCKS5, "localhost")
socket.socket = socks.socksocket
Whether your set rdns
socks.set_default_proxy(socks.SOCKS5,"127.0.0.1", 7071, True)
socks.set_default_proxy(socks.SOCKS5,"127.0.0.1", 7071, False)
same pdb result
python 3.6.7 c:\python36\lib\socket.py(713)create_connection()
702 host, port = address # It's hostname here
703 err = None
704 for res in getaddrinfo(host, port, 0, SOCK_STREAM):
705 af, socktype, proto, canonname, sa = res # After getaddrinfo reture res , sa in res already resolve to hostip . For example ('141.101.120.54', 443)
706 sock = None
707 try:
708 sock = socket(af, socktype, proto)
709 if timeout is not _GLOBAL_DEFAULT_TIMEOUT:
710 sock.settimeout(timeout)
711 if source_address:
712 sock.bind(source_address)
713 -> sock.connect(sa) # This call socks.py of PySocks
socks.py receive request in ip form, already resolve dns .
No DNS work left to socks.py
Whether your set rdns
socks.set_default_proxy(socks.SOCKS5, "localhost", True) socks.set_default_proxy(socks.SOCKS5, "localhost", False)
should be
socks.set_default_proxy(socks.SOCKS5, "localhost", rdns=True)
socks.set_default_proxy(socks.SOCKS5, "localhost", rdns=False)
# use default port 1080
or
socks.set_default_proxy(socks.SOCKS5, "localhost", your_port, True)
socks.set_default_proxy(socks.SOCKS5, "localhost", your_port, False)
Whether your set rdns
socks.set_default_proxy(socks.SOCKS5, "localhost", True) socks.set_default_proxy(socks.SOCKS5, "localhost", False)should be
socks.set_default_proxy(socks.SOCKS5, "localhost", rdns=True) socks.set_default_proxy(socks.SOCKS5, "localhost", rdns=False) # use default port 1080or
socks.set_default_proxy(socks.SOCKS5, "localhost", your_port, True) socks.set_default_proxy(socks.SOCKS5, "localhost", your_port, False)
See the old post, about dns.
#22
Forget #22, if you do not use socket
directly.
If you want to use urllib.request.OpenerDirector
, sockshandler has provided, do socket.socket = socks.socksocket
has no effect; if you want to create a new connection, use socks.create_connection
, not the socket.create_connection
.
already 3 years have passed, and now it looks like sockshandler doesn't work anymore on python 3.10.
I've receive an issue on my repo: nil0x42/phpsploit#194
It's frustrating, i'll have to make a copy of the lib patched by #135 instead of waiting for a proper release.
@Anorov , would you kindly consider merging pull requests ?