Using Paramiko with SOCKS proxy - python

I an trying to use Paramiko with SOCKS proxy (SecureCRT or PuTTY configured as SOCKS proxy). I am using the below code
import paramiko,socks
host, port = '127.0.0.1', 1080
# Set up your proxy information for this socket
sock=socks.socksocket()
sock.set_proxy(
proxy_type=socks.SOCKS4,
addr=host,
port=port,
)
# Connect the socket
sock.connect((host, port))
# Create your Paramiko Transport
transport = paramiko.Transport(sock)
transport.connect(
username='username', #<------not sure if it is needed, the socks proxy needs no username/password
password='secret',
)
client = paramiko.client.SSHClient.connect('remotedevice', username='usernameonremotedevice',sock=sock)
stdin, stdout, stderr=client.exec_command("ls -la")
# Do stuff
# Clean up
client.close()
transport.close()
The above approach seems to confuse Paramiko since it is using 127.0.0.1 for both.
My issue originated in the Paramiko libraries used by Exscript so I wanted to simplify to see if this would work ....
This is the log that SecureCRT shows with each attempt
[LOCAL] : Starting port forward from 127.0.0.1 on local 127.0.0.1:1080 to remote 127.0.0.1:1080.
[LOCAL] : Could not start port forwarding from local service 127.0.0.1:3106 to 127.0.0.1:1080. Reason: The channel could not be opened because the connection failed. Server error details: Connection refused
The script fails like below:
Traceback (most recent call last):
File "C:\Users\Username\Documents\Eclipse\ESNetworkDiscovery\ParamikoProxyTest.py", line 24, in <module>
sock.connect((host, port))
File "C:\Utils\WPy2.7-32\python-2.7.13\lib\site-packages\socks.py", line 96, in wrapper
return function(*args, **kwargs)
File "C:\Utils\WPy2.7-32\python-2.7.13\lib\site-packages\socks.py", line 813, in connect
negotiate(self, dest_addr, dest_port)
File "C:\Utils\WPy2.7-32\python-2.7.13\lib\site-packages\socks.py", line 667, in _negotiate_SOCKS4
raise SOCKS4Error("{0:#04x}: {1}".format(status, error))
socks.SOCKS4Error: 0x5b: Request rejected or failed

The answer by #pynexj is correct, but having a full working example is always nice:
import socks
import paramiko
sock=socks.socksocket()
sock.set_proxy(
proxy_type=socks.SOCKS5,
addr="proxy.host.name.example",
port=1080,
username="blubbs",
password="blabbs"
)
sock.connect(('ssh.host.name.example', 22))
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect('ignored without host key verification', username='caesar', sock=sock)
print((ssh.exec_command('ls')[1]).read().decode())
ssh.close()
(Would be nice to know if sock has to be closed separately…)

sock.connect((host, port)) should use the SSH server's hostname (the same host you use for SSHClient.connect()) and port (default 22).

Related

ConnectionRefusedError: [Errno 61] Connection refused Python3.8.5 on Mac

I'm trying to connect myself with 2 pythons little programs while using socket.
1st program:
#server.py
import socket
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = '127.0.0.1' #L'IP du Serveur
port = 1234 #data transfering port
server.bind((host,port)) #bind server
server.listen(5)
client, addr = server.accept()
print("Got Connection from",addr)
client.send("Hello World :)".encode('UTF-8')) #send data to client
msg = client.recv(1024)
print(msg.decode('UTF-8'))
input()
2nd program:
#client.py
import socket
server = socket.socket()
host = '127.0.0.1' #L'IP du Serveur
port = 1234
server.connect((host,port))
msg =server.recv(1024)
print(msg.decode('UTF-8'))
server.send('Client Online ...'.encode('UTF-8'))
input()
I first run server.py, no problems. Than, I run client.py but when I run it I have:
"
Traceback (most recent call last):
File "/Users/user/Documents/client.py", line 8, in <module>
server.connect((host,port))
ConnectionRefusedError: [Errno 61] Connection refused
>>>
"
I tried multiple things like desactivate my wall fire, put my 192.168.1.x IP but still have the same message error. I also send that to one of my friends that is on a PC (I'm on a MAC) and he has no problems. So I guess that the problem is because of the fact that I have a mac. Someone have an answer or an explanation ?
I was coding with IDLE. It was the problem. I guess that IDLE has a protection that doesn't allow people to do sockets. So I just went to Terminal and it finally works.

Python websockets server works on localhost but not on server

I made a basic chat client and server using python websockets, ran it on my pc and it worked completely fine, when I uploaded it to my windows server machine (which has the port '12345' forwarded) and tried to access it using a client from my pc I got a ConnectionRefusedError
I've tried switching to a different port (which was also forwarded) but it didn't change the result
The client (this is the bit that caused the error)
ip = input("IP Address: ")
port = int(input("Port: "))
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((ip, port))
The server
def open_socket(PORT:int, MAX_USERS:int):
new_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_address = ("localhost", PORT)
new_socket.bind(server_address)
new_socket.listen(MAX_USERS)
return new_socket
Here's the error:
Traceback (most recent call last):
File "client.py", line 24, in <module>
sock.connect((ip, port))
ConnectionRefusedError: [WinError 10061] No connection could be made because the target machine actively refused it
EDIT: After trying out Jin's answer I'm now getting a timeout error at the same place (line 24 in client.py)
EDIT #2: It is now working! I changed the port to the original one (12345) and I successfully connected to the server!
Even though you changed a port forward config in your router, you still need to check whether your server is accepting incoming traffic in the firewall setting. You can do this from Control Panel-Security or Windows Firewall (Sorry I don't remember the exact name of the menu of the Windows).
You should bind your IP with the socket, not localhost. You would want to programmatically get your IP address, rather than using hard-coded one. The followed link would help.
Finding local IP addresses using Python's stdlib

How can a Python proxy server (using SSL socket) pretend to be an HTTPS server and specify my own keys to get decrypted data?

I'm trying to handle HTTPS connections from web browsers in decrypted data using Python SSL socket. I thought I can do this like a man-in-the-middle attack via my Python proxy server program, by pretending to be an HTTPS server, and I've already generated my keys using OpenSSL. However, browser treats my program as a proxy server, not as an HTTPS server. How can my program pretend to be an HTTPS server and specify my own keys to communicate with the browser?
I'm using Chrome and a Chrome extension SwitchySharp to forward requests to another local port (HTTP to 127.0.0.1:8080, and HTTPS to 127.0.0.1:8081). It works well for HTTP requests, but doesn't work for HTTPS.
Background Knowledge
When handling HTTPS with a proxy server, the browser first sends a CONNECT request to proxy:
CONNECT xxx.xxx:443 HTTP/1.1
Host: xxx.xxx:443
Proxy-Connection: keep-alive
(some other headers)
and proxy creates a tunnel to target server, and then browser sends encrypted data via this tunnel. Therefore, the proxy server never gets decrypted data.
To get decrypted data, I've tried two ways.
First, I tried ssl.wrap_socket():
import socket
import ssl
import thread
def handle(conn):
request = conn.recv(4096)
print request
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(('127.0.0.1', 8081))
sock.listen(10)
sock = ssl.wrap_socket(sock, 'pkey.pem', 'cert.pem', True)
while True:
conn, addr = sock.accept()
thread.start_new_thread(handle, (conn,))
But I got the following error:
Traceback (most recent call last):
File "https.py", line 12, in <module>
conn, addr = sock.accept()
File "C:\Python27\lib\ssl.py", line 898, in accept
server_side=True)
File "C:\Python27\lib\ssl.py", line 369, in wrap_socket
_context=self)
File "C:\Python27\lib\ssl.py", line 617, in __init__
self.do_handshake()
File "C:\Python27\lib\ssl.py", line 846, in do_handshake
self._sslobj.do_handshake()
ssl.SSLError: [SSL: HTTPS_PROXY_REQUEST] https proxy request (_ssl.c:726)
The cause of this error is that the CONNECT request is not encrypted so ssl can't handle it. I have no idea how to get rid of this error.
Then, I tried the following code:
import socket
import thread
def handler(conn, tunn):
while True:
data = conn.recv(40960)
if data:
tunn.sendall(data)
else:
break
def handle(conn):
request = conn.recv(40960)
print request
i = request.find(' ') + 1
j = request.find(' ', i)
host, port = request[i : j].split(':')
port = int(port)
tunn = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tunn.connect((host, port))
conn.sendall('HTTP/1.1 200 Connection Established\r\n\r\n')
thread.start_new_thread(handler, (conn, tunn))
thread.start_new_thread(handler, (tunn, conn))
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(('127.0.0.1', 8081))
sock.listen(10)
while True:
conn, addr = sock.accept()
thread.start_new_thread(handle, (conn,))
It worked (without ssl module), but I can't specify my own keys and therefore can't get decrypted data.
It seems that my program has to pretend to be an HTTPS server to "directly" communicate with browser, so I can specify my own key and get decrypted data. But I really have no idea how to pretend to be an HTTPS server and specify my own keys.
Can anyone help me? Thanks in advance.
UPD: I finally solved this problem using ssl module.
I was wrong --- I thought that after connection established the browser sends encrypted data. But it doesn't. In fact, those unreadable data are just SSL handshake. So what I need to do is just to use ssl.wrap_socket() after connection established. Besides, I have to additionally call do_handshake() of the ssl-wrapped socket.
import socket
import ssl
import thread
def handle(tid, conn):
request = conn.recv(40960)
i = request.find(' ') + 1
j = request.find(' ', i)
if request[i : j].find(':') != -1:
host, port = request[i : j].split(':')
else:
host, port = request[i : j], 80
port = int(port)
tunn = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tunn.connect((host, port))
conn.sendall('HTTP/1.1 200 Connection Established\r\n\r\n')
conn_s = ssl.wrap_socket(conn, keyfile = 'cert/userkey.pem', certfile = 'cert/usercert.pem', server_side = True, do_handshake_on_connect = False)
conn_s.do_handshake()
data = conn_s.recv(40960)
print data
conn_s.sendall('HTTP/1.1 200 OK\r\n\r\n<h1>Hello, world!</h1>')
conn_s.close()
tunn.close()
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(('127.0.0.1', 8081))
sock.listen(10)
buf = {}
while True:
conn, addr = sock.accept()
thread.start_new_thread(handle, (conn,))
Anyway, it doesn't pretend to be an HTTPS server -- it still behaves as a proxy server. I just misunderstood those unreadable data.
Thanks to those who helped me in the comments.

From client connect with server with the same network

I have this code to connect with server like this:
This is file server.py
host = "192.168.0.91"
port = 5004
s = socket.socket()
s.bind((host,port))
s.listen(5)
print("Server Started.")
But when I run it, it showed me an error
File "D:/odoo11new/server.py", line 61, in Main
s.bind((host,port))
OSError: [WinError 10049] The requested address is not valid in its context
How can i fix that problem :( any suggest for me? Thanks in advance
You tried to bind the host which wasn't set up on your server.
Check host via ipconfig
Or bind any host like this:
host = "0.0.0.0"

Why am I getting the error "connection refused" in Python? (Sockets)

I'm new to Sockets, please excuse my complete lack of understanding.
I have a server script(server.py):
#!/usr/bin/python
import socket #import the socket module
s = socket.socket() #Create a socket object
host = socket.gethostname() #Get the local machine name
port = 12397 # Reserve a port for your service
s.bind((host,port)) #Bind to the port
s.listen(5) #Wait for the client connection
while True:
c,addr = s.accept() #Establish a connection with the client
print "Got connection from", addr
c.send("Thank you for connecting!")
c.close()
and client script (client.py):
#!/usr/bin/python
import socket #import socket module
s = socket.socket() #create a socket object
host = '192.168.1.94' #Host i.p
port = 12397 #Reserve a port for your service
s.connect((host,port))
print s.recv(1024)
s.close
I go to my desktop terminal and start the script by typing:
python server.py
after which, I go to my laptop terminal and start the client script:
python client.py
but I get the following error:
File "client.py", line 9, in
s.connect((host,port))
File "/usr/lib/python2.7/socket.py", line 224, in meth
return getattr(self._sock,name)(*args)
socket.error: [Errno 111] Connection refused
I've tried using different port numbers to no avail. However, I was able to get the host name using the same ip and the gethostname() method in the client script and I can ping the desktop (server).
Instead of
host = socket.gethostname() #Get the local machine name
port = 12397 # Reserve a port for your service
s.bind((host,port)) #Bind to the port
you should try
port = 12397 # Reserve a port for your service
s.bind(('', port)) #Bind to the port
so that the listening socket isn't too restricted. Maybe otherwise the listening only occurs on one interface which, in turn, isn't related with the local network.
One example could be that it only listens to 127.0.0.1, which makes connecting from a different host impossible.
This error means that for whatever reason the client cannot connect to the port on the computer running server script. This can be caused by few things, like lack of routing to the destination, but since you can ping the server, it should not be the case. The other reason might be that you have a firewall somewhere between your client and the server - it could be on server itself or on the client. Given your network addressing, I assume both server and client are on the same LAN, so there shouldn't be any router/firewall involved that could block the traffic. In this case, I'd try the following:
check if you really have that port listening on the server (this should tell you if your code does what you think it should): based on your OS, but on linux you could do something like netstat -ntulp
check from the server, if you're accepting the connections to the server: again based on your OS, but telnet LISTENING_IP LISTENING_PORT should do the job
check if you can access the port of the server from the client, but not using the code: just us the telnet (or appropriate command for your OS) from the client
and then let us know the findings.
Assume s = socket.socket()
The server can be bound by following methods:
Method 1:
host = socket.gethostname()
s.bind((host, port))
Method 2:
host = socket.gethostbyname("localhost") #Note the extra letters "by"
s.bind((host, port))
Method 3:
host = socket.gethostbyname("192.168.1.48")
s.bind((host, port))
If you do not exactly use same method on the client side, you will get the error: socket.error errno 111 connection refused.
So, you have to use on the client side exactly same method to get the host, as you do on the server. For example, in case of client, you will correspondingly use following methods:
Method 1:
host = socket.gethostname()
s.connect((host, port))
Method 2:
host = socket.gethostbyname("localhost") # Get local machine name
s.connect((host, port))
Method 3:
host = socket.gethostbyname("192.168.1.48") # Get local machine name
s.connect((host, port))
Hope that resolves the problem.
host = socket.gethostname() # Get the local machine name
port = 12397 # Reserve a port for your service
s.bind((host,port)) # Bind to the port
I think this error may related to the DNS resolution.
This sentence host = socket.gethostname() get the host name, but if the operating system can not resolve the host name to local address, you would get the error.
Linux operating system can modify the /etc/hosts file, add one line in it. It looks like below( 'hostname' is which socket.gethostname() got).
127.0.0.1 hostname
in your server.py file make : host ='192.168.1.94' instead of host = socket.gethostname()
Pay attention to change the port number. Sometimes, you need just to change the port number. I experienced that when i made changes over changes over syntax and functions.
I was being able to ping my connection but was STILL getting the 'connection refused' error. Turns out I was pinging myself! That's what the problem was.
I was getting the same problem in my code, and after thow days of search i finally found the solution, and the problem is the function socket.gethostbyname(socket.gethostname) doesnt work in linux so instead of that you have to use socket.gethostbyname('put the hostname manually') not socket.gethostbyname('localhost'), use socket.gethostbyname('host') looking with ifconfig.
try this command in terminal:
sudo ufw enable
ufw allow 12397

Categories

Resources