-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.go
127 lines (99 loc) · 2.55 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
package main
import (
"bufio"
"flag"
"fmt"
"net/http"
"os"
"sync"
"time"
)
var checkedLines int
var mu sync.Mutex
func main() {
var inputFileName string
var numThreads int
flag.StringVar(&inputFileName, "f", "", "Path to the file containing domains")
flag.IntVar(&numThreads, "t", 1, "Number of threads")
flag.Parse()
if inputFileName == "" {
fmt.Println("Please provide a valid filename using the -f option")
return
}
customTextDone := make(chan bool)
go displayCustomText(customTextDone)
<-customTextDone
file, err := os.Open(inputFileName)
if err != nil {
fmt.Printf("Error opening the file: %v\n", err)
return
}
defer file.Close()
scanner := bufio.NewScanner(file)
var wg sync.WaitGroup
concurrencyLimit := make(chan struct{}, numThreads)
totalLines := 0
for scanner.Scan() {
totalLines++
}
file.Seek(0, 0)
scanner = bufio.NewScanner(file)
progressFormat := "Progress: [%s] %d/%d"
loadingChars := []string{"|", "/", "-", "\\"}
fmt.Printf(progressFormat, " ", checkedLines, totalLines)
for scanner.Scan() {
domain := scanner.Text()
if domain != "" {
wg.Add(1)
concurrencyLimit <- struct{}{}
go func(domain string) {
defer func() {
<-concurrencyLimit
wg.Done()
mu.Lock()
checkedLines++
progress := loadingChars[checkedLines%len(loadingChars)]
fmt.Printf(progressFormat+"\r", progress, checkedLines, totalLines)
mu.Unlock()
}()
checkSecurityHeaders(domain)
}(domain)
}
}
wg.Wait()
if err := scanner.Err(); err != nil {
fmt.Printf("Error reading the file: %v\n", err)
}
fmt.Println("\nDone!")
}
func displayCustomText(customTextDone chan<- bool) {
customText := "Made with ˗ˋˏ ♡ ˎˊ˗ by GrozdniyAndy of XSS.is"
for i := 0; i <= len(customText); i++ {
fmt.Print("\r" + customText[:i] + "_")
time.Sleep(100 * time.Millisecond)
}
fmt.Print("\r" + customText)
time.Sleep(1000 * time.Millisecond)
customTextDone <- true
fmt.Println("")
}
func checkSecurityHeaders(domain string) {
checkURL(domain, "http")
checkURL(domain, "https")
}
func checkURL(domain, protocol string) {
url := protocol + "://" + domain
client := &http.Client{
Timeout: 3 * time.Second,
}
resp, err := client.Get(url)
if err != nil {
return
}
defer resp.Body.Close()
contentSecurityPolicy := resp.Header.Get("Content-Security-Policy")
xFrameOptions := resp.Header.Get("X-Frame-Options")
if contentSecurityPolicy == "" && xFrameOptions == "" {
fmt.Printf("Success: %s - %s - Headers not found (Content-Security-Policy and X-Frame-Options)\n", domain, protocol)
}
}