I need to scan every host on a network to see if they are hosting a webserver on port 80 using python. I wrote a script to do this, but it's mind bogglingly inefficient. Are there any modules or libraries that can more efficiently do this task
def scanhosts():
for ifaceName in interfaces():
addresses = [i['addr'] for i in ifaddresses(ifaceName).setdefault(AF_INET, [{'addr':'No IP addr'}] )]
if ifaceName == "wlan0":
return ', '.join(addresses)
def scanlooper(subnet):
for i in range(0,1):
for x in range(0,999):
s = "%s.%s.%s" % (subnet,i,x)
request = urllib2.Request('http://%s/' % s)
try:
response = urllib2.urlopen(request)
html = response.read()
if html != "False":
print "%s is hosting a server" % s
except:
print "%s is not hosting a server" % s
localip = scanhosts()
ipstrip = localip.strip(".")
subnet = "%s.%s" % (ipstrip[0],ipstrip[1])
scanlooper(subnet)
Obviously there is a better way of performing this task, downloading a page from 1'000'000 potential hosts can hardly be efficient.
Thanks
Check out the python bindings for nmap
Related
This is my code it's just starting the scan but it is not completing ,where is the error in it. i need output as port number and port side by side.when i run in command prompt it gives like that,please give suggetions on that
from socket import *
import sys,time
from datetime import datetime
host =''
max_port=100
min_port=1
def scan_host(host,port,r_code=1):
try:
s=socket(AF_INET,SOCK_STREAM)
code=s.connect_ex((host,port))
if code==0:
r_code=code
s.close()
except Exception,e:
pass
return r_code
try:
host=raw_input("Enter Host address:")
except KeyboardInterrupt:
print("\n Application shtdown")
sys.exit(1)
hostip=gethostbyname(host)
print("\n Host:%s IP:%s" %(host,hostip))
print("Scanning Started At %s...\n" %(time.strftime("%H:%M:%S")))
start_time=datetime.now()
for port in range(min_port,max_port):
try:
response=scan_host(host,port)
if response ==0:
print("Port %d: Open" %(port))
except Exception,e:
pass
stop_time=datetime.now()
total_time_duration=stop_time -start_time
print("\n Scanning Finished At %s ..." % (time.strftime("%H:%M:%S")))
print("Scanning Duration:%s..." %(total_time_duration))
print("Have a nice day ...Sergeant Exploiter (Sploit)")
Before using the following port scanner, you may want to check a few things first:
Is the firewall on your computer blocking the port scanner?
Is the device your computer connected to blocking certain ports?
Is the computer you are trying to scan blocking ports with its firewall?
Do you know the correct name of the host that you are trying to scan?
Can you create a server on one computer and connect to it with a client on the other?
If none of the above points are cause for your problem, the program shown below may work for you:
#! /usr/bin/env python3
import argparse
import collections
import itertools
import multiprocessing
import operator
import socket
PURPOSE = 'Scan for open ports on a computer.'
PORTS = range(1 << 16)
POOL_SIZE = 1 << 8
TIMEOUT = 0.01
def main():
"""Get computer to scan, connect with process pool, and show open ports."""
parser = argparse.ArgumentParser(description=PURPOSE)
parser.add_argument('host', type=str, help='computer you want to scan')
host = parser.parse_args().host
with multiprocessing.Pool(POOL_SIZE, socket.setdefaulttimeout, [TIMEOUT]) \
as pool:
results = pool.imap_unordered(test, ((host, port) for port in PORTS))
servers = filter(operator.itemgetter(0), results)
numbers = map(operator.itemgetter(1), servers)
ordered = sorted(numbers)
print(f'Ports open on {host}:', *format_ports(ordered), sep='\n ')
field_names = 'family', 'socket_type', 'protocol', 'canon_name', 'address'
AddressInfo = collections.namedtuple('AddressInfo', field_names)
del field_names
def test(address):
"""Try connecting to the server and return whether or not it succeeded."""
host, port = address
for info in itertools.starmap(AddressInfo, socket.getaddrinfo(host, port)):
try:
probe = socket.socket(info.family, info.socket_type, info.protocol)
except OSError:
pass
else:
try:
probe.connect(info.address)
except OSError:
pass
else:
probe.shutdown(socket.SHUT_RDWR)
return True, port
finally:
probe.close()
return False, port
def format_ports(ports):
"""Convert port numbers into strings and show all associated services."""
if ports:
for port in ports:
try:
service = socket.getservbyport(port)
except OSError:
service = '?'
yield f'{port:<5} = {service}'
else:
yield 'None'
if __name__ == '__main__':
main()
I'm trying to get all HTTP GET/POST incoming requests.
I've found this code which seems promising, but I've noticed that it only works on standard HTTP ports. If I use another port (say 8080) scapy can't find the HTTP layer (packet.haslayer(http.HTTPRequest) == False).
This is the code:
from scapy.all import IP, sniff
from scapy.layers import http
def process_tcp_packet(packet):
'''
Processes a TCP packet, and if it contains an HTTP request, it prints it.
'''
if not packet.haslayer(http.HTTPRequest):
# This packet doesn't contain an HTTP request so we skip it
return
http_layer = packet.getlayer(http.HTTPRequest)
ip_layer = packet.getlayer(IP)
print '\n{0[src]} just requested a {1[Method]} {1[Host]}{1[Path]}'.format(ip_layer.fields, http_layer.fields)
# Start sniffing the network.
sniff(filter='tcp', prn=process_tcp_packet)
Any idea about what I'm doing wrong?
**** UPDATE ****
I got rid of scapy_http and just looked at the raw data.
I'm posting here the code I'm using - it works fine for me as I'm debugging a strange problem I'm having on Apache Solr - but your mileage may vary.
def process_tcp_packet(packet):
msg = list()
try:
if packet.dport == 8983 and packet.haslayer(Raw):
lines = packet.getlayer(Raw).load.split(os.linesep)
# GET or POST requests ?
if lines[0].lower().startswith('get /') or lines[0].lower().startswith('post /'):
# request forwarded by a proxy ?
_ = [line.split()[1] for line in lines if line.startswith('X-Forwarded-For:')]
s_ip = (_[0] if _ else packet.getlayer(IP).src)
# collect info
d_port = packet.getlayer(IP).dport
now = datetime.datetime.now()
msg.append('%s: %s > :%i -> %s' % (now, s_ip, d_port, lines[0]))
except Exception, e:
msg.append('%s: ERROR! %s' % (datetime.datetime.now(), str(e)))
pass
with open('http.log', 'a') as out:
for m in msg:
out.write(m + os.linesep)
Currently, I have a home server in my closet basically doing nothing. It has Ubuntu Server 8.0.4 installed, apache for web development ill be using later, ssh, and python/twisted installed.
Here's the issue:
I created an app to talk to "localhost" port-40, using socket implementation, here is a link of what I did but what I want to develop off of : http://www.raywenderlich.com/3932/how-to-create-a-socket-based-iphone-app-and-server
Now connecting to the localhost is no problem but I want to expand this to work with my server.
I implemented the python protocol onto my server and changed the ip address im accessing in the iOS app. Here's the implementation I have, it's exactly the same as the tutorial except for the port i'm accessing.
from twisted.internet.protocol import Factory, Protocol
from twisted.internet import reactor
class IphoneChat(Protocol):
def connectionMade(self):
self.factory.clients.append(self)
print "clients are ", self.factory.clients
def connectionLost(self, reason):
self.factory.clients.remove(self)
def dataReceived(self, data):
a = data.split(':')
print a
#b = password.split(':')
#print b
if len(a) > 1:
command = a[0]
content = a[1]
#username = a[2]
#password = a[2]
msg = ""
#msg2 = ""
if command == "username":
self.name = data
msg = self.name + " has joined"
#self.name = password
#msg2 = self.name + " this is his password"
#print msg
elif command == "password":
self.name = data
msg = self.name + " this is their password"
elif command == "msg":
msg = self.name + ": " + data
print msg
#msg2 = self.name + ": " + password
#print msg2
for c in self.factory.clients:
c.message(msg)#1, msg2)
def message(self, message):
self.transport.write(message + '\n')
factory = Factory()
factory.protocol = IphoneChat #here1#
factory.clients = []
reactor.listenTCP(40, factory)
print "Iphone Chat server started"
reactor.run()
So the REAL issue is, I cannot connect clients to my server or something..... I'm sorry but I am very new to networking.
Any opinion will help.
If you've not established networking communication to your server from the internet before you'll want to establish that you can do that with simple test cases first, there's a lot that can stop traffic from the internet reaching your program on your server.
Is your server connected to the internet through a router? If so, can you communicate with the server from inside the local network (i.e. use the 192.168.xxx.xxx ip address), using something like netcat or telnet?
If that works you should try from outside the network (i.e. using the other ip address, from whatismyip.net or similar). If you've really no prior experience with networking you may have neglected to set up port forwarding, this is a setting on your router.
There are a lot of tutorials around teaching you how to set up a Ubuntu home server, I suggest learning how to host a (very) simple webpage as a means of learning how to network, this will help a lot with debugging a networked program like the one you're making.
The object is to set up n number of ssh tunnels between satellite servers and a centralized registry database. I have already set up public key authentication between my servers so they just log right in without password prompts. Now what ? I've tried Paramiko. It seems decent but gets pretty complicated just to set up a basic tunnel, although code exmplaes would be aprreciated. I've tried Autossh and it dies 2 minutes after setting up a working tunnel, bizarre! Hopefully someone can help me with a simple code snippet that I can daemonize and monitor with supervisord or monit.
Here is a cutdown version of the script that Alex pointed you to.
It simply connects to 192.168.0.8 and forwards port 3389 from 192.168.0.6 to localhost
import select
import SocketServer
import sys
import paramiko
class ForwardServer(SocketServer.ThreadingTCPServer):
daemon_threads = True
allow_reuse_address = True
class Handler (SocketServer.BaseRequestHandler):
def handle(self):
try:
chan = self.ssh_transport.open_channel('direct-tcpip', (self.chain_host, self.chain_port), self.request.getpeername())
except Exception, e:
print('Incoming request to %s:%d failed: %s' % (self.chain_host, self.chain_port, repr(e)))
return
if chan is None:
print('Incoming request to %s:%d was rejected by the SSH server.' % (self.chain_host, self.chain_port))
return
print('Connected! Tunnel open %r -> %r -> %r' % (self.request.getpeername(), chan.getpeername(), (self.chain_host, self.chain_port)))
while True:
r, w, x = select.select([self.request, chan], [], [])
if self.request in r:
data = self.request.recv(1024)
if len(data) == 0:
break
chan.send(data)
if chan in r:
data = chan.recv(1024)
if len(data) == 0:
break
self.request.send(data)
chan.close()
self.request.close()
print('Tunnel closed from %r' % (self.request.getpeername(),))
def main():
client = paramiko.SSHClient()
client.load_system_host_keys()
client.set_missing_host_key_policy(paramiko.WarningPolicy())
client.connect("192.168.0.8")
class SubHandler(Handler):
chain_host = "192.168.0.6"
chain_port = 3389
ssh_transport = client.get_transport()
try:
ForwardServer(('', 3389), SubHandler).serve_forever()
except KeyboardInterrupt:
sys.exit(0)
if __name__ == '__main__':
main()
Is there a special reason not to just do it with ssh, the usual
(ssh -L <localport>:localhost:<remoteport> <remotehost>)
minuet? Anyway, this script is an example of local port forwarding (AKA tunneling).
I'm trying to write a simple module that will enable sending SMS. I using bluetooth to connect to the mobile using the below example:
file: bt-sendsms.py
import bluetooth
target = '00:32:AC:32:36:E8' # Mobile address
print "Trying to send SMS on %s" % target
BTSocket = bluetooth.BluetoothSocket(bluetooth.RFCOMM)
BTSocket.connect((target, 2)) # BT Address
BTSocket.send('ATZ\r')
BTSocket.send('AT+CMGF=1\r')
#sockfd.send('AT+CSCA="+972547716507"\r') # This line changes the SMSC address - do not modify unless required
BTSocket.send('AT+CMGS="+972547877763"\r') # TO Phone Number
BTSocket.send('This is a test message - port 2.\n')
BTSocket.send(chr(26)) # CTRL+Z
print "SMS sent"
sockfd.close()
print "Closed"
My problem is that I'm unable to verify or get an error code for the SMS sending or any of the socket operation.
Any referral to the right direction will be appreciated
From the Python you look like you are opening any old RFCOMM channel and hoping it will magically take the AT commands and do the messaging.
I think (and I could be wrong) that you need to connect to a specific profile/sevice channel and I think for SMS it is the the Messaging Access Profile (MAP), which is not yet standardised so finding a phone with it on, well I won't say impossible but very, very unlikely. Otherwise, some phones will support AT commands for messaging but this is outside the specs e.g. I have it on authority that Sony-Ericson phones will support it though the Dial-Up Networking profile (DUN).
So, first of all, does your mobile device support some out of spec AT commands for SMS and if so, on a certain profile or on an ad-hoc proprietary one? Next, you need to connect to that profile.
You can browse the supported services etc... using the following Python (checks all surrounding BT devices)...
import bluetooth
def whats_nearby():
name_by_addr = {}
nearby = bluetooth.discover_devices(flush_cache=True)
for bd_addr in nearby:
name = bluetooth.lookup_name( bd_addr, 5)
print bd_addr, name
name_by_addr[bd_addr] = name
return name_by_addr
def what_services( addr, name ):
print " %s - %s" % ( addr, name )
for services in bluetooth.find_service(address = addr):
print "\t Name: %s" % (services["name"])
print "\t Description: %s" % (services["description"])
print "\t Protocol: %s" % (services["protocol"])
print "\t Provider: %s" % (services["provider"])
print "\t Port: %s" % (services["port"])
print "\t service-classes %s" % (services["service-classes"])
print "\t profiles %s" % (services["profiles"])
print "\t Service id: %s" % (services["service-id"])
print ""
if __name__ == "__main__":
name_by_addr = whats_nearby()
for addr in name_by_addr.keys():
what_services(addr, name_by_addr[addr])
Once you find the correct service/profile, your next problem will be negotiating security (pin code for pairing), which I haven't worked out how to do yet!
See the www.bluetooth.org for all your Bluetooth needs!