I'm trying to code a port scanner in python with banner grabbing.
Without the s.send('getBanner\n') line (which grabs the banner) my script works, and it prints the open ports.
But when I add the 'getBanner' line, a socket error says '[Errn 32] Broken Pipe'.
I know that this error probably happens because the clients don't wait till the connection get established and close the socket. How can I solve this?
The code:
import socket
host = '192.168.1.1'
for port in range(1,1024):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
result = s.connect_ex((host, port))
s.send(('getBanner\n'))
banner = s.recv(1024)
if result == 0:
print "[+] Port %s tcp/open" % port
print "[+] Banner: %s" % banner
s.close()
Not all ports have a service listening on them and when they do, you need to follow whatever protocol is normal for that service. I assume you have some sort of service that responds to "getBanner", but most will not. You are connecting to things like FTP, SSH, DNS, NFS and mail servers and these things don't have "getBanner" commands. But you are also trying to connect to ports that don't have anything listening on them and this generates an error.
Looking at the docs:
connect_ex(...)
connect_ex(address) -> errno
This is like connect(address), but returns an error code (the errno value)
instead of raising an exception when an error occurs.
Your connection call is returning an error code and you need to check that before trying to send the request. So, as a minimum:
import socket
host = '192.168.1.1'
for port in range(1,1024):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
result = s.connect_ex((host, port))
if result == 0:
s.send(('getBanner\n'))
banner = s.recv(1024)
if result == 0:
print "[+] Port %s tcp/open" % port
print "[+] Banner: %s" % banner
s.close()
But since most servers listening on ports don't respond to a "getBanner" command, its either going to hang or more likely raise connection reset errors.
Related
I'm reading about socket module in a web learning site about python, they gave us a simple steps to use socket module like follows:
import socket
with socket.socket() as client_socket:
hostname = '127.0.0.1'
port = 9090
address = (hostname, port)
client_socket.connect(address)
data = 'Wake up, Neo'
data = data.encode()
client_socket.send(data)
response = client_socket.recv(1024)
response = response.decode()
print(response)
when executing I got the error message:
ConnectionRefusedError: [WinError 10061] No connection could be made because the target machine actively refused it.
when I searched about this some sites was talking about server listening and I see in most of tutorials about server socket and they use it along with client one.
so Is the error message related to the fact that I'm not using a server socket and is it a must to use them both
Update:
after reading the answers I got, I went to the test.py file that the course instructors use to evaluate our codes and I see that they make the server socket in it , so the server is already made by them. that take me back to the Error I got why does it happen then.
def server(self):
'''function - creating a server and answering clients'''
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.sock.bind(('localhost', 9090))
self.ready = True
try:
self.sock.listen(1)
conn, addr = self.sock.accept()
self.connected = True
conn.settimeout(15)
while True:
data = conn.recv(1024)
self.message.append(data.decode('utf8'))
if len(self.message) > 1_000_000:
conn.send(
json.dumps({
'result': 'Too many attempts to connect!'
}).encode('utf8'))
break
if not data:
break
Each connection requires a client, which initiates the connection, and a server, which listens for the incoming connection from the client. The code you have shown is for the client end of the connection. In order for this to run successfully you will need a server listening for the connection you are trying to create.
In the code you showed us you have the lines
hostname = '127.0.0.1'
port = 9090
address = (hostname, port)
client_socket.connect(address)
These are the lines that define what server you are connecting to. In this case it is a server at 127.0.0.1 (which is localhost, the same machine you are running the code on) listening on port 9090.
If you want to make your own server then you can look at the documentation for Python sockets and the particular functions you want to know about are bind, listen, and accept. You can find examples at the bottom of that same page.
Given that you appear to have found this code as part of a course, I suspect they may provide you with matching server code at some point in order to be able to use this example.
I've written two programs according to a guide on sockets in python.
I'm using a rasbperry pi 3 as a client, and a regular linux ubuntu computer as a server. this is the server software:
import socket
import sys
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_address = ('localhost', 15000)
print("starting up on %s port %s" % server_address, file=sys.stderr)
sock.bind(server_address)
# Listen for incoming connections
sock.listen(1)
while True:
# Wait for a connection
print("waiting for a connection", file=sys.stderr)
connection, client_address = sock.accept()
try:
print("connection from ", client_address, file=sys.stderr)
# Receive the data in small chunks and retransmit it
while True:
data = connection.recv(16)
print("received %s" % data, file=sys.stderr)
if data:
print("sending data back to the client", file=sys.stderr)
connection.sendall(data)
else:
print("no more data from ", client_address, file=sys.stderr)
break
finally:
# Clean up the connection
connection.close()
and this is the client software:
import socket
import sys
# Create a TCP/IP socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# Connect the socket to the port where the server is listening
server_address = ('192.168.18.250', 15000)
print("connecting to %s port %s" % server_address, file=sys.stderr)
sock.connect(server_address)
try:
# Send data
message = "This is the message. It will be repeated."
print("sending %s" % message, file=sys.stderr)
sock.sendall(message)
# Look for the response
amount_received = 0
amount_expected = len(message)
while amount_received < amount_expected:
data = sock.recv(16)
amount_received += len(data)
print("received %s" % data, file=sys.stderr)
finally:
print("closing socket")
sock.close()
this is the output on the server:
peter#GIGAS:~/thermServer$ python3 thermServer.py
starting up on localhost port 15000
waiting for a connection
and this is the output on the raspberry pi:
pi#raspberrypi:~ $ python3 thermClient.py
connecting to 192.168.18.250 port 15000
Traceback (most recent call last):
File "thermClient.py", line 10, in <module>
sock.connect(server_address)
ConnectionRefusedError: [Errno 111] Connection refused
I have forwarded the port in my router, but as this is internal traffic that shouldn't matter, did I miss adding something in the server that opens the port properly or do I need to fiddle with something outside of the project in my linux machine?
In your server code you have:
server_address = ('localhost', 15000)
This sets up a listener on ipnumer 127.0.0.1. This 'localhost' ip cannot be contacted from clients outside of this server.
If you want your server to listen on all assigned ip-adresses, use:
server_address = ('0.0.0.0', 15000)
When you create a socket, bound to the localhost address, you create a socket listening on the "loopback interface", i.e. 127.0.0.1. You appear to be trying to connect to the server by the local IP - 192.168.18.250, which is assigned to a different interface (generally the one connected to your LAN). Because nothing is listening to port 15000 on that interface you get a connection refused.
You have two solutions here: either change the server to be listening to the correct interface (listening to 0.0.0.0 generally works here, although if it's a guaranteed static IP, use that instead), or change the client to try to connect to the loopback interface - try connect on 127.0.0.1 or "localhost"
Ive seen similar questions but they I couldn't fix this error. Me and my friend are making a chat program but we keep getting the error
ConnectionRefusedError: [Errno 61] Connection refused
We are on different networks by the way.
Here is my code for the server
import socket
def socket_create():
try:
global host
global port
global s
host = ''
port = 9999
s = socket.socket()
except socket.error as msg:
print("Socket creation error" + str(msg))
#Wait for client, Connect socket and port
def socket_bind():
try:
global host
global port
global s
print("Binding socket to port: " + str(port))
s.bind((host, port))
s.listen(5)
except socket.error as msg:
print("Socket binding error" + str(msg) + "\n" + "Retrying...")
socket_bind
#Accept connections (Establishes connection with client) socket has to be listining
def socket_accept():
conn, address = s.accept()
print("Connection is established |" + " IP:" + str(address[0]) + "| port:" + str(address[1]))
chat_send(conn)
def chat_send(conn):
while True:
chat =input()
if len(str.encode(chat)) > 0:
conn.send(str.encode(chat))
client_response = str(conn.recv(1024), "utf-8")
print(client_response)
def main():
socket_create()
socket_bind()
socket_accept()
main()
And my client code
import socket
#connects to server
s = socket.socket()
host = '127.0.0.1'
port = 9999
s.connect((host, port))
#gets chat
while True:
data = s.recv(1024)
print (data[:].decode("utf-8"))
chat = input()
s.send(str.encode(chat))
This may not answer your original question, but I encountered this error and it was simply that I had not starting the server process first to listen to localhost (127.0.0.1) on the port I chose to test on. In order for the client to connect to localhost, a server must be listening on localhost.
'127.0.0.1' means local computer - so client connents with server on the same computer. Client have to use IP from server - like 192.168.0.1.
Check on server:
on Windows (in cmd.exe)
ipconfig
on Linux (in console)
ifconfig
But if you are in different networks then it may not work. ipconfig/ifconfig returns local IP (like 192.168.0.1) which is visible only in local network. Then you may need external IP and setting (redirections) on your and provider routers. External IP can be IP of your router or provider router. You can see your external IP when you visit pages like this http://httpbin.org/ip . But it can still need some work nad it be bigger problem.
You need simply to start server at first, and then run the client_code.
In VS Code i've opened 2 terminals. One for the server_code to be running While True, and the other one for the client_code
So this may not fix your question specifically but it fixed mine and it can help someone else I work with vscode and I use some extension that runs my code so when you want to run your server run it on your CMD or Terminal and run your client in vscode it helped me (maybe importat I work on mac so maybe spesific OS problem)
If you are connecting to a host:port that is open but there is no service bound to it you may see this IIRC. Eg with ssh you sometimes see this while attempting to connect to a server that is booting but sshd is not running.
This Code Not Valid For Chatting, you have to use unblocking sockets and select module or other async modules
i'm new to python programming and here is a fisrt code i've done
so,here is a port scanner i've done , it works fine on localhost ,
but when i try to scan a website , after waiting 10 minutes there is nothing
what is wrong with my code.
here is the code:
from socket import *
print "Simple port scanner"
print "-------------------"
print ""
adress = raw_input("Enter adress (or localhost): ")
ip = gethostbyname(adress)
print adress,"has the IP:",ip
alpha = int(raw_input("Port (min):"))
omega = int(raw_input("Port (max):"))
def scanner(ip,min_port, max_port):
count = 0
for ports in range(alpha, omega):
s = socket(AF_INET, SOCK_STREAM)
result = s.connect_ex((ip, ports))
if(result == 0) :
print 'Port %d: is OPEN' % (ports,)
count = count + 1
s.close()
print "Scanning finshed !"
print ""
print "Found",count,"open ports"
print ""
print "Beggin to scan..."
scanner(ip,alpha,omega)
Here is the output for localhost:
Simple port scanner
-------------------
Enter adress (or localhost): localhost
localhost has the IP: 127.0.0.1
Port (min):0
Port (max):100
Beggin to scan...
Port XX: is OPEN
Port XX: is OPEN
Scanning finshed !
Found 2 open ports
and the output for google (for example)
and there is the problem , there is NOTHING :(
Simple port scanner
-------------------
Enter adress (or localhost): google.com
google.com has the IP: 74.125.195.100
Port (min):24
Port (max):82
Beggin to scan...
Thank you for helping me .
thank you for your answer Lawrence Benson ,
i have try it with some othe IP's (no more google , but my website and friend website to stay legal) but same error , have you an idea to improve this script ?
If you change s.connect_ex() to s.connect(), an Execption will be raised if an error occurs. connect_ex returns a error value which needs to be interpreted. There are many errors, e.g. timeout or connection refused.
If I test it on my server, many ports are actively refused. So if I print
print "Port %d is closed" % ports
I can see that all ports are refused.
The best approach would be to go through the error messages you get with connect() and find out how to handle those, especially because you are new to python.
Additionally, you can set a timeout after which your socket gives up on trying to connect.
s.settimeout(3)
Thank you,
I have made some changes and now it works :) I have changed ".connect_ex" to ".connect", add try/except, and two settimeouts.
Here is the code again (modified):
from socket import *
print "Simple port scanner"
print "-------------------"
print ""
adress = raw_input("Enter adress (or localhost): ")
ip = gethostbyname(adress)
print adress,"has the IP:",ip
alpha = int(raw_input("Port (min):"))
omega = int(raw_input("Port (max):"))
def scanner(ip,alpha, omega):
count = 0
for ports in range(alpha, omega):
try:
print "Scanning port :%d" % (ports,)
s = socket(AF_INET, SOCK_STREAM)
s.settimeout(3)
s.connect((ip, ports))
s.settimeout(3)
print "Port %d: is OPEN" % (ports,)
count = count + 1
except:
print "Port %d is CLOSED" % (ports,)
s.close()
print "Scanning finshed !"
print ""
print "Found %d open ports" % (count)
print ""
print "Beggin to scan..."
scanner(ip,alpha,omega)
And the output:
Enter adress (or localhost): xxx.xxx.org
xxx.xxx.org has the IP: xx.xx.xx.xx
Port (min):440
Port (max):445
Beggin to scan...
Scanning port :440
Port 440 is CLOSED
Scanning port :441
Port 441 is CLOSED
Scanning port :442
Port 442 is CLOSED
Scanning port :443
Port 443: is OPEN
Scanning port :444
Port 444 is CLOSED
Scanning finshed !
Found 1 open ports
I would suggest having a function to check the state of a port.
#-*-coding:utf8;-*-
#qpy:3
#qpy:console
import socket
import os
# This is used to set a default timeout on socket
# objects.
DEFAULT_TIMEOUT = 0.5
# This is used for checking if a call to socket.connect_ex
# was successful.
SUCCESS = 0
def check_port(*host_port, timeout=DEFAULT_TIMEOUT):
''' Try to connect to a specified host on a specified port.
If the connection takes longer then the TIMEOUT we set we assume
the host is down. If the connection is a success we can safely assume
the host is up and listing on port x. If the connection fails for any
other reason we assume the host is down and the port is closed.'''
# Create and configure the socket.
sock = socket.socket()
sock.settimeout(timeout)
# the SO_REUSEADDR flag tells the kernel to reuse a local
# socket in TIME_WAIT state, without waiting for its natural
# timeout to expire.
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
# Like connect(address), but return an error indicator instead
# of raising an exception for errors returned by the C-level connect()
# call (other problems, such as “host not found,” can still raise exceptions).
# The error indicator is 0 if the operation succeeded, otherwise the value of
# the errnovariable. This is useful to support, for example, asynchronous connects.
connected = sock.connect_ex(host_port) is SUCCESS
# Mark the socket closed.
# The underlying system resource (e.g. a file descriptor)
# is also closed when all file objects from makefile() are closed.
# Once that happens, all future operations on the socket object will fail.
# The remote end will receive no more data (after queued data is flushed).
sock.close()
# return True if port is open or False if port is closed.
return connected
con = check_port('www.google.com', 83)
print(con)
I keep getting this error
[Errno 10061] No connection could be made because the target machine actively refused it.
I'm running Windows 7 64 bit, no virus or protection software, and python is allowed through my firewall (I've also tried turning my firewall completely off but same result). When I run the server and use telnet it connects just fine. When I try to connect to the server with the client it fails. Any suggestions as to what I could try to fix this? If you need more information just ask and I'll provide.
Client Code
import socket
import sys
def main():
host = ""
port = 8934
message = "Hello World!"
host = raw_input("Enter IP: ")
#Create Socket
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
except socket.error, msg:
print "Failed to create socket. Error code: %s Error Message: %s"%(str(msg[0]),msg[1])
sys.exit()
print "Socket created"
#Connec to Server
print host
print port
s.connect((host,port))
print "You are connected to %s with IP adress of %s"%(host,host)
#Send Data
try:
s.sendall(message)
except socket.error:
print "Failed to send."
#Receive Data
reply = s.recv(4096)
if __name__ == "__main__":
main()
Server Code
# !usr/bin/python
import socket
import sys
HOST = ""
PORT = 8934
def main():
#Setup socket
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
except socket.error,msg:
print "Unable to create socket"
sys.exit()
print "Socket created."
#Bind to adress
try:
s.bind((HOST,PORT))
except socket.error,msg:
print "Bind failed. Closing..."
sys.exit()
print "Socket bound."
#Start listening
s.listen(10)
print "Socket Listening"
#Accept connection
conn, addr = s.accept()
print "Connected to %s:%s"%(addr[0],addr[1])
if __name__ == "__main__":
main()
Taking a guess at your indentation, and running your code… it works just fine.* (As long as I type in 127.0.0.1 when it asks me for the IP.)
Of course the second time I run the client (if I haven't restarted the server) I get a connection-refused error. But that's just because you've coded a server that immediately quits as soon as it gets the first connection. So the second time you run the client, there is no server, so the OS rejects the connection.
You can always run the server again, which lets you run the client one more time. (Except that the server may get a 10048 error when it tries to bind the socket, because the OS is keeping it around for the previous owner. If you see that, look at SO_REUSEADDR in the docs.)
* By "works just fine" I mean that it connects, and prints out the following before quitting:
Socket created
127.0.0.1
8934
You are connected to 127.0.0.1 with IP adress of 127.0.0.1
Obviously it never sends anything to the server or receives anything back, because the server has no send or recv calls, or anything else.