Iterate through subnet and run portscan function - python

I'm trying to write a python program that will ping sweep a given network (192.168.0.0/24) for example. And then store the alive hosts in an array. From that array, I want to port scan them using a function I wrote. However, I have no idea what I'm doing wrong.
Here is a condensed version of the script not using the alive hosts, just the entire subnet (its the same idea):
#!/usr/bin/env python
import socket
import ipaddress
def portscan(host):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
for port in range(75,85):
result = sock.connect_ex((host, port))
if result == 0: #the error indictator returns 0 if the operation succeeds.
print "port ",port," is open on ", host
# else:
# print "port ",port," is closed"
sock.close()
logging.debug(i)
except:
print "no connection on port",port, "from host",host
def main():
subnet = ipaddress.ip_network(u'192.168.0.0/29')
for i in subnet:
print i
portscan(i)
if __name__ == "__main__":
main()
The above just returns:
192.168.0.0
no connection on port 75 from host 192.168.0.0
192.168.0.1
no connection on port 75 from host 192.168.0.1
192.168.0.2
no connection on port 75 from host 192.168.0.2
192.168.0.3
no connection on port 75 from host 192.168.0.3
192.168.0.4
no connection on port 75 from host 192.168.0.4
192.168.0.5
no connection on port 75 from host 192.168.0.5
192.168.0.6
no connection on port 75 from host 192.168.0.6
192.168.0.7
no connection on port 75 from host 192.168.0.7
[Finished in 0.0s]
I've also wrote a script that runs a portscan on one specific host, and it works totally fine:
#!/usr/bin/env python
import socket
import sys
server = '192.168.0.1'
def portscanner():
try:
for port in range(1,445):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
result = sock.connect_ex((server, port))
if result == 0: #the error indictator returns 0 if the operation succeeds.
print "port",port," is open on",server
# else:
# print "port ",port," is closed"
sock.close()
except KeyboardInterrupt:
print " CTRL+C Interruption. Exiting..."
sys.exit()
portscanner()
the hard coded ip returns:
port 80 is open on 192.168.0.1
port 443 is open on 192.168.0.1
[Finished in 20.3s]
I've wrote so many different variations off this to get it to work. But I'm consistently getting it wrong!
I'm also very new to Python, so be gentle!
TL;DR:
iterate through a bunch of IP addresses and call a portscan function on each IP address.

try:
for port in range(75,85):
Your for loop is inside the try block -- as soon as one of the connection attempts fails, it jumps directly to the except clause and skips all of the other ports in the loop. Since most systems won't have port 75 open, this will make the "scan" fail.
Move the for loop outside the try, like you have it in your other script.

Related

How to connect a "client" socket on any network in the world to my "socket server"

I made a socket to see how it works.
Basically my intention for testing was to run commands in client computer cmd
First I made the server to receive a connection from my other script client
import socket
HOST = '192.168.100.xx' #my computer ipv4
PORT = 50000
server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
server.bind((HOST,PORT))
server.listen(5)
print('Server waiting connection...')
conn,addr = server.accept()
print('Connection established!')
print('Connected in addr: {}\n'.format(addr))
while True:
cmd = str(input('command>'))
conn.send(str.encode(cmd))
response = str(conn.recv(1024),"utf-8")
print(response)
if cmd == 'quit':
break
server.close()
Then I made the client:
import socket
import subprocess
import os
HOST = '192.168.100.xx' #ipv4 from my computer (server)
PORT = 50000
client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
client.connect((HOST,PORT))
print('Connecting to the server {}'.format(HOST))
while True:
command = client.recv(1024).decode()
print('Server command>'+command)
cmd = subprocess.Popen(args=command,shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
output = (cmd.stdout.read() + cmd.stderr.read()).decode("utf-8", errors="ignore")
client.send(str.encode(str(output)+ str(os.getcwd()) +'$'))
Here's how I get my IPv4 address:
Initially when I tested it on a machine on my network this worked fine, but when I sent the client to a friend far away to run it, it didn't work.
I would like to know what I do to be able to use my socket server to connect with socket client in any corner of the world.
You are using a local ip which allows people connected only to your router connect.
So you need to use your public ip address. (Click Here to check your IP)
Open a port in your router. for example: 1234.
Dont know how? See this video.
Want to learn about it? See this video.
Once you do that, change the port in your code to the port you opened on the router page.
and then change the ip in the client code to your public ip.
Now your friend should be able to connect to your server.
(also you need to have static ip and not dynamic ip)

How could we establish connection between server and client through socket programming(Python) with server and client on different networks?

How could we establish connection between server and client through socket programming(Python) with server and client on different devices and on different networks? When we create socket with i/p addr and port
of server, server and client gets connected if both devices are connected on same network. But this is not the case with different networks. What needs to be done to connect them?
import socket
def server_program():
host = socket.gethostname()
port = 5000
server_socket = socket.socket()
server_socket.bind((host, port))
server_socket.listen(2)
conn, address = server_socket.accept()
print("Connection from: " + str(address))
while True:
data = conn.recv(1024).decode()
if not data:
break
print("from connected user: " + str(data))
data = input(' -> ')
conn.send(data.encode())
conn.close()
if __name__ == '__main__':
server_program()
import socket
def client_program():
host = socket.gethostname() // used ngrok i/p here
port = 5000 // used ngrok port no
client_socket = socket.socket()
client_socket.connect((host, port))
message = input(" -> ")
while message.lower().strip() != 'bye':
client_socket.send(message.encode())
data = client_socket.recv(1024).decode()
print('Received from server: ' + data)
message = input(" -> ")
client_socket.close()
if __name__ == '__main__':
client_program()
To establish a connection between server and client on different networks you either need to use port forwarding or you can take help of some external software like ngrok
How do you use ngrok ?
First of all you need to sign up.
Download the ngrok software
Now you would get a screen like this
Copy the line ./ ngrok authtoken .........
Open up cmd and cd into the folder where you've downloaded ngrok
Paste the copied commmand (Note- If you're on windows remove the ./ from starting of the command) and hit enter
Enter the following command
ngrok tcp [Port on which your server is listening]
For example - If your server is listening on port 65432 then you'd have to enter the following command
ngrok tcp 65432
You should now be seeing a window like this
Copy the x.tcp.ngrok...... from the window (highlited in the image above)
Open up cmd and type ping [copied text here]
The output should be something like this :
Pinging x.tcp.ngrok...... [ip here] with 32 bytes of data:
....
....
....
Copy the ip
Now in your client.py file replace the ip with the ip you copied
Copy the port from the ngrok window (Next to the highlighted text in the image above, in my case it's 11171)
Replace the port in client.py file with the port you copied
In server.py change the host to "0.0.0.0"
You're all set to go now! Clients can now connect to your server from all over the globe

Python port scanner marks every port as closed when using for loop and range function

I am trying to make a simple Python port scanner script, connect to IP and port/s, if connection is successful, the port should be marked as open.
I have tried to omit the for loop and the range function, using the port number explicitly and it works, but for some reason it does not like the iteration thing, also tried to use connect_ex function and did not work.
server.py
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(("127.0.0.1", 1200))
s.listen(600)
print("Waiting for connections...")
while 1:
clientsocket, address = s.accept()
print(f"Connection from {address} has been established!")
clientsocket.send(bytes("Welcome to the server!","utf-8"))
portScanner.py
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
for port in range(1000,1400):
try:
s.settimeout(3)
connection = s.connect(("127.0.0.1",port))
print(f"Port {port} is open!")
except:
print(f"Port {port} is closed.")
s.close()
I expect the output to be "Port 1200 is open!" among the lines of Port xxxx is closed., but the actual output is all the ports are marked as closed.
I believe the issue lies in the fact that you're trying to use the same socket for each connection. I'm able to reproduce your issue on a mac, though the issue might be platform dependent as the socket library calls the OS directly.
In your code the first exception thrown is [Errno 61] Connection refused and then everything after is [Errno 22] Invalid argument, so there is something in the state of the socket that is causing all other connection attempts to fail. Note that you're not calling s.close() in a finally block in the loop which you should be doing, but even doing that will give you a [Errno 9] Bad file descriptor error.
In any event, I was able to get this to work by creating a new socket for each connect attempt and properly closing it with a with block:
for port in range(1000, 1400):
try:
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.settimeout(3)
connection = s.connect(("127.0.0.1", port))
print(f"Port {port} is open!")
except:
print(f"Port {port} is closed.")

python - print out ports with their names

I have the following code written in 2.7 python:
#...import stuff
remoteServer = raw_input("Enter a remote host to scan: ")
remoteServerIP = socket.gethostbyname(remoteServer)
print "Please wait, scanning remote Host", remoteServerIP
try:
for port in xrange(1, 1024):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
result = sock.connect_ex((remoteServerIP, port))
if result == 0:
print "port {}: open".format(port)
sock.close
except KeyboardInterrupt:
print "\nexiting..."
sys.exit()
Output:
Enter a remote host to scan: www.myexamplesite.com
Please wait, scanning remote Host xxx.xxx.xx.xx
port 21: open
port 22: open
...
But the problem is that I also want to know which ports are used and for what they are used just like:
#... as usual
port 1 httpserver
port 2 chat server
...
but this is only printing the ports from 1 to 1024
is there a function/way to do this?
socket.getservbyport() will translate port numbers into the service expected to be running on that port (via /etc/services), but won't actually communicate over the port to find out what is really running.

Python socket not accepting port as variable from api

I am running a socket script to wait for a connection using a port number from an api response
SELENIUMPORT = cont["Ports"][0]["PublicPort"]
I am converting it to an int using a function then I'm passing it to socket but it errors with
client.connect(('192.168.33.10',SELENIUMPORT))
socket.error: [Errno 111] Connection refused
ECONNREFUSED (111)
Connection refused. This error can occur during an attempt to connect a TCP socket. It is reported when a reset or an unexpected SYNC message is received.
I pretty sure that you are going to have to put that in try loop and wait for the other end to be listening.
Edit:
From your comments you are going to have to print out the SELENIUMPORT at the same time that you have that port number from the program that is supposedly listening to check that they are identical each time.
Arguably, testing by adding let's say 10 to the port number should give you an identical error, ie nothing is listening on the other end.
Short of that, create a script that does listen on a given port and test against that i.e.
import os, socket, time
address = ('localhost',32840)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(address)
s.listen(1)
sc, client_address = s.accept()
while True:
print ("Connection made ", client_address)
n = 1
try:
data_recv = sc.recv(4096)
if len(data_recv) > 0:
print ("Received ", data_recv,n)
except:
print ("Disconnect")
break
Try running that and get your connection challenged code to connect to it or run something like:
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
address = ('localhost',32840)
s.connect(address)
s.sendall('mystuff')

Categories