-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathnmap-sV.go
145 lines (128 loc) · 3.44 KB
/
nmap-sV.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
package main
import (
"bufio"
_ "embed"
"encoding/json"
"flag"
"fmt"
"io"
"os"
"strings"
"sync"
"time"
"github.com/WHIJK/nmap-sV/core"
"github.com/WHIJK/nmap-sV/core/model"
"github.com/WHIJK/nmap-sV/core/util"
"github.com/WHIJK/nmap-sV/option"
"github.com/projectdiscovery/gologger"
)
const version = "1.6.1"
// 并发,线程池
var jobsChannel = make(chan string, 100)
var bannerChannel = make(chan string, 100)
var portList = make([]string, 0) // 端口符合,优先发送
var bannerStruct model.BannerResult
// 任务创建
func createJobs(s *bufio.Scanner) {
var batch []string
taskCount := 0 // 用于统计任务数量
for s.Scan() {
line := strings.TrimSpace(s.Text())
if line != "" {
batch = append(batch, line)
if len(batch) >= 100 { // 每 100 条任务批量发送
for _, job := range batch {
jobsChannel <- job
taskCount++ // 每发送一个任务,计数器加 1
}
batch = nil
}
}
}
// 处理剩余未发送的任务
for _, job := range batch {
jobsChannel <- job
taskCount++ // 计数器加 1
}
close(jobsChannel)
gologger.Info().Msgf("Total tasks created: %d\n", taskCount) // 打印任务总数
}
// 输出
func printBanner(done chan bool) {
for v := range bannerChannel {
if option.File != "" {
util.W2json(v)
}
json.Unmarshal([]byte(v), &bannerStruct)
print_info := fmt.Sprintf("%-10s %s ", bannerStruct.Address, bannerStruct.Service)
if option.Info {
print_info = util.BufferJoin([]string{print_info, " (", bannerStruct.Banner.Vendorproductname})
if bannerStruct.Banner.Version != "" {
print_info = util.BufferJoin([]string{print_info, " ", bannerStruct.Banner.Version, ") "})
} else {
print_info = util.BufferJoin([]string{print_info, ") ", bannerStruct.Banner.Operatingsystem})
}
}
if option.Banner {
print_info = util.BufferJoin([]string{print_info, " ", bannerStruct.Banner.BannerPrint})
}
if option.Pattern {
print_info = util.BufferJoin([]string{print_info, " ", bannerStruct.Pattern})
}
if bannerStruct.Banner.Extra != "" {
print_info = util.BufferJoin([]string{print_info, " ", bannerStruct.Banner.Extra})
}
fmt.Println(print_info)
}
done <- true
}
// 创建线程池
func createPool(threads int) {
var wg sync.WaitGroup
for i := 0; i < threads; i++ {
wg.Add(1)
go worker(&wg)
}
wg.Wait()
close(bannerChannel)
}
// 执行任务
func worker(wg *sync.WaitGroup) {
defer wg.Done()
for v := range jobsChannel {
core.Run(v, bannerChannel, option.TaskNumber, !option.Script)
}
}
func init() {
flag.Usage = func() {
fmt.Fprintf(os.Stderr, "%s Usage: %s [options]\n", version, os.Args[0])
fmt.Println("Options:")
flag.PrintDefaults()
}
flag.Parse()
}
func main() {
stat, _ := os.Stdin.Stat()
if (stat.Mode()&os.ModeCharDevice) != 0 && option.Host == "" {
fmt.Fprintln(os.Stderr, "No input detected. Hint: cat ip:port.txt | nmap-sV")
os.Exit(1)
}
var inputReader io.Reader
if option.Host != "" && (stat.Mode()&os.ModeCharDevice) != 0 {
inputReader = io.MultiReader(strings.NewReader(option.Host+"\n"), os.Stdin)
} else if option.Host != "" {
inputReader = io.MultiReader(strings.NewReader(option.Host + "\n"))
} else {
inputReader = os.Stdin
}
s := bufio.NewScanner(inputReader)
startTime := time.Now()
go createJobs(s)
done := make(chan bool)
go printBanner(done)
createPool(option.Threads)
<-done
endTime := time.Now()
diffTime := endTime.Sub(startTime).Seconds()
fmt.Printf("\nTake %f seconds", diffTime)
}