0


【安全开发】内网扫描器

文章目录


前言

为什么要写这个?
  1. fscna被杀的概率太高(哪天二开一下免杀)。
  2. go还在学习的阶段正是写项目的时候,边写边学习go项目。
  3. 自己写的项目改起来更加方便。
  4. 实现功能暂时定为网段扫描和暴力破解和输出文档。

现实现的功能较少后序开发会逐步加入简单漏洞探探测和代理功能。

一、开发过程

项目已经打包上传至github:https://github.com/19xinan/Scanl

1.项目结构

项目结构非常简单,现在开发的基本功能包括主机存活探测、端口扫描、暴力破解功能其他功能后序开发。

scanl/|-- main.go//程序入口,主函数包括命令格式和网段格式限制|-- core/||-- scanner.go// 扫描器,包括线程控制||-- services.go//服务识别|-- bruteforce/||-- bruteforce.go//暴力破解模版|-- pass.txt//暴力破解使用的密码文件

2.main.go

1.实现网段限制
2.实现网段存活探测
3.实现命令行参数限制
4.实现输出扫描结果文档

package main

import("flag""fmt""net""os""sync""time""scanl/bruteforce""scanl/core")funcmain(){
    fmt.Println(`
  ██████  ▄████▄   ▄▄▄       ███▄    █  ██▓    
▒██    ▒ ▒██▀ ▀█  ▒████▄     ██ ▀█   █ ▓██▒    
░ ▓██▄   ▒▓█    ▄ ▒██  ▀█▄  ▓██  ▀█ ██▒▒██░    
  ▒   ██▒▒▓▓▄ ▄██▒░██▄▄▄▄██ ▓██▒  ▐▌██▒▒██░    
▒██████▒▒▒ ▓███▀ ░ ▓█   ▓██▒▒██░   ▓██░░██████▒
▒ ▒▓▒ ▒ ░░ ░▒ ▒  ░ ▒▒   ▓▒█░░ ▒░   ▒ ▒ ░ ▒░▓  ░
░ ░▒  ░ ░  ░  ▒     ▒   ▒▒ ░░ ░░   ░ ▒░░ ░ ▒  ░
░  ░  ░  ░          ░   ▒      ░   ░ ░   ░ ░   
      ░  ░ ░            ░  ░         ░     ░  ░
         ░
    `)// 解析命令行参数:-h网段、-all全端口、-t线程数、-pwd指定密码文件、-output指定输出文件名(不指定默认输出)
    subnet := flag.String("h","","Target subnet for scanning (e.g., 192.168.10.0/24)")
    allPorts := flag.Bool("all",false,"Scan all ports (0-65535)")
    threads := flag.Int("t",100,"Number of concurrent threads")
    passwordFile := flag.String("pwd","pass.txt","Password file for bruteforce")
    outputFile := flag.String("output","scan_results.txt","Output file for scan results")
    flag.Parse()//检查网段if*subnet ==""{
        fmt.Println("Usage: ScanL.exe -h <target_subnet> [-all] [-t N] [-pwd pass.txt] [-output scan_results.txt]")
        os.Exit(1)}// 打开输出文件
    outputFileHandle, err := os.OpenFile(*outputFile, os.O_CREATE|os.O_WRONLY|os.O_TRUNC,0644)if err !=nil{
        fmt.Printf("Error opening output file: %v\n", err)
        os.Exit(1)}defer outputFileHandle.Close()// 解析网段
    ips, err :=expandCIDR(*subnet)if err !=nil{
        fmt.Fprintf(outputFileHandle,"Error parsing subnet: %v\n", err)
        os.Exit(1)}var wg sync.WaitGroup
    var mutex sync.Mutex
    var aliveHosts []string// 检测存活主机并输出到终端和文件for_, ip :=range ips {
        wg.Add(1)gofunc(ip string){defer wg.Done()ifisHostAlive(ip){
                mutex.Lock()
                aliveHosts =append(aliveHosts, ip)
                mutex.Unlock()
                fmt.Printf("Host %s is alive\n", ip)
                fmt.Fprintf(outputFileHandle,"Host %s is alive\n", ip)}else{
                fmt.Printf("Host %s is not alive\n", ip)
                fmt.Fprintf(outputFileHandle,"Host %s is not alive\n", ip)}}(ip)}

    wg.Wait()// 输出存活主机到文件
    fmt.Fprintln(outputFileHandle,"Alive hosts in subnet:")for_, ip :=range aliveHosts {
        fmt.Fprintln(outputFileHandle, ip)}var ports []intif*allPorts {
        ports =make([]int,65536)for i :=0; i <=65535; i++{
            ports[i]= i
        }}else{
        ports =[]int{21,22,23,25,53,80,110,119,123,143,161,194,443,445,465,587,993,995,1433,1521,1723,3306,3389,5900,8080,8443,8888,9090,7001,9999,6379,9200,9300,27017}// 精简端口列表}// 扫描主机并输出结果到终端和文件for_, ip :=range aliveHosts {
        fmt.Fprintf(outputFileHandle,"Scanning host: %s\n", ip)
        fmt.Printf("Scanning host: %s\n", ip)
        results := core.ScanPorts(ip, ports,*threads)

        fmt.Fprintf(outputFileHandle,"Open ports on host %s:\n", ip)
        fmt.Printf("Open ports on host %s:\n", ip)for port, service :=range results {if service !="Closed"{
                fmt.Fprintf(outputFileHandle,"Port %d: %s\n", port, service)
                fmt.Printf("Port %d: %s\n", port, service)}}// 默认启用暴力破解模块,针对开启了SSH或RDP的端口if service, found := results[22]; found && service =="SSH"{
            fmt.Fprintln(outputFileHandle,"Starting bruteforce attack on SSH...")
            fmt.Println("Starting bruteforce attack on SSH...")
            bruteforce.Bruteforce(ip,22,*passwordFile)}//RDP实现有问题暂存//if service, found := results[3389]; found && service == "RDP" {//    fmt.Fprintln(outputFileHandle, "Starting bruteforce attack on RDP...")//    fmt.Println("Starting bruteforce attack on RDP...")//    bruteforce.Bruteforce(ip, 3389, *passwordFile)//}

        fmt.Fprintln(outputFileHandle,"---------------------------------------------")
        fmt.Println("---------------------------------------------")}

    fmt.Printf("Scan results saved to %s\n",*outputFile)}// expandCIDR 解析网段,生成所有 IP 地址funcexpandCIDR(cidr string)([]string,error){
    ip, ipNet, err := net.ParseCIDR(cidr)if err !=nil{returnnil, err
    }var ips []stringfor ip := ip.Mask(ipNet.Mask); ipNet.Contains(ip);inc(ip){
        ips =append(ips, ip.String())}// 排除网络地址和广播地址
    lenIPs :=len(ips)switch{case lenIPs <2:breakcase lenIPs >2:
        ips = ips[1:len(ips)-1]}return ips,nil}// IP地址递增funcinc(ip net.IP){for j :=len(ip)-1; j >=0; j--{
        ip[j]++if ip[j]>0{break}}}// isHostAlive 检测主机是否存活funcisHostAlive(ip string)bool{
    timeout :=2* time.Second
    conn, err := net.DialTimeout("ip4:icmp", ip, timeout)if err !=nil{returnfalse}defer conn.Close()returntrue}

3.core模块

3.1 scanner.go

package core

import("fmt""net""sync""time")// ScanPorts 扫描指定主机的指定端口,使用指定数量的并发线程funcScanPorts(host string, ports []int, threads int)map[int]string{
    results :=make(map[int]string)var mu sync.Mutex
    var wg sync.WaitGroup
    portChan :=make(chanint,len(ports))// 启动指定数量的goroutinesfor i :=0; i < threads; i++{
        wg.Add(1)gofunc(){defer wg.Done()for port :=range portChan {
                service :=scanPort(host, port)
                mu.Lock()
                results[port]= service
                mu.Unlock()}}()}// 将所有端口放入通道for_, port :=range ports {
        portChan <- port
    }close(portChan)

    wg.Wait()return results
}// scanPort 扫描单个端口funcscanPort(host string, port int)string{
    address := fmt.Sprintf("%s:%d", host, port)
    conn, err := net.DialTimeout("tcp", address,1*time.Second)if err !=nil{return"Closed"}deferfunc(conn net.Conn){
        err := conn.Close()if err !=nil{}}(conn)returnidentifyService(port)}

3.2 service.go

package core

// identifyService 根据端口号识别服务funcidentifyService(port int)string{
    services :=map[int]string{21:"FTP",22:"SSH",23:"Telnet",25:"SMTP",53:"DNS",80:"HTTP",110:"POP3",119:"NNTP",123:"NTP",143:"IMAP",161:"SNMP",194:"IRC",443:"HTTPS",445:"SMB",465:"SMTPS",587:"Submission",993:"IMAPS",995:"POP3S",1433:"MSSQL",1521:"Oracle DB",1723:"PPTP",3306:"MySQL",3389:"RDP",5900:"VNC",8080:"HTTP-Proxy",8443:"HTTPS-Alt",8888:"HTTP-Alt",9090:"Weblogic",7001:"Weblogic-Alt",9999:"HTTP-Alt2",6379:"Redis",9200:"Elasticsearch",9300:"Elasticsearch-Transport",27017:"MongoDB",}if service, found := services[port]; found {return service
    }return"Unknown"}

4.bruteforc

这里少了rdp的爆破

4.1 bruteforce.go

package bruteforce

import("bufio""fmt""os""sync""time""golang.org/x/crypto/ssh")// 默认账号列表var defaultAccounts =[]string{"root","admin","administrator"}// Bruteforce 执行暴力破解攻击funcBruteforce(host string, port int, passwordFile string){
    passwords, err :=readPasswords(passwordFile)if err !=nil{
        fmt.Printf("Error reading password file: %v\n", err)return}var wg sync.WaitGroup
    wg.Add(len(defaultAccounts)*len(passwords))// 并发尝试不同的账号和密码组合for_, account :=range defaultAccounts {for_, password :=range passwords {gofunc(host string, port int, account string, password string){defer wg.Done()
                fmt.Printf("Trying account: %s, password: %s\n", account, password)ifsshLogin(host, port, account, password){
                    fmt.Printf("SSH login successful: %s:%s@%s\n", account, password, host)}}(host, port, account, password)}}

    wg.Wait()}// readPasswords 读取密码文件funcreadPasswords(filePath string)([]string,error){
    file, err := os.Open(filePath)if err !=nil{returnnil, err
    }deferfunc(file *os.File){
        err := file.Close()if err !=nil{}}(file)var passwords []string
    scanner := bufio.NewScanner(file)for scanner.Scan(){
        passwords =append(passwords, scanner.Text())}if err := scanner.Err(); err !=nil{returnnil, err
    }return passwords,nil}// sshLogin 尝试使用SSH登录funcsshLogin(host string, port int, username, password string)bool{
    config :=&ssh.ClientConfig{
        User: username,
        Auth:[]ssh.AuthMethod{
            ssh.Password(password),},
        HostKeyCallback: ssh.InsecureIgnoreHostKey(),
        Timeout:5* time.Second,}

    conn, err := ssh.Dial("tcp", fmt.Sprintf("%s:%d", host, port), config)if err !=nil{returnfalse}deferfunc(conn *ssh.Client){
        err := conn.Close()if err !=nil{}}(conn)returntrue}

二、使用步骤

ScanL.exe -h 192.168.10.1/24
其他参数
ScanL.exe -h <target_subnet>[-all][-t N][-pwd pass.txt][-output scan_results.txt]

请添加图片描述

标签: 安全 个人开发 go

本文转载自: https://blog.csdn.net/qq_39583774/article/details/140053216
版权归原作者 0x717866 所有, 如有侵权,请联系我们删除。

“【安全开发】内网扫描器”的评论:

还没有评论