This repository was archived by the owner on Aug 4, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.go
194 lines (180 loc) · 4.44 KB
/
main.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
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
// iot_detector project main.go
package main
import (
"bufio"
"bytes"
"crypto/tls"
"flag"
"fmt"
"io"
"io/ioutil"
"net"
"net/http"
"os"
"runtime"
"strings"
"sync"
"time"
)
type ListItem struct {
ip string
port string
}
type OutputStruct struct {
thread_id int
ip string
port string
answer string
}
var (
THREADS_COUNT int
VERBOSE bool
GLOBAL_REQUEST Request
AUTOSCHEME bool
scheme_array = []string{"http://", "https://"}
PORTS string
)
func request(target string, port string, client *http.Client) (string, bool) {
var t = &http.Transport{
Dial: (&net.Dialer{
Timeout: 5 * time.Second,
}).Dial,
TLSHandshakeTimeout: 5 * time.Second,
}
if strings.Contains("https", target) {
t.TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
t.MaxIdleConns = 10
t.IdleConnTimeout = 30 * time.Second
}
client.Transport = t
// build a new request, but not doing the POST yet
url := fmt.Sprintf("%s:%s%s", target, port, GLOBAL_REQUEST.Path)
// Check POST and GET requests
var req *http.Request
var err error
if GLOBAL_REQUEST.Method == "POST" {
req, err = http.NewRequest(GLOBAL_REQUEST.Method, url, bytes.NewBuffer([]byte(GLOBAL_REQUEST.Data)))
} else if GLOBAL_REQUEST.Method == "GET" {
if len(GLOBAL_REQUEST.Data) > 0 {
url += "?" + GLOBAL_REQUEST.Data
}
req, err = http.NewRequest(GLOBAL_REQUEST.Method, url, nil)
} else {
return "[WRONG METHOD]", false
}
if err != nil {
return "[ERROR CONNECT]", false
}
// Insert header items
for header := range GLOBAL_REQUEST.Headers {
req.Header.Add(header, GLOBAL_REQUEST.Headers[header])
}
// now POST it
resp, err := client.Do(req)
if err != nil {
return fmt.Sprintf("[NO RESPONSE] => %s", err.Error()), false
}
defer resp.Body.Close()
if resp.StatusCode != 200 {
return "[WRONG RESPONSE]", false
}
answer, err := ioutil.ReadAll(resp.Body)
_, _ = io.Copy(io.Discard, resp.Body) // Discard the body
if searchPatterns(string(answer), GLOBAL_REQUEST.Search) {
return "[SUCCESS]", true
}
return "[NOT DETECTED]", false
}
func worker(thread_num int, jobs chan ListItem, wg *sync.WaitGroup, output chan OutputStruct, c *http.Client) {
var answer, host string
var status bool
var result OutputStruct
for v := range jobs {
status = false
answer = ""
if portCheck(v.ip, v.port) {
if AUTOSCHEME {
for _, scheme := range scheme_array {
host = scheme + v.ip
answer, status = request(host, v.port, c)
if status {
break
}
}
} else {
answer, status = request(v.ip, v.port, c)
}
}
if status || VERBOSE {
result.answer = answer
result.ip = v.ip
result.port = v.port
result.thread_id = thread_num
output <- result
}
}
wg.Done()
}
func main() {
var iplist string
var request_file string
flag.IntVar(&THREADS_COUNT, "t", 1000, "Thread count")
flag.StringVar(&iplist, "l", "", "List of ip or ip,port")
flag.StringVar(&request_file, "r", "", "Json request file")
flag.BoolVar(&VERBOSE, "v", true, "Verbose")
flag.BoolVar(&AUTOSCHEME, "a", false, "Auto URL scheme")
flag.StringVar(&PORTS, "p", "", "Ports to scan (e.g. 22,80,443,1000-2000)")
flag.Parse()
// Use maximum numbers of CPU
numcpu := runtime.NumCPU()
fmt.Println("NumCPU", numcpu)
runtime.GOMAXPROCS(1)
// Parse input request file
if err := GLOBAL_REQUEST.loadRequestFromFile(request_file); err != nil {
fmt.Println("Error:", err)
return
}
jobs := make(chan ListItem, 100)
wg := sync.WaitGroup{}
output := make(chan OutputStruct)
client := &http.Client{
Timeout: 5 * time.Second,
}
for i := 1; i < THREADS_COUNT; i++ {
go worker(i, jobs, &wg, output, client)
wg.Add(1)
}
file, err := os.Open(iplist)
if err != nil {
panic(err)
}
defer file.Close()
// print output
go func() {
for line := range output {
fmt.Printf("{%d}\t%s\t%s\t%s\n", line.thread_id, line.ip, line.port, line.answer)
}
}()
scanner := bufio.NewScanner(file)
// Parser for input ports
ports := parsePorts(PORTS)
// Input list scanner
for scanner.Scan() {
line := strings.TrimSpace(scanner.Text())
if strings.Contains(line, ",") {
// Split line from file by host:port and create a task
host_port := strings.Split(line, ",")
item := ListItem{ip: host_port[0], port: host_port[1]}
jobs <- item
} else {
// Generate tasks for single host and multiple ports
for _, port := range ports {
item := ListItem{ip: line, port: fmt.Sprint(port)}
jobs <- item
}
}
}
close(jobs)
wg.Wait()
close(output)
}