内容简介:功能:可以快速扫描指定端口范围,ip地址范围。将扫描结果保存到本地!先来体验一下运行后的效果:
功能:可以快速扫描指定端口范围,ip地址范围。将扫描结果保存到本地!先来体验一下运行后的效果:
帮助信息
scanPort -h Options: -h 帮助信息 -ip string ip地址 例如:-ip 192.168.0.1-255 或直接输入域名 xs25.cn (default "127.0.0.1") -n int 进程数 例如:-n 10 (default 100) -p string 端口号范围 例如:-p 80,81,88-1000 (default "80") -path string 日志地址 例如:-path log (default "log") -t int 超时时长(毫秒) 例如:-t 200 (default 200)
例1:指定端口号扫描,如我们要扫描xs25.cn这台服务的开放端口,使用1000个协程进行
scanport -p 80,81,88-3306 -ip xs25.cn -n 1000
例2:指定IP范围扫描,如我们扫描 192.168.0.1-255 网段的端口 80-10000
scanPort -ip 192.168.0.1-255 -p 80-10000
注:程序扫描完后开放端口放在log目录中,如想更改目录名请加 -path 参数来指定
具体代码如下
详细代码见: https://github.com/xs25cn/scanPort main.go 文件:
package main import ( "flag" "fmt" "os" "github.com/xs25cn/scanPort/lib" "github.com/xs25cn/scanPort/scan" "time" ) var ( startTime = time.Now() ip = flag.String("ip", "127.0.0.1", "ip地址 例如:-ip=192.168.0.1-255 或直接输入域名 xs25.cn") port = flag.String("p", "80-1000", "端口号范围 例如:-p=80,81,88-1000") path = flag.String("path", "log", "日志地址 例如:-path=log") timeout = flag.Int("t", 200, "超时时长(毫秒) 例如:-t=200") process = flag.Int("n", 100, "进程数 例如:-n=10") h = flag.Bool("h", false, "帮助信息") ) //go run main.go -h func main() { flag.Parse() //帮助信息 if *h == true { lib.Usage("scanPort version: scanPort/1.10.0\n Usage: scanPort [-h] [-ip ip地址] [-n 进程数] [-p 端口号范围] [-t 超时时长] [-path 日志保存路径]\n\nOptions:\n") return } fmt.Printf("========== Start %v ip:%v,port:%v ==================== \n", time.Now().Format("2006-01-02 15:04:05"), *ip, *port) //创建目录 lib.Mkdir(*path) //初始化 scanIP := scan.ScanIp{ Debug: true, Timeout: *timeout, Process: *process, } ips, err := scanIP.GetAllIp(*ip) if err != nil { fmt.Println(err.Error()) return } //扫所有的ip fileName := *path + "/" + *ip + "_port.txt" for i := 0; i < len(ips); i++ { ports := scanIP.GetIpOpenPort(ips[i], *port) if len(ports) > 0 { f, err := os.OpenFile(fileName, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666) if err != nil { if err := f.Close(); err != nil { fmt.Println(err) } continue } var str = fmt.Sprintf("%v ip:%v,开放端口:%v \n", time.Now().Format("2006-01-02 15:04:05"), ips[i], ports) if _, err := f.WriteString(str); err != nil { if err := f.Close(); err != nil { fmt.Println(err) } continue } } } fmt.Printf("========== End %v 总执行时长:%.2fs ================ \n", time.Now().Format("2006-01-02 15:04:05"), time.Since(startTime).Seconds()) }
scan.go 文件
package scan import ( "errors" "fmt" "math" "net" "os" "strconv" "strings" "sync" "time" ) //ip 扫描 type ScanIp struct { Debug bool Timeout int Process int } //获取开放端口号 func (s *ScanIp) GetIpOpenPort(ip string, port string) []int { var ( total int pageCount int num int openPorts []int mutex sync.Mutex ) ports, _ := s.getAllPort(port) total = len(ports) if total < s.Process { pageCount = total } else { pageCount = s.Process } num = int(math.Ceil(float64(total) / float64(pageCount))) s.sendLog(fmt.Sprintf("%v 【%v】需要扫描端口总数:%v 个,总协程:%v 个,每个协程处理:%v 个,超时时间:%v毫秒", time.Now().Format("2006-01-02 15:04:05"), ip, total, pageCount, num, s.Timeout)) start := time.Now() all := map[int][]int{} for i := 1; i <= pageCount; i++ { for j := 0; j < num; j++ { tmp := (i-1)*num + j if tmp < total { all[i] = append(all[i], ports[tmp]) } } } wg := sync.WaitGroup{} for k, v := range all { wg.Add(1) go func(value []int, key int) { defer wg.Done() var tmpPorts []int for i := 0; i < len(value); i++ { opened := s.isOpen(ip, value[i]) if opened { tmpPorts = append(tmpPorts, value[i]) } } mutex.Lock() openPorts = append(openPorts, tmpPorts...) mutex.Unlock() if len(tmpPorts) > 0 { s.sendLog(fmt.Sprintf("%v 【%v】协程%v 执行完成,时长: %.3fs,开放端口: %v", time.Now().Format("2006-01-02 15:04:05"), ip, key, time.Since(start).Seconds(), tmpPorts)) } }(v, k) } wg.Wait() s.sendLog(fmt.Sprintf("%v 【%v】扫描结束,执行时长%.3fs , 所有开放的端口:%v", time.Now().Format("2006-01-02 15:04:05"), ip, time.Since(start).Seconds(), openPorts)) time.Sleep(time.Second * 1) return openPorts } //获取所有ip func (s *ScanIp) GetAllIp(ip string) ([]string, error) { var ( ips []string ) ipTmp := strings.Split(ip, "-") firstIp, err := net.ResolveIPAddr("ip", ipTmp[0]) if err != nil { return ips, errors.New(ipTmp[0] + "域名解析失败" + err.Error()) } if net.ParseIP(firstIp.String()) == nil { return ips, errors.New(ipTmp[0] + " ip地址有误~") } //域名转化成ip再塞回去 ipTmp[0] = firstIp.String() ips = append(ips, ipTmp[0]) //最少有一个ip地址 if len(ipTmp) == 2 { //以切割第一段ip取到最后一位 ipTmp2 := strings.Split(ipTmp[0], ".") startIp, _ := strconv.Atoi(ipTmp2[3]) endIp, err := strconv.Atoi(ipTmp[1]) if err != nil || endIp < startIp { endIp = startIp } if endIp > 255 { endIp = 255 } totalIp := endIp - startIp + 1 for i := 1; i < totalIp; i++ { ips = append(ips, fmt.Sprintf("%s.%s.%s.%d", ipTmp2[0], ipTmp2[1], ipTmp2[2], startIp+i)) } } return ips, nil } //记录日志 func (s *ScanIp) sendLog(str string) { if s.Debug == true { fmt.Println(str) } } //获取所有端口 func (s *ScanIp) getAllPort(port string) ([]int, error) { var ports []int //处理 ","号 如 80,81,88 或 80,88-100 portArr := strings.Split(strings.Trim(port, ","), ",") for _, v := range portArr { portArr2 := strings.Split(strings.Trim(v, "-"), "-") startPort, err := s.filterPort(portArr2[0]) if err != nil { continue } //第一个端口先添加 ports = append(ports, startPort) if len(portArr2) > 1 { //添加第一个后面的所有端口 endPort, _ := s.filterPort(portArr2[1]) if endPort > startPort { for i := 1; i <= endPort-startPort; i++ { ports = append(ports, startPort+i) } } } } //去重复 ports = s.arrayUnique(ports) return ports, nil } //端口合法性过滤 func (s *ScanIp) filterPort(str string) (int, error) { port, err := strconv.Atoi(str) if err != nil { return 0, err } if port < 1 || port > 65535 { return 0, errors.New("端口号范围超出") } return port, nil } //查看端口号是否打开 func (s *ScanIp) isOpen(ip string, port int) bool { conn, err := net.DialTimeout("tcp", fmt.Sprintf("%s:%d", ip, port), time.Millisecond*time.Duration(s.Timeout)) if err != nil { if strings.Contains(err.Error(),"too many open files"){ fmt.Println("连接数超出系统限制!"+err.Error()) os.Exit(1) } return false } _ = conn.Close() return true } //数组去重 func (s *ScanIp) arrayUnique(arr []int) []int { var newArr []int for i := 0; i < len(arr); i++ { repeat := false for j := i + 1; j < len(arr); j++ { if arr[i] == arr[j] { repeat = true break } } if !repeat { newArr = append(newArr, arr[i]) } } return newArr }
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- XSS 扫描器成长记
- 手动编译高速扫描器MasScan
- 漏洞扫描器 hang 住 case 复盘
- 修改CppCheck,做自己的扫描器 - 01
- 修改CppCheck,做自己的扫描器 - 02
- Python实现FTP弱口令扫描器
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
计数组合学(第一卷)
斯坦利 / 付梅、侯庆虎、辛国策 / 高等教育 / 2009-6 / 42.00元
《计数组合学(第1卷)》是两卷本计数组合学基础导论中的第一卷,适用于研究生和数学研究人员。《计数组合学(第1卷)》主要介绍生成函数的理论及其应用,生成函数是计数组合学中的基本工具。《计数组合学(第1卷)》共分为四章,分别介绍了计数(适合高年级的本科生),筛法(包括容斥原理),偏序集以及有理生成函数。《计数组合学(第1卷)》提供了大量的习题,并几乎都给出了解答,它们不仅是对《计数组合学(第1卷)》正......一起来看看 《计数组合学(第一卷)》 这本书的介绍吧!