专栏首页玄魂工作室Python3实现TCP端口扫描器

Python3实现TCP端口扫描器

在渗透测试的初步阶段通常我们都需要对攻击目标进行信息搜集,而端口扫描就是信息搜集中至关重要的一个步骤。通过端口扫描我们可以了解到目标主机都开放了哪些服务,甚至能根据服务猜测可能存在某些漏洞。 TCP端口扫描一般分为以下几种类型:

  1. TCP connect扫描:也称为全连接扫描,这种方式直接连接到目标端口,完成了TCP三次握手的过程,这种方式扫描结果比较准确,但速度比较慢而且可轻易被目标系统检测到。
  2. TCP SYN扫描:也称为半开放扫描,这种方式将发送一个SYN包,启动一个TCP会话,并等待目标响应数据包。如果收到的是一个RST包,则表明端口是关闭的,而如果收到的是一个SYN/ACK包,则表示相应的端口是打开的。
  3. Tcp FIN扫描:这种方式发送一个表示拆除一个活动的TCP连接的FIN包,让对方关闭连接。如果收到了一个RST包,则表明相应的端口是关闭的。
  4. TCP XMAS扫描:这种方式通过发送PSH、FIN、URG、和TCP标志位被设为1的数据包。如果收到了一个RST包,则表明相应的端口是关闭的。

下面我们将使用Python3 实现TCP全连接端口扫描器,下面进入编程环节。

编码实战

全连接扫描方式的核心就是针对不同端口进行TCP连接,根据是否连接成功来判断端口是否打开,现在我们来实现一个最简单的端口扫描器:

#!/usr/bin/python3
# -*- coding: utf-8 -*-
from socket import *

def portScanner(host,port):
    try:
        s = socket(AF_INET,SOCK_STREAM)
        s.connect((host,port))
        print('[+] %d open' % port)
        s.close()
    except:
        print('[-] %d close' % port)

def main():
    setdefaulttimeout(1)
    for p in range(1,1024):
        portScanner('192.168.0.100',p)

if __name__ == '__main__':
    main()

这段代码的核心就是portScanner函数,从其中的内容可以看出,只是进行了简单的TCP连接,如果连接成功则判断为端口打开,否则视为关闭。 我们来看一下运行结果:

这样的扫描看起来效率太低了,实际也确实很慢,因为我们设置了默认的超时时间为1秒,这要是扫描10000个端口,岂不是要等到花都谢了? 最简单的办法就是用多线程来提高效率,虽然python的多线程有点太弱了,不过至少可以利用我们等待的时间去干点别的。另外之前扫描的端口比较多, 显示的信息我们看起来不方便,这次我们只显示我们关心的打开的端口,并将打开端口的数量在扫描结束的时候显示出来。

#!/usr/bin/python3
# -*- coding: utf-8 -*-
from socket import *
import threading

lock = threading.Lock()
openNum = 0
threads = []

def portScanner(host,port):
    global openNum
    try:
        s = socket(AF_INET,SOCK_STREAM)
        s.connect((host,port))
        lock.acquire()
        openNum+=1
        print('[+] %d open' % port)
        lock.release()
        s.close()
    except:
        pass

def main():
    setdefaulttimeout(1)
    for p in range(1,1024):
        t = threading.Thread(target=portScanner,args=('192.168.0.100',p))
        threads.append(t)
        t.start()     

    for t in threads:
        t.join()

    print('[*] The scan is complete!')
    print('[*] A total of %d open port ' % (openNum))

if __name__ == '__main__':
    main()

运行看一下效果,如下图:

这下看起来是不是方便多了?至此效率上的问题解决了,现在我们还需要为扫描器增加一个 参数解析的功能,这样才能看起来像个样子,总不能每次都改代码来修改扫描目标和端口吧!

参数解析我们将用python3自带的标准模块argparse,这样我们就省去了自己解析字符串的麻烦! 下面来看代码:

#!/usr/bin/python3
# -*- coding: utf-8 -*-
from socket import *
import threading
import argparse

lock = threading.Lock()
openNum = 0
threads = []

def portScanner(host,port):
    global openNum
    try:
        s = socket(AF_INET,SOCK_STREAM)
        s.connect((host,port))
        lock.acquire()
        openNum+=1
        print('[+] %d open' % port)
        lock.release()
        s.close()
    except:
        pass

def main():
    p = argparse.ArgumentParser(description='Port scanner!.')
    p.add_argument('-H', dest='hosts', type=str)
    args = p.parse_args()
    hostList = args.hosts.split(',')
    setdefaulttimeout(1)
    for host in hostList:
        print('Scanning the host:%s......' % (host))
        for p in range(1,1024):
            t = threading.Thread(target=portScanner,args=(host,p))
            threads.append(t)
            t.start()     

        for t in threads:
            t.join()

        print('[*] The host:%s scan is complete!' % (host))
        print('[*] A total of %d open port ' % (openNum))

if __name__ == '__main__':
    main()

看一下运行效果,如下图:

至此我们的端口扫描器就基本完成了,虽然功能比较简单,旨在表达端口扫描器的基本实现思路! 至于更详细的功能可以基于这个基本结构来逐步完善!

小结

本节主要讲解了Python3实现一个简单的端口扫描器的过程,本次实验采用了Tcp全连接的方式,不断尝试连接主机的端口来判断端口的开放情况,虽然存在一些缺点, 不过这种方式最适合初学者学习,至于更复杂的方式以后学习起来也不会很难。想举一反三的朋友可以根据协议和端口的对照关系来完成扫描时同时输出协议, 这样看起来会更好一些,至于更详细的功能就留给大家做练习了!

本文分享自微信公众号 - 玄魂工作室(xuanhun521),作者:高海峰

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2016-10-12

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Hacker基础之Linux篇:基础Linux命令八

    我们开始学习Linux压缩和打包基础 tar 在Linux中,打包和压缩是分两步完成的 打包 打包是将多个文件归并到一个文件中 tar -cvf test.ta...

    用户1631416
  • Kali Linux Web渗透测试手册(第二版) - 8.3 - 使用Wapiti发现漏洞

    thr0cyte,Gr33k,花花,MrTools,R1ght0us,7089bAt

    用户1631416
  • 如何将HTML字符转换为DOM节点并动态添加到文档中

    将字符串动态转换为DOM节点,在开发中经常遇到,尤其在模板引擎中更是不可或缺的技术。 字符串转换为DOM节点本身并不难,本篇文章主要涉及两个主题:<br />

    用户1631416
  • Material on Mobile Development

    1.Android开发者:http://developer.android.com/index.html Google官方Android开发者网站,发布关于A...

    宅男潇涧
  • Android知识图谱:我们到底需要学习哪些Android知识?

    版权声明:本文为博主原创文章,未经博主允许不得转载,更多请继续关注Carson_Ho https://blog.csdn.net/carson_ho/a...

    Carson.Ho
  • 最终预览版 Beta 4 现已发布,Android P 正式版即将到来!

    Android P 即将面世,新平台目前正处于最后调试阶段。今天,我们向各位开发者发布 Android P 的 Beta 4 版本。

    Android 开发者
  • Android P Beta 3 现已发布!

    Android 开发者
  • Android P Beta 2 及终版 API 强势来袭!

    Android 开发者
  • 深度了解Android 7.0 ,你准备好了吗?

    8月22日,谷歌正式推送Android 7.0 Nougat(牛轧糖)正式版,首发推送了多款Nexus设备。除了修复常规BUG,Android 7.0还新增了分...

    WeTest质量开放平台团队
  • 提示Android Q Beta 3 亮相 Google I/O'19

    I/O'19 期间 Android 达成了两项里程碑的成就: 其一,迎来第 10 个主版本;其二,全球活跃设备数量突破 25 亿台。

    Android 开发者

扫码关注云+社区

领取腾讯云代金券