服务识别

前言

在渗透测试的过程中,服务识别是一个很重要的环节。对于入侵者来说,发现这些运行在目标上的服务,就可以利用这些软件上的漏洞入侵目标;对于网络安全的维护者来说,也可以提前发现系统的漏洞,从而预防这些入侵行为。由于很多软件在连接之后都会提供一个表明自身信息的banner,在这里我们可以根据获取的banner信息对运行的服务类型进行判断,进而可以确定开放端口对应的服务类型及版本号。

文件共享服务端口

端口号 说明 作用
21/22/69 FTP/TFTP 允许匿名上传、下载、破解和嗅探攻击
2049 NFS服务 配置不当
139 Samba服务 破解、未授权访问、远程代码执行
389 LDAP(目录访问协议) 注入、允许匿名访问、使用弱口令

远程连接服务端口

端口号 说明 作用
22 SSH远程连接 破解、SSH隧道及内网代理转发、文件传输
23 Telnet远程连接 破解、嗅探、弱口令
3389 Rdp远程桌面连接 Shift后门(需要Windows Server 2003以下的系统)、破解
5900 VNC 弱口令破解
5632 PyAnywhere服务 抓密码、代码执行

Web应用服务端口

端口号 说明 作用
80/443/8080 常见Web服务端口 Web攻击、破解、服务器版本漏洞
7001/7002 WebLogic控制台 Java反序列化、弱口令
8080/8089 Jboss/Resin/Jetty/JenKins 反序列化、控制台弱口令
9090 WebSphere控制台 Java反序列化、弱口令
4848 GlassFish控制台 弱口令
1352 Lotus Domino邮件服务 弱口令、信息泄露、破解
10000 Webmin-Web控制面板 弱口令

数据库服务端口

端口号 说明 作用
3306 MySQL 注入、提权、破解
1433 MSSQL 注入、提权、SA弱口令、破解
1521 Oracle数据库 TNS破解、注入、反弹shell
5432 PostgreSQL数据库 破解、注入、弱口令
27017/27018 MongoDB 破解、未授权访问
6379 Redis数据库 可尝试未授权访问、弱口令破解
5000 SysBase/DB2 破解、注入

邮件服务端口

端口号 说明 作用
25 SMTP邮件服务 邮件伪造
110 POP3协议 破解、嗅探
143 IMAP协议 破解

网络常见协议端口

端口号 说明 作用
53 DNS域名系统 允许区域传送、DNS劫持、缓存投毒、欺骗
67/68 DHCP服务 劫持、欺骗
161 SNMP协议 破解、搜集目标内网信息

特殊服务端口

端口号 说明 作用
2181 Zookeeper 未授权访问
8069 Zabbix服务 远程执行、SQL注入
9200/9300 Elasticsearch 远程执行
11211 Memcache服务 未授权访问
512/513/514 Linux Rexec服务 破解、Rlogin登录
873 Rsync服务 匿名访问、文件上传
3690 SVN服务 SVN泄露、未授权访问
50000 SAP Management Console 远程执行

代码展示

导入程序所用到的模块和SIGNS指纹库

from optparse import OptionParser
import time
import socket
import re

SIGNS = (
    # 协议 | 版本 | 关键字
    #b" "前缀表示:后面字符串是bytes 类型
    #用处:网络编程中,服务器和浏览器只认bytes 类型数据
    b'FTP|FTP|^220.*FTP',
    b'MySQL|MySQL|mysql_native_password',
    b'oracle-https|^220- ora',
    b'Telnet|Telnet|Telnet',
    b'Telnet|Telnet|^\r\n%connection closed by remote host!\x00$',
    b'VNC|VNC|^RFB',
    b'IMAP|IMAP|^\* OK.*?IMAP',
    b'POP|POP|^\+OK.*?',
    b'SMTP|SMTP|^220.*?SMTP',
    b'Kangle|Kangle|HTTP.*kangle',
    b'SMTP|SMTP|^554 SMTP',
    b'SSH|SSH|^SSH-',
    b'HTTPS|HTTPS|Location: https',
    b'HTTP|HTTP|HTTP/1.1',
    b'HTTP|HTTP|HTTP/1.0',
)

time模块主要用于产生延迟时间,optparse模块用于生成命令行参数,socket模块用于产生TCP请求,re模块为正则表达式模块,与指纹信息进行有效匹配,进而确定服务类型。SIGNS为指纹库,用于对目标主机返回的banner信息进行匹配。

然后利用optparse模块对输入的参数进行接收和批量处理

def main():
    parser = OptionParser("Usage: %prog -i <target host>")
    parser.add_option('-i',type='string',dest='IP',help='specify target host')
    #获取IP地址参数
    parser.add_option('-p',type='string',dest='PORT',help='specify target host')
    options,args = parser.parse_args()
    ip = options.IP
    port = options.PORT
    print("Scan report for " +ip+ "\n")
    for line in port.split(','):
        request(ip,line)
        time.sleep(0.2)
    print("\nScan finished!...\n")

我们在request函数中首先调用sock.connect()函数探测目标主机端口是否开放,如果端口开放,则利用sock.sendall()函数将PROBE探针发送给目标端口。sock.recv()函数用于接收返回的指纹信息,并将指纹信息及端口发送到regex()函数。

def request(ip,port):
    response = ''
    PROBE = 'GET / HTTP/1.0\r\n\r\n'
    sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    sock.settimeout(10)
    result = sock.connect_ex((ip,int(port)))
    if result == 0:
        try:
            sock.sendall(PROBE.encode())
            response = sock.recv(256)
            if response:
                regex(response,port)
        except(ConnectionResetError,socket.timeout):
            pass
    else:
        pass
    sock.close()

利用re.search()函数将返回的banner信息与SIGNS包含的指纹信息进行正则匹配,并将匹配到的结果输出。没有则输出Unrecongnized。

def regex(response,port):
    text = ""
    if re.search(b'<title>502 Bad Gateway',response):
        proto = {"Service failed to access!!"}
    for pattern in SIGNS:
        pattern = pattern.split(b'|')
        if re.search(pattern[-1], response, re.IGNORECASE):
            proto = "["+port+"]" + " open " + pattern[1].decode()
            break
        else:
            proto = "["+port+"]" + " open " + "Unrecongnized"
    print(proto)

最后编写主函数

if __name__ == '__main__':
    try:
        main()
    except KeyboardInterrupt:
        print("interrupted by user, killing all threads...")

效果如下图所示
服务识别
这个是Nmap版本的,nmap的扫描速度相对较快

import nmap
import optparse

def NmapScan(targetIP,targetPort):
    #实例化PortScanner对象
    nm = nmap.PortScanner()
    try:
        #host为目标IP地址,arguments为Nmap的扫描参数
        #-sn:使用ping进行扫描
        #-PE:使用ICMP的echo请求包(-PP:使用timestamp请求包 -PM:network请求包)
        result = nm.scan(hosts=targetIP,arguments='-sV -p'+str(targetPort))
        #对结果进行切片,提取主机状态信息
        port_infor = result['scan'][targetIP]['tcp'][int(targetPort)]
        print("[{}:{}] : [{}:{}]".format(targetPort,port_infor['state'],port_infor['name'],port_infor['product']))
    except Exception as e:
        pass

if __name__ == '__main__':
	parser = optparse.OptionParser('usage: python %prog -i ip -p port\n\n'
                                    'Example: python %prog -i 192.168.1.1 -p 80,3306\n')
	# 添加目标IP参数-i
	parser.add_option('-i','--ip',dest='targetIP',default='192.168.1.1',type='string',help='target ip address')
	# 添加扫描端口参数-p
	parser.add_option('-p','--port',dest='targetPort',default='80',type='string',help='target port')
	options,args = parser.parse_args()
	for i in range(0,len(options.targetPort.split(','))):
		NmapScan(options.targetIP, options.targetPort.split(',')[i])

服务识别

上一篇:UDP&TCP Linux网络应用编程详解


下一篇:python----------基于UDP的聊天室程序