文章目录
前言
为什么要写这个?
- 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 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 {