【安全开发】内网扫描器

文章目录

  • 前言
    • `现实现的功能较少后序开发会逐步加入简单漏洞探探测和代理功能。`
  • 一、开发过程
    • 1.项目结构
    • 2.main.go
    • 3.core模块
      • 3.1 scanner.go
      • 3.2 service.go
    • 4.bruteforc
      • 4.1 bruteforce.go
  • 二、使用步骤


前言

为什么要写这个?

  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"
)

func main() {
	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)
		go func(ip string) {
			defer wg.Done()
			if isHostAlive(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 []int
	if *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 地址
func expandCIDR(cidr string) ([]string, error) {
	ip, ipNet, err := net.ParseCIDR(cidr)
	if err != nil {
		return nil, err
	}

	var ips []string
	for ip := ip.Mask(ipNet.Mask); ipNet.Contains(ip); inc(ip) {
		ips = append(ips, ip.String())
	}

	// 排除网络地址和广播地址
	lenIPs := len(ips)
	switch {
	case lenIPs < 2:
		break
	case lenIPs > 2:
		ips = ips[1 : len(ips)-1]
	}

	return ips, nil
}

// IP地址递增
func inc(ip net.IP) {
	for j := len(ip) - 1; j >= 0; j-- {
		ip[j]++
		if ip[j] > 0 {
			break
		}
	}
}

// isHostAlive 检测主机是否存活
func isHostAlive(ip string) bool {
	timeout := 2 * time.Second
	conn, err := net.DialTimeout("ip4:icmp", ip, timeout)
	if err != nil {
		return false
	}

	defer conn.Close()
	return true
}

3.core模块

3.1 scanner.go

package core

import (
	"fmt"
	"net"
	"sync"
	"time"
)

// ScanPorts 扫描指定主机的指定端口,使用指定数量的并发线程
func ScanPorts(host string, ports []int, threads int) map[int]string {
	results := make(map[int]string)
	var mu sync.Mutex
	var wg sync.WaitGroup
	portChan := make(chan int, len(ports))

	// 启动指定数量的goroutines
	for i := 0; i < threads; i++ {
		wg.Add(1)
		go func() {
			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 扫描单个端口
func scanPort(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"
	}
	defer func(conn net.Conn) {
		err := conn.Close()
		if err != nil {

		}
	}(conn)
	return identifyService(port)
}

3.2 service.go

package core

// identifyService 根据端口号识别服务
func identifyService(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 执行暴力破解攻击
func Bruteforce(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 {
			go func(host string, port int, account string, password string) {
				defer wg.Done()
				fmt.Printf("Trying account: %s, password: %s\n", account, password)
				if sshLogin(host, port, account, password) {
					fmt.Printf("SSH login successful: %s:%s@%s\n", account, password, host)
				}
			}(host, port, account, password)
		}
	}

	wg.Wait()
}

// readPasswords 读取密码文件
func readPasswords(filePath string) ([]string, error) {
	file, err := os.Open(filePath)
	if err != nil {
		return nil, err
	}
	defer func(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 {
		return nil, err
	}

	return passwords, nil
}

// sshLogin 尝试使用SSH登录
func sshLogin(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 {
		return false
	}
	defer func(conn *ssh.Client) {
		err := conn.Close()
		if err != nil {

		}
	}(conn)
	return true
}

二、使用步骤

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

请添加图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/754236.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

从单一到多元:EasyCVR流媒体视频汇聚技术推动安防监控智能升级

随着科技的飞速发展&#xff0c;视频已成为我们日常生活和工作中的重要组成部分。尤其在远程办公、在线教育、虚拟会议等领域&#xff0c;视频的应用愈发广泛。为了满足日益增长的视频需求&#xff0c;流媒体视频汇聚融合技术应运而生&#xff0c;它不仅改变了传统视频的观看和…

江山欧派杯2024全国华佗五禽戏线上线下观摩交流比赛在亳州开幕

6月28日&#xff0c;2024全国华佗五禽戏线上线下观摩交流比赛在安徽省亳州市开幕。 此次比赛是由安徽省亳州市文化旅游体育局和安徽省非物质文化遗产保护中心主办、亳州市华佗五禽戏协会&#xff08;国家级非遗华佗五禽戏保护单位&#xff09;和亳州市传统华佗五禽戏俱乐部&…

【数字基础设施1007】探索数字基础设施的影响:宽带政策变量数据集来了!

今天给大家分享的是国内顶级期刊2023年发表论文《数字基础设施与代际收入向上流动性——基于“宽带中国”战略的准自然实验》使用到的重要数据集——“宽带中国”政策变量数据、互联网发展指数以及工具变量&#xff08;所在城市到杭州市的球面距离和到“八纵八横”政策节点城市…

2.最简单的hello驱动

写驱动最快的方法就是抄内核中的其他驱动&#xff0c;这里选择的是/Linux-4.9.88/drivers/char/mem.c 第一步新建一个hello_drv.c,把mem.c中的头文件都复制过来 #include <linux/mm.h> #include <linux/miscdevice.h> #include <linux/slab.h> #include <…

干货︱部分领域数字孪生白皮书及报告汇总(附下载)

在国家政策和市场需求的双轮驱动下&#xff0c;数字孪生技术越来越为人们所熟知。作为数字化的重要底层技术&#xff0c;数字孪生在优化各行各业产业布局、实现产业结构优化、打通生产上下游链条、迈向产业智能发展、推动行业高质量发展中发挥着重要作用。为了帮助广大读者朋友…

uni-app通过配置package.json实现环境变量、自定义条件编译

文章目录 前言官方提示使用方法微信小程序配置如下自定义条件编译使用方法 前言 uni-app 官方概括 官方文档 在开发web时&#xff0c;有时需要一套代码编译发布到不同的站点&#xff0c;比如主站和微信h5站。&#xff08;注意不是一套代码内部自适应不同浏览器&#xff0c;是真…

贾英才主任的中医探索之路

在北京崇文门中医医院&#xff0c;贾英才主任在中医领域的钻研从未停歇。他对药理的探究和药物搭配的研究&#xff0c;展现出了非凡的专注与执着。 贾英才主任常常埋首于浩瀚的中医典籍之中&#xff0c;逐字逐句地研读古代名医的论述&#xff0c;试图从那些古老的智慧中汲取精…

第十九课,编写并调用自定义函数

一&#xff0c;函数五大组成部分 因为其重要性故再此强调&#xff0c;参数列表可以为任意个数&#xff0c;返回值只能有一个&#xff08;请初学者暂时这样认为&#xff09; 特殊的&#xff0c;如果不需要返回结果&#xff0c;用None替代&#xff01; 二&#xff0c;编写自定义…

BUUCTF--WEB

首頁 - OWASP Top 10:2021 [极客大挑战 2019]EasySQL 类型:sql注入 使用万能密码 flag{f580db5b-c0c9-4b13-bfb6-adfa525c93f5} [极客大挑战 2019]Havefun 类型:代码审计 F12打开浏览器控制台 GET请求,在url添加参数/?cat=dog访问 返回flag{f60c7d5c-9f44-4e92-88c0…

操作系统期末复习(对抽象概念的简单形象化)

操作系统 引论 定义与基本概念&#xff1a;操作系统是计算机硬件与用户之间的桥梁&#xff0c;类似于家中的管家&#xff0c;它管理硬件资源&#xff08;如CPU、内存、硬盘&#xff09;&#xff0c;并为用户提供方便的服务&#xff08;应用程序执行、文件管理等&#xff09;。…

三星DRAM、NAND,“又双叒叕”带头涨价了

据韩国媒体《每日经济新闻》报道&#xff0c;三星电子计划在第三季度上调服务器DRAM和企业级NAND闪存的价格&#xff0c;涨幅预计在15%-20%&#xff0c;主要受人工智能(AI)需求激增的推动。这一举措有望提振公司下半年业绩。 据《经济日报》报道援引业内消息&#xff0c;由于厂…

数据资产赋能企业决策:通过精准的数据分析和洞察,构建高效的数据资产解决方案,为企业提供决策支持,助力企业实现精准营销、风险管理、产品创新等目标,提升企业竞争力

一、引言 在信息化和数字化飞速发展的今天&#xff0c;数据已成为企业最宝贵的资产之一。数据资产不仅包含了企业的基本信息&#xff0c;还蕴含了丰富的市场趋势、消费者行为和潜在商机。如何通过精准的数据分析和洞察&#xff0c;构建高效的数据资产解决方案&#xff0c;为企…

使用QGIS进行研究区域制图实战

目录 前言 一、QGIS的版本和数据介绍 1、关于QGIS版本 2、需要准备的数据 二、准备制图 1、制作全国区位图 2、矢量和遥感信息的编辑 三、出图编辑 1、设置主题信息 2、打印布局制作 3、美化地图 总结 前言 俗话说“一图胜千言”&#xff0c;在地理信息的领域中&…

利用代理IP实现高效大数据抓取的策略与技巧

在当今信息爆炸的时代&#xff0c;数据对于各行各业都至关重要。而数据的获取往往需要通过网络爬取。然而随着网络安全意识的提高和反爬虫机制的加强&#xff0c;传统的数据爬取方式可能会受到限制。在这种情况下&#xff0c;代理IP技术的应用就显得尤为重要。本文将探讨代理IP…

Java编程基本功大揭秘 | 详解深入分析Java线程池源码和底层原理,掌握实战技巧【1】

详解深入分析Java线程池源码和底层原理 文章大纲引言Java线程池概念及重要性 ThreadPoolExecutor类的概述ThreadPoolExecutor类的基本功能和作用**基本功能****核心作用** ThreadPoolExecutor主要构造函数及其参数继承关系链功能介绍ThreadPoolExecutor 构造器构造器参数构造器…

SysML与MBSE的关系

SysML与MBSE的关系 对于任何基于模型的系统工程 &#xff08;MBSE&#xff09; 方法&#xff0c;推荐的最佳实践是基于模型的语言、基于模型的工具、基于模型的流程和基于模型的架构框架的协同应用&#xff0c;如下图所示 系统架构四元组 图。经过十年将SysML应用于棘手的系统…

MATLAB算法实战应用案例精讲-【数模应用】线性判别分析(附MATLAB、python和R语言代码实现)

目录 前言 算法原理 什么是判别分析 线性判别分析(LDA) 数学模型 二分类 多分类LDA ​编辑 算法思想: 费歇(FISHER)判别思想 贝叶斯(BAYES)判别思想 LDA算法流程 LDA与PCA对比 SPSSPRO 1、作用 2、输入输出描述 3、案例示例 4、案例数据 5、案例操作 …

MySQL高级-SQL优化- update 优化(尽量根据主键/索引字段进行数据更新,避免行锁升级为表锁)

文章目录 0、update 优化1、创建表2、默认是行锁3、行锁升级为表锁4、给name字段建立索引 0、update 优化 InnoDB的行锁是针对索引加的锁&#xff0c;不是针对记录加的锁&#xff0c;并且该索引不能失效&#xff0c;否则会从行锁升级为表锁。 1、创建表 create table course(…

【Python机器学习实战】 | 基于支持向量机(Support Vector Machine, SVM)进行分类和回归任务分析

&#x1f3a9; 欢迎来到技术探索的奇幻世界&#x1f468;‍&#x1f4bb; &#x1f4dc; 个人主页&#xff1a;一伦明悦-CSDN博客 ✍&#x1f3fb; 作者简介&#xff1a; C软件开发、Python机器学习爱好者 &#x1f5e3;️ 互动与支持&#xff1a;&#x1f4ac;评论 &…

物联网 IoT 收录

物联网IoT日常知识收录 thingsboard, nodered是国际大品牌&#xff0c; iotgateway是国内的&#xff0c; 几个scada, pyscada, json-scada都还不错&#xff0c;比较一下。thingsboard-gateway是python系的&#xff0c;如果你愿意&#xff0c;可以用这个作为公司的物联网网关。…