[原创]K8Cscan for Python 2.0

0x000 简介

K8Cscan扫描器Python版支持Windows和Linux系统

详情参考:https://www.cnblogs.com/k8gege/p/10519321.html

0x001 功能

1.MS17-010漏洞检测

2.SMB协议版本探测

3.存活主机扫描

4.DLL插件扫描(可加载Cscan已发布的DLL,注:该功能仅限Windows且.net版本>=4.0)

PS:由于Cscan功能较多,发现Py可调用.net编写的DLL,偷懒先加载现有插件。

虽然思路一样,但有些功能实现起来不一样,比方其它语言均可ICMP协议实现ping

当然python也可以,但是Py的Socket Raw一定要管理员权限,为了保证任意权限下可用

所以PY版我采用调用系统ping命令这种非常次的方法,来实现内网存活主机的扫描。

没办法我们不是那种可以扛自己的设备去现场接条网线施工的人,打下的权限未必高权限。

很多时候同样的功能由于实现方式不一样,有些工具任意权限下可用,有些仅管理员可用。

0x001 代码

#K8Cscan for python 2.0
#Author: K8gege
#Date: 20190530
#Platform: (Windows & Linux)
#Windows need to .net framework >= 4.0
#Linux not support load 'netscan40.dll' (Maybe Mono is support)
#Usage:
#python K8Cscan.py 192.11.22.40
#python K8Cscan.py 192.11.22.40/24
#python K8Cscan.py 192.11.22.40/24 -t ms17010
#python K8Cscan.py --type=dll 192.11.22.42
#python K8Cscan.py 192.11.22.40/24 -t dll

import platform
import socket
import os
import threading
import time
import telnetlib
import argparse
# import gevent
# from gevent import monkey; monkey.patch_all(); 
# import socket 
# from gevent.pool import Pool 

from mysmb import MYSMB
from impacket import smb, smbconnection, nt_errors
from impacket.uuid import uuidtup_to_bin
from impacket.dcerpc.v5.rpcrt import DCERPCException
from struct import pack
import sys

USERNAME = ''
PASSWORD = ''
NDR64Syntax = ('71710533-BEBA-4937-8319-B5DBEF9CCC36', '1.0')
MSRPC_UUID_BROWSER  = uuidtup_to_bin(('6BFFD098-A112-3610-9833-012892020162','0.0'))
MSRPC_UUID_SPOOLSS  = uuidtup_to_bin(('12345678-1234-ABCD-EF00-0123456789AB','1.0'))
MSRPC_UUID_NETLOGON = uuidtup_to_bin(('12345678-1234-ABCD-EF00-01234567CFFB','1.0'))
MSRPC_UUID_LSARPC   = uuidtup_to_bin(('12345778-1234-ABCD-EF00-0123456789AB','0.0'))
MSRPC_UUID_SAMR     = uuidtup_to_bin(('12345778-1234-ABCD-EF00-0123456789AC','1.0'))

pipes = {
    'browser'  : MSRPC_UUID_BROWSER,
    'spoolss'  : MSRPC_UUID_SPOOLSS,
    'netlogon' : MSRPC_UUID_NETLOGON,
    'lsarpc'   : MSRPC_UUID_LSARPC,
    'samr'     : MSRPC_UUID_SAMR,
}

def smbcheck(target):
    if checkPort(target,'445'):
        conn = MYSMB(target)
        try:
            conn.login(USERNAME, PASSWORD)
        except smb.SessionError as e:
            #print('Login failed: ' + nt_errors.ERROR_MESSAGES[e.error_code][0])
            sys.exit()
        finally:
            #print('OS: ' + conn.get_server_os())
            TragetOS = '(' + conn.get_server_os()+')'

        tid = conn.tree_connect_andx('\\'+target+'\'+'IPC$')
        conn.set_default_tid(tid)

        # test if target is vulnerable
        TRANS_PEEK_NMPIPE = 0x23
        recvPkt = conn.send_trans(pack('<H', TRANS_PEEK_NMPIPE), maxParameterCount=0xffff, maxDataCount=0x800)
        status = recvPkt.getNTStatus()
        if status == 0xC0000205:  # STATUS_INSUFF_SERVER_RESOURCES
            #print('The target is not patched')
            CheckResult = 'MS17-010	'+TragetOS

        return CheckResult

def GetSmbVul(ip): 
    # output = os.popen('ping -%s 1 %s'%(ptype,ip)).readlines()
    # for w in output:
        # if str(w).upper().find('TTL')>=0:
            #print "online "+ip
    try:
        SmbVul=smbcheck(ip)
        if SmbVul<>None:
            print('%s	%s'%(ip,SmbVul))
    except:
        pass
def GetOSname(ip): 
    try:
        print('%s	%s	%s'%(ip,getHostName(ip)))
    except:
        pass
def ScanSmbVul(ip): 
    if '/24' in ip:
        ipc = (ip.split('.')[:-1])
        for i in range(1,256):
            add = ('.'.join(ipc)+'.'+str(i))
            threading._start_new_thread(GetSmbVul,(add,))
            time.sleep(0.1)
    else:
        GetSmbVul(ip)

def checkPort(ip,port):
    server = telnetlib.Telnet()
    try:
        server.open(ip,port)
        #print('{0} port {1} is open'.format(ip, port))
        return True
    except Exception as err:
        #print('{0} port {1} is not open'.format(ip,port))
        return False
    finally:
        server.close()

def getHostName(target):
    try:
      result = socket.gethostbyaddr(target)
      return result[0]
    except socket.herror, e:
      return ''
def getos():
    return platform.system()

try:
    import clr
except:
    pass

def netscan(ip):
	try:  
		clr.FindAssembly('netscan40.dll')
		clr.AddReference('netscan40')
		from CscanDLL import scan
		print(scan.run(ip)),
	except:
		pass

def Cscan(ip): 
    if '/24' in ip:
        ipc = (ip.split('.')[:-1])
        for i in range(1,256):
            add = ('.'.join(ipc)+'.'+str(i))
            threading._start_new_thread(netscan,(add,))
            # if type=='dll':
                # threading._start_new_thread(netscan,(add,))
            # elif type=='smb':
                # threading._start_new_thread(netscan,(add,))
            time.sleep(0.1)
    else:
        netscan(ip)

def CscanSMBver(ip): 
    if '/24' in ip:
        ipc = (ip.split('.')[:-1])
        for i in range(1,256):
            add = ('.'.join(ipc)+'.'+str(i))
            threading._start_new_thread(smbVersion,(add,))
            time.sleep(0.1)
    else:
        smbVersion(ip)
def CscanOSname(ip): 
    if '/24' in ip:
        ipc = (ip.split('.')[:-1])
        for i in range(1,256):
            add = ('.'.join(ipc)+'.'+str(i))
            threading._start_new_thread(GetOSname,(add,))
            time.sleep(0.1)
    else:
        GetOSname(ip)

def getip():                                           
    return socket.gethostbyname(socket.gethostname())
 
def pingIP(ip): 
    #print ip
    #gevent.sleep(0)
    output = os.popen('ping -%s 1 %s'%(ptype,ip)).readlines()
    for w in output:
        if str(w).upper().find('TTL')>=0:
            print ip
            # try:
                # SmbVul=smbcheck(ip)
                # if SmbVul==None:
                    # print('%s	%s'%(ip,getHostName(ip)))
                # else:
                    # print('%s	%s	%s'%(ip,getHostName(ip),SmbVul))
            # except:
                # pass

def CpingIP(ip): 
    ip=ipc+str(ip)
    pingIP(ip)

def Cping(ip): 
    if '/24' in ip:
        ipc = (ip.split('.')[:-1])
        for i in range(1,256):
            add = ('.'.join(ipc)+'.'+str(i))
            threading._start_new_thread(pingIP,(add,))
            time.sleep(0.1)

        #ipcc = scanip.split('.')[:-1]
        #ipccc = ('.'.join(ipcc)+'.')
        #global ipc 
        #ipc = ipccc
        #ipc = scanip.split('.')[:-1]
        #print "ipc: "+ipc

        # pool = Pool(255) 
        # pool.map(CpingIP,xrange(1,254)) 
        # pool.join()
    else:
        pingIP(ip)
def PrintLine():
    print('=============================================')

from impacket.smbconnection import *
from impacket.nmb import NetBIOSError
import errno

def smbVersion(rhost):
    host = rhost
    port=445
    try:
        smb = SMBConnection(host, host, sess_port=port)
    except NetBIOSError:
        return
    except socket.error, v:
        error_code = v[0]
        if error_code == errno.ECONNREFUSED:
            return
        else:
            return
    dialect = smb.getDialect()
    if dialect == SMB_DIALECT:
        print(host + "	SMBv1 ")
    elif dialect == SMB2_DIALECT_002:
        print(host + "	SMBv2.0 ")
    elif dialect == SMB2_DIALECT_21:
        print(host + "	SMBv2.1 ")
    else:
        print(host + "	SMBv3.0 ")

ipc=""
if __name__ == '__main__':

    print('K8Cscan 2.0 by k8gege')
    parser = argparse.ArgumentParser()
    parser.add_argument('ip',help='IP or IP/24') 
    parser.add_argument('--type', '-t', type=str, choices=['ping', 'smbver', 'osname','ms17010','dll'], help='Scan Type',default='ping')
    args = parser.parse_args()
    if getos() == 'Windows':
        ptype = 'n'
    elif getos() == 'Linux':
        ptype = 'c'
    else:
        print('The system is not supported.')
        sys.exit()
    scanip=args.ip
    if args.type == 'ping':
        print "Scan Online"
        PrintLine()
        Cping(scanip)
    elif args.type == 'smbver':
        print "Scan Smb Version "
        CscanSMBver(scanip)
    elif args.type == 'dll':
        if ptype =='n':
            if(os.path.exists('netscan40.dll')):
                print('load netscan40.dll (.net >= 4.0)')
                PrintLine()
                Cscan(scanip)
            else:
                print('load netscan40.dll')
        else:
            print('The system is not supported.')
        sys.exit(1)
    elif args.type == 'ms17010':
        print "Scan MS17-010 VUL 
" + scanip
        ScanSmbVul(scanip)
    elif args.type == 'osname':
        print "Scan hostName 
" + scanip
        CscanOSname(scanip)
    PrintLine()
    print('Scan Finished!')

0x003 用法

例子1: SMB漏洞之MS17-010扫描

例子2:DLL扫描之Cscan操作系统探测插件

根目录下放osscan.rar中的netscan40.dll即可(其它dll同理,windows下不建议python版)PY受好者请继续

如图所示探测到内网Win7三台、Win10两台、2012一台及主机名、路由一台(开放WEB服务,产品版本等)

例子3:SMB版本探测(可用于判断操作系统,因Linux默认不开启)

SMB版本对应操作系统(可用于判断操作系统,因Linux默认不开启)

Scan Smb Version
192.11.22.118   SMBv3.0   Win8.1
192.11.22.7       SMBv3.0   Win10
192.11.22.41     SMBv2.1   (Win7)

SMBv1   XP or 2003

Kali开启SMB后
192.11.22.54    SMBv3.0
192.11.22.54    KALI            [Win 6.1]
抓包显示为 Windows Server 2003 3790 Service Pack 2

例子4:Kali下使用

 0x004 下载

https://github.com/k8gege/K8CScan/blob/master/K8Cscan.py

https://github.com/k8gege/K8tools/blob/master/K8Cscan.py

原文地址:https://www.cnblogs.com/k8gege/p/10852832.html