I am trying to build a very simplistic port scanner in order to practice with the concept of sockets. The design I have is as following:
from socket import *
ip = input("Submit IP to scan:")
start = input("Submit starting port:")
end = input("Submit ending port:")
print("Scanning IP:", ip)
for port in range(int(start),int(end)):
print("Scanning port:" + str(port) + "..")
var_socket = socket(AF_INET,SOCK_STREAM)
var_socket.settimeout(3)
if var_socket.connect_ex((ip,port)) == 0:
print("port", port, "is open")
else:
print("err code:", var_socket.connect_ex((ip,port)))
var_socket.close()
print("Scanning completed!")
This all works pretty well when I run it from a file. Unfortunately I may not always have the luxury to run my scripts from a file, so I'll need to be able to create this script in a command shell. I've made some attempts myself with tips and tricks from the internet, but they all failed in some way.
from socket import * #Press enter. Note that I am in a windows terminal.
ip = input("enter ip to scan:")\ #Press enter
start = input("enter starting port:")\ #Press enter
output:
Syntax error: Invalid syntax
The other solution I found actually worked, but brings some unwanted complexity along the way:
from socket import *
ip,start,end = map(int,input().split()) #Press enter
This solution allows me to enter 3 values seperated by a space, mapping them to ip, start and end respectively. Of course this will not work unless I design a function that manually transforms the entered ip value into a valid dotted decimal IP address. Does anyone know a better approach to ask for multiple inputs in a shell environment?
Thanks a lot in advance.
When copying your script, the python interpreter reads your code line by line, which makes it fill your input with the script you are typing.
One solution to avoid that is to read files from a different place (arguments, files, …). Or, you can also load your script in memory, then execute before asking for the inputs:
script = '''
from socket import *
ip = input("Submit IP to scan:")
start = input("Submit starting port:")
end = input("Submit ending port:")
print("Scanning IP:", ip)
for port in range(int(start),int(end)):
print("Scanning port:" + str(port) + "..")
var_socket = socket(AF_INET,SOCK_STREAM)
var_socket.settimeout(3)
if var_socket.connect_ex((ip,port)) == 0:
print("port", port, "is open")
else:
print("err code:", var_socket.connect_ex((ip,port)))
var_socket.close()
print("Scanning completed!")
'''
exec(script)
Related
I'm brand new to Python (as of last week) and I'm still getting to grips with the basics so please excuse any ignorance I display.
As part of my homework I have been asked to make a basic port scanner and one of the functions I have to include is the retrieval of a list of sockets on the current machine. I have been looking around and managed to piece together a piece of code that allows me to enter the IP of the machine I wish to scan but I want to try and make it so it automatically scans whichever machine it is running on.
elif (userChoice == "4"):
print("You selected " + userChoice)
try:
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM) # s will be equal to the command looking for the IPV4 addresses
except socket.error:
sys.exit("Failed to create socket.") # error handling message to be printed to the console should a socket failed to be created
print("Socket created")
hostAddress = input("Please enter host address to scan - example 'www.server.com': ")
print ("You entered " + hostAddress )
try:
remoteIP = socket.gethostbyname(hostAddress)
except socket.gaierror:
sys.exit("Hostname could not be resolved exiting")
ret = input("Hit return to go back to the menu")
continue
print("IP address of " + hostAddress + ' is ' + remoteIP)
This is my code so far. If anyone could help me out or tell me if I'm even going in the right direction with this I would be very grateful.
Also, with me being a noob, if anyone has any suggestions for good reading materials to help me get to get to grips with the basics I would very much appreciate it.
Thanks.
To check open ports on remote server-
# For input hostAddress
remoteIP = socket.gethostbyname(hostAddress)
for port in range(1,1025):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
result = sock.connect_ex((remoteIP, port))
if result == 0:
print("Port %s: Open"%port)
sock.close()
=> Port 80: Open
I am trying to create a port scanner in Python. I got the scanner going but it takes forty five minutes to print results. I started to institute threading however I can't figure out how to put different ranges into the script. I started to go to creating a global variable and try to pass that along in each thread. Unfortunately it's not working correctly and I am getting an invalid syntax error. Below is the code.
import socket
import os
import sys
from threading import Thread
server = raw_input("Please enter a server name ")
def portConnect():
global num
try:
serv_ip = socket.gethostbyname(server) # connects to server through try
print "Please wait, scanning remote host", serv_ip
for port in range(num):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connect = sock.connect_ex((serv_ip, port))
if connect == 0:
print "Port {}: Open".format(port)
sock.close()
except socket.gaierror:
print """
I can't find that server, idiot! Try again
"""
sys.exit()
for i in range(1):
t = Thread(target=portConnect,(num=100))
t.start()
What am I doing wrong?
Thread expects args= as tuple and it sends it as arguments to function
This way you send 100 as first argument (num) to portConnect()
def portConnect(num):
print(num)
# code
t = Thread(target=portConnect, args=(100,) )
To send range you need two arguments
def portConnect(from_, to_):
print(from_, to_)
for port in range(from_, to_):
# ...
size = 20
for i in range(1, 100, size):
t = Thread(target=portConnect, args=(i, i+size))
t.start()
BTW: module scapy lets you send single packet so it is used for portscanning, sniffing, etc.
You can do more with special tools like nmap (GUI wrapper: Zenmap) or Kali Linux
You may try to use nmap in Python: python-nmap : nmap from python
you can solve this really easily using nmap.
nmap -p- <some_host>
So I have a network scanner, but its not working. It's showing that every ip on the network from 127.0.0.1 to 127.0.0.254 is down. I know for sure that's not the case. Does anyone know what the problem is?
import socket, ping
from struct import unpack, pack
my_ip = socket.gethostbyname(socket.gethostname())
print "My computer IP address:", my_ip
my_deets = socket.gethostbyname_ex(socket.gethostname())
print "My computer details:", my_deets
subnet_mask = "255.255.255.0"
def ip2long(ip):
"""7
Convert an IP string to long
"""
return unpack(">L", socket.inet_aton(ip))[0]
def long2ip(ip):
"""
Convert a long to IP string
"""
return socket.inet_ntoa(pack('!L', ip))
# Applying the subnet mask to IP
addr = ip2long(my_ip)
mask = ip2long("255.255.255.0")
prefix = addr & mask
print "Base address for network", long2ip(prefix)
# Get the number of possible computers on our network
all_computers = ip2long("255.255.255.255")
num_computers = all_computers ^ mask
# Go through each computer
for ip_suffix in range(num_computers):
# Try to ping a computer on the network
test_ip = long2ip(prefix + ip_suffix)
try:
print "[*] Checking to see if host is up..."
timeout = ping.do_one(test_ip, 1)
print timeout
if timeout != None:
print "[+] Host is there:", test_ip
print "-"*100
except socket.error, e:
print "[-] Host not there:", test_ip
Your script does work (and it's kind of fun, though I'll prefer nmap ;) ).
However
do_one takes a third argument, psize don't know how it works on your side.
You need to be root (e.g. administrator). And your script mixes up the "failure" and "host down" cases. When a host is down, the function will return None. When an error occurs, it means that the ping could not be sent. So the fact that "It's showing that every ip on the network from 127.0.0.1 to 127.0.0.254 is down", means actually that no packets could be sent.
127.0.0.1 is the loopback interface. There will be no other computer than yours on that network. The fact that socket.gethostbyname(socket.gethostname()) returns that address could mean that your network is improperly set. In some old days, the 127.0.0.1 address was hardlinked to the localhost hostname in the /etc/hosts file in order for some badly written programs (like Gnome apps at that time), who would wait for the IP associated with the hostname to respond or timeout before continuing with the start up, leading to extremely long delay to start the application each time the computer wasn't connected to any network. That workaround is no longer necessary IIRC.
I am trying to talk to a Stanford Research Systems SR760 spectrum analyzer on my mac (10.7.5) via Serial, using a Serial-to-USB adapter to connect to my laptop. I am using the Prolific USB-serial driver. Not sure which but I installed it recently. It probably is the PL2303 one.
Using Python, here's some sample code
import time
import serial
# configure the serial connections (the parameters differs on the device you
# are connecting to)
ser = serial.Serial(
port='/dev/cu.PL2303-0000201A',
baudrate=19200,
parity=serial.PARITY_NONE,
bytesize=serial.EIGHTBITS,
stopbits=serial.STOPBITS_ONE,
rtscts=0,
dsrdtr=0,
timeout=2,
)
if ser.isOpen():
ser.flushInput()
ser.flushOutput()
print """Enter your commands below.\r\nInsert "exit" to leave the
application."""
while 1:
# get keyboard input
input = raw_input(">> ")
if input == 'exit':
ser.close()
exit()
else:
ser.write(input + '\r')
out = ''
# let's wait one second before reading output (let's give device
# time to answer)
lines = 0
while 1:
time.sleep(1)
out = out + ser.readline()
lines = lines + 1
if lines > 5:
break
print "read data: " + out
Using the SR760's manual, I send it: *IDN?, a basic "identify" command. I expect for something to pop up in my terminal, nothing does. It just times out. However, if I look at the send queue on the SR760, it will show the identity string, and in fact responds to a bunch of different commands. I'm just not getting anything on my computer and that is the problem. I know it is supposed to work that way because my colleague wrote code that words on his computer (a windows laptop).
How do I even start debugging this? I've tweaked the timeout, and confirmed the sr760 had the same parameters I was expecting.
I made a simple TCP fuzzer in Python. I need it to be able to receive some response and if I didn't get the response, break the loop. My code is this:
import socket
from time import sleep
import sys
ip = raw_input ("please insert host ip: ")
port = input ("please insert port to fuzz: ")
packet = raw_input ("what string would you like to fuzz with? : ")
multi = input ("in what jumps would you liike to multiply the string ? (10 = A*10) : ")
host = ip, port
s = socket.socket()
char = packet * multi
a = 1
try:
while a > 0:
s.connect((host))
s.send(packet)
sleep(1)
print 'fuzzing param %s' % (packet)
packet = char + packet
s.close()
except (Exception):
print "Connection lost for some reason"'
But when I run the program I get this error:
please insert host ip: 10.0.0.138
please insert port to fuzz: 80
what string would you like to fuzz with? : A
in what jumps would you liike to multiply the string ? (10 = A*10) : 2
fuzzing param A
Connection lost
which is weird because it just suppose to reconnect in an endless loop , (i know the server didn't crush)
The remote endpoint simply hung up, probably because the data you send doesn't match the format it expects.
You can either create a new connection every time the remote end hangs up, or send a data in the format that the remote end expects. For example, if the remote end is an HTTP server, you may want to send the request line first, and then the fuzzed part, like this:
GET / HTTP/1.0
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
When you fuzz testing (and in general) it is very important to handle errors. You should expect that something will get wrong when you are sending Gibberish to your server. So I suggest that you wrap the calls with try ... except ... finally: s.close() clause. And print debug messages to see when you are fail to send and start see why - You don't know how the server react to what you send, and you might just have killed the server after the first call...