【安全开发】内网扫描器
文章目录
- 前言
- `现实现的功能较少后序开发会逐步加入简单漏洞探探测和代理功能。`
- 一、开发过程
- 1.项目结构
- 2.main.go
- 3.core模块
- 3.1 scanner.go
- 3.2 service.go
- 4.bruteforc
- 4.1 bruteforce.go
- 二、使用步骤
前言
为什么要写这个?
- fscna被杀的概率太高(哪天二开一下免杀)。
- go还在学习的阶段正是写项目的时候,边写边学习go项目。
- 自己写的项目改起来更加方便。
- 实现功能暂时定为网段扫描和暴力破解和输出文档。
现实现的功能较少后序开发会逐步加入简单漏洞探探测和代理功能。
一、开发过程
项目已经打包上传至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 mainimport ("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.WaitGroupvar mutex sync.Mutexvar 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 []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 地址
func expandCIDR(cidr string) ([]string, error) {ip, ipNet, err := net.ParseCIDR(cidr)if err != nil {return nil, 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地址递增
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.Secondconn, err := net.DialTimeout("ip4:icmp", ip, timeout)if err != nil {return false}defer conn.Close()return true
}
3.core模块
3.1 scanner.go
package coreimport ("fmt""net""sync""time"
)// ScanPorts 扫描指定主机的指定端口,使用指定数量的并发线程
func ScanPorts(host string, ports []int, threads int) map[int]string {results := make(map[int]string)var mu sync.Mutexvar wg sync.WaitGroupportChan := make(chan int, len(ports))// 启动指定数量的goroutinesfor 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] = servicemu.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 bruteforceimport ("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.WaitGroupwg.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 []stringscanner := 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]

相关文章:
【安全开发】内网扫描器
文章目录 前言现实现的功能较少后序开发会逐步加入简单漏洞探探测和代理功能。 一、开发过程1.项目结构2.main.go3.core模块3.1 scanner.go3.2 service.go 4.bruteforc4.1 bruteforce.go 二、使用步骤 前言 为什么要写这个? fscna被杀的概率太高(哪天二…...
ESP32-C3模组上跑通MQTT(5)
接前一篇文章:ESP32-C3模组上跑通MQTT(4) 本文内容参考: 《ESP32-C3 物联网工程开发实战》 一分钟了解MQTT协议 ESP32 MQTT API指南-CSDN博客 ESP-IDF MQTT 示例入门_mqtt outbox-CSDN博客 ESP32用自签CA进行MQTT的TLS双向认证通信_esp32 mqtt ssl-CSDN博客 特此致谢!…...
Arduino - LED 矩阵
Arduino - LED 矩阵 Arduino - LED Matrix LED matrix display, also known as LED display, or dot matrix display, are wide-used. In this tutorial, we are going to learn: LED矩阵显示器,也称为LED显示器,或点阵显示器,应用广泛。在…...
设计模式 - Observer Pattern 观察者模式
文章目录 定义观察者模式的实现构成构成UML图 观察者模式的代码实现场景代码实现 总结优点缺点应用场景 其他设计模式文章: 定义 观察者模式是行为型模式的一种,它定义对象间的一种一对多的依赖关系,使得每当一个对象改变状态,它…...
【面试系列】C++ 高频面试题
欢迎来到我的博客,很高兴能够在这里和您见面!欢迎订阅相关专栏: ⭐️ 全网最全IT互联网公司面试宝典:收集整理全网各大IT互联网公司技术、项目、HR面试真题. ⭐️ AIGC时代的创新与未来:详细讲解AIGC的概念、核心技术、…...
程序猿大战Python——实现简单的图书馆系统操作
步骤1:安装和导入库 首先,确保已经安装了 pymysql 库。如果没有安装,请执行以下命令: pip install pymysql 然后,导入必要的库: import pymysql 步骤2:创建数据库和表的函数 编写一个函数来…...
液体粒子计数器的原理及常见型号选择 lighthouse代理商北京中邦兴业
液体颗粒计数用于测量液体样品中颗粒的大小和分布。通过用激光二极管照射液体样品并检测散射光来测量颗粒分布和尺寸。散射光的性质与粒子大小的大小有关。液体颗粒计数器可用于批量取样或在线(连续监测)应用,如水处理厂,或用于…...
Java知识点整理 16 — Spring Bean
在之前的文章 Java知识点整理 8 — Spring 简介 中介绍了 Spring 的两大核心概念 IoC 和 AOP,但对 Spring Bean 的介绍不全面,本文将补充 Spring 中 Bean 的概念。 一. 什么是 Spring Bean 在 Spring 官方文档中,对 bean 的定义为…...
Nvidia Jetson/RK3588+AI双目立体相机,适合各种割草机器人、扫地机器人、AGV等应用
双目立体视觉是基于视差原理,依据成像设备从不同位置获取的被测物体的图像,匹配对应点的位置偏移,得到视差数据,进而计算物体的空间三维信息。为您带来高图像质量的双目立体相机,具有高分辨率、低功耗、远距离等优点&a…...
springboot使用feign调用不依赖cloud
在使用spring boot调用第三方api中,常用的是okhttp、apache http client等,但是直接使用下来还是有点繁琐,需要手动转换实体。 在springcloud中有个openfeign调用,第一次体验到调用接口还能这么丝滑。注解写道接口上,…...
springboot中使用springboot cache
前言:SpringBoot中使用Cache缓存可以提高对缓存的开发效率 此图片是SpringBootCache常用注解 Springboot Cache中常用注解 第一步:引入依赖 <!--缓存--><dependency><groupId>org.springframework.boot</groupId><artifactId…...
Promise,async/await的运用
一,了解Promise Promise是异步编程的一种解决方案,它是一个对象,可以获取异步操作的消息,它的出现避免了地狱回调。 (1)Promise的实例有三个状态: Pending(进行中) Re…...
图论·多源最短路径Floyddijsktra
例题地址 多源最短路径 多个源点多个终点可以使用Floyd算法直接求各源点到终点的最短距离,也可以直接多次使用dijsktra算法求单源点到终点的最短距离 Floyd算法 使用条件 多源最短路径权值正负皆可 核心思想:动态规划 子问题: 设(A,B)…...
微服务 | Springboot整合GateWay+Nacos实现动态路由
1、简介 路由转发 执行过滤器链。 网关,旨在为微服务架构提供一种简单有效的统一的API路由管理方式。同时,基于Filter链的方式提供了网关的基本功能,比如:鉴权、流量控制、熔断、路径重写、黑白名单、日志监控等。 基本功能…...
做google SEO 有哪些好用的工具?这12款谷歌SEO工具值得收藏!
1、Google Trends 谷歌旗下一款基于搜索数据推出的一款免费分析工具 外贸人有句老话,七分靠选品,三分靠运营。在你开始做独立站之前,在你不清楚你的行业在Google上面能否有足够的流量时,那么Google Trends则是你最好的工具。 你只…...
【变频调速在锅炉引风机控制中的应用】
变频调速在锅炉引风机控制中的应用 变频器的选型 变频器是利用电力半导体器件的通断作用将工频电源变换为另一种频率的电能控制装置,能宏观对交流异步电机软启动,变频调速,提高运转精度,改变功率因数,过流/过压/过载保护等功能,国内技术较领先的品牌有汇川、欧瑞(原烟台…...
网络配置(IP、NETMASK、GATEWAY、DNS、DHCP) <持续更新中>
参考: 初学Linux之网络配置(IP、NETMASK、GATEWAY、DNS、DHCP)-CSDN博客【学习笔记】网关 & 路由_网关和路由-CSDN博客【学习笔记】计算机网络 IP地址与MAC地址_根据mac分配ip-CSDN博客【学习笔记】TCP 和 UDP 协议_tcp 发送 syn 应答没有syn ack-CSDN博客 一…...
【ArcGIS 脚本工具】拯救密恐,隐藏唯一值渲染图层的标记符号
最近拿到了【Hello 图狗】制作的三调/变更样式符号库,确实比之前网上下载的版本好用很多。 ArcGIS Pro三调23变更符号库V1.02(汇总)_中大比例尺.stylx和样式属性对调 不过使用过程中触发了一个旧病,就是匹配样式之后,…...
tensorflow学习1.3-创建会话,启动会话
tensorflow学习1.3-创建会话,启动会话 会话的由来与作用由来作用 会话的定义与结构定义 用法基本用法上下文管理器执行部分计算图获取多个结果 总结 练习代码报错原因:TensorFlow 2.x中的Eager Execution使用兼容模式来启用SessionEager Execution和计算…...
QT基本对话框(基本对话框、工具盒类、进度条、调色板与电子钟、可扩展对话框、程序启动画面)
此篇文章通过实例介绍基本对话框的用法。首先介绍标准文件对话框(QFileDialog)、标准颜色对话框(QColorDialog)、标准字体对话框(QFontDialog)、标准输入对话框(QInputDialog)以及标…...
IDEA运行Tomcat出现乱码问题解决汇总
最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…...
linux之kylin系统nginx的安装
一、nginx的作用 1.可做高性能的web服务器 直接处理静态资源(HTML/CSS/图片等),响应速度远超传统服务器类似apache支持高并发连接 2.反向代理服务器 隐藏后端服务器IP地址,提高安全性 3.负载均衡服务器 支持多种策略分发流量…...
使用VSCode开发Django指南
使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架,专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用,其中包含三个使用通用基本模板的页面。在此…...
day52 ResNet18 CBAM
在深度学习的旅程中,我们不断探索如何提升模型的性能。今天,我将分享我在 ResNet18 模型中插入 CBAM(Convolutional Block Attention Module)模块,并采用分阶段微调策略的实践过程。通过这个过程,我不仅提升…...
高频面试之3Zookeeper
高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个?3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制(过半机制࿰…...
转转集团旗下首家二手多品类循环仓店“超级转转”开业
6月9日,国内领先的循环经济企业转转集团旗下首家二手多品类循环仓店“超级转转”正式开业。 转转集团创始人兼CEO黄炜、转转循环时尚发起人朱珠、转转集团COO兼红布林CEO胡伟琨、王府井集团副总裁祝捷等出席了开业剪彩仪式。 据「TMT星球」了解,“超级…...
第25节 Node.js 断言测试
Node.js的assert模块主要用于编写程序的单元测试时使用,通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试,通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...
Cloudflare 从 Nginx 到 Pingora:性能、效率与安全的全面升级
在互联网的快速发展中,高性能、高效率和高安全性的网络服务成为了各大互联网基础设施提供商的核心追求。Cloudflare 作为全球领先的互联网安全和基础设施公司,近期做出了一个重大技术决策:弃用长期使用的 Nginx,转而采用其内部开发…...
Map相关知识
数据结构 二叉树 二叉树,顾名思义,每个节点最多有两个“叉”,也就是两个子节点,分别是左子 节点和右子节点。不过,二叉树并不要求每个节点都有两个子节点,有的节点只 有左子节点,有的节点只有…...
Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决
Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决 问题背景 在一个基于 Spring Cloud Gateway WebFlux 构建的微服务项目中,新增了一个本地验证码接口 /code,使用函数式路由(RouterFunction)和 Hutool 的 Circle…...
