您的位置:首页 > 编程语言 > Python开发

『Python』 多线程 端口扫描器

2016-03-09 18:43 627 查看
[b]  0x 00 Before Coding[/b]  当端口打开时,向端口发送 TCP SYN 请求,会返回一个 ACK 响应:    当端口关闭,返回的是 RST 响应:    0x 01 Coding   可以用 socket 编写一个小脚本来测试主机端口的开启情况,基本代码如下:  
# coding: utf-8

import socket
from datetime import datetime

# Set time-out to get the scanning fast
socket.setdefaulttimeout(0.5)

# Ask for input
remote_server = raw_input("Enter a remote host to scan:")
remote_server_ip = socket.gethostbyname(remote_server)

# Print a nice banner with info on which host we are about to scan
print '-' * 60
print 'Please wait, scanning remote host ', remote_server_ip
print '-' * 60

# Check what time the scan started
t1 = datetime.now()

# Using the range function to specify ports(1 - 1024)
# We also put in some error handling for catching errors
try:
for port in range(1,1025):
sock = socket.socket(2,1) # 2:socket.AF_INET 1:socket.SOCK_STREAM
res = sock.connect_ex((remote_server_ip,port))
if res == 0:
print 'Port {}: OPEN'.format(port)
sock.close()

except socket.gaierror:
print 'Hostname could not be resolved.Exiting'

except socket.error:
print "Could't connect to the server"

# Check the time now
t2 = datetime.now()

# Calculates the difference of time
total = t2 - t1

# Print the info to screen
print 'Scanning Completed in: ', total
  参考:http://www.pythonforbeginners.com/code-snippets-source-code/port-scanner-in-python/  程序测试结果如下:    看出来 在 socket 的超时时间设置为0.5的前提下 依然需要花费 8分27秒才能够把周知端口号扫完,有没有其他方式加快扫描速度?答案是有的。  //////////////////// ******************** 该部分可以略过,一个小坑 ************************ ////////////////////  打开 抓到的数据包列表,发现 timeout 包都会发送2个“伪重传”,发送这两个一般没什么用的数据包会占用 CPU的处理时间,  所以在想能不能不让程序发这两个包来提高效率??  自己分析连续两个端口的时间间隔就会发现:间隔是0.5s(由 39号、46号、53号数据包分析得出),这恰好是在程序中设置的超时时间,  也就是说超时重传的包并不会占用专门的时间,所以这种想法就被干掉了。  这样的话,1个端口0.5的超时等待,扫描一个主机的 1- 1024 号端口所用时间是可以大致估算下的:  1024 * 0.5 / 60 = 8.53 分钟左右。和上面程序实际扫描的时间(8分27秒)相符合。  //////////////////// ******************** 坑结束 ************************ ////////////////////  0x 02 Better Coding   所以对于这种时间主要花费在 socket 连接( 非 CPU 计算密集型 )的程序 可以使用 多线程来提升效率,  这里选择使用内建的库 multiprocessing.dummy 来实现多线程扫描:
# coding: utf-8
'''
  多线程 Socket TCP 端口扫描器  by: EvilCLAY
'''
import socket
from datetime import datetime
from multiprocessing.dummy import Pool as ThreadPool

remote_server = raw_input("Enter a remote host to scan:")
remote_server_ip = socket.gethostbyname(remote_server)
ports = []

print '-' * 60
print 'Please wait, scanning remote host ', remote_server_ip
print '-' * 60

socket.setdefaulttimeout(0.5)

def scan_port(port):
try:
s = socket.socket(2,1)
res = s.connect_ex((remote_server_ip,port))
if res == 0: # 如果端口开启 发送 hello 获取banner
print 'Port {}: OPEN'.format(port)
s.close()
except Exception,e:
print str(e.message)

for i in range(1,1025):
ports.append(i)

# Check what time the scan started
t1 = datetime.now()

pool = ThreadPool(processes = 8)
results = pool.map(scan_port,ports)
pool.close()
pool.join()

print 'Multiprocess Scanning Completed in  ', datetime.now() - t1
  扫描的结果如下:    可以发现 8 个线程并行发起请求,效率有很大的提升。  在被扫描主机未安装连接限制软件的前提下,测试了开启不同线程扫描所花费的时间 :
  16 个线程 使用 32 秒扫完;
  32个线程,使用 16 秒扫完;
  64个线程,使用 8 秒扫完;
  128个线程,使用 4 秒扫完;
  256个线程,使用 2 秒扫完;
  512个线程,使用 1.50 秒扫完;
  1024个线程,使用 1.25 秒扫完;

  获取 Banner
  把 函数修改成如下 即可:
def scan_port(port):
try:
s = socket.socket(2,1)
res = s.connect_ex((remote_server_ip,port))
if res == 0: # 如果端口开启 发送 hello 获取banner

try:
s.send('hello')
banner = s.recv(1024)

except Exception,e:
print 'Port {}: OPEN'.format(port)
print str(e.message)
else:
print 'Port {}: OPEN'.format(port)
print 'Banner {}'.format(banner)

s.close()
except Exception,e:
print str(e.message)
  晚上研究下 Zmap 与 ZGrab 分析下 这两款神器牛在什么地方 ~~

                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: