Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
projectdiscovery
GitHub Repository: projectdiscovery/nuclei
Path: blob/dev/pkg/protocols/utils/variables.go
2070 views
1
package utils
2
3
import (
4
"fmt"
5
"path"
6
"strings"
7
8
"github.com/projectdiscovery/gologger"
9
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/contextargs"
10
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/generators"
11
maputil "github.com/projectdiscovery/utils/maps"
12
urlutil "github.com/projectdiscovery/utils/url"
13
"github.com/weppos/publicsuffix-go/publicsuffix"
14
)
15
16
// KnownVariables are the variables that are known to input requests
17
var KnownVariables maputil.Map[KnownVariable, string]
18
19
func init() {
20
KnownVariables = maputil.Map[KnownVariable, string]{
21
BaseURL: "BaseURL",
22
RootURL: "RootURL",
23
Hostname: "Hostname",
24
Host: "Host",
25
Port: "Port",
26
Path: "Path",
27
Query: "Query",
28
File: "File",
29
Scheme: "Scheme",
30
Input: "Input",
31
Fqdn: "FQDN",
32
Rdn: "RDN",
33
Dn: "DN",
34
Tld: "TLD",
35
Sd: "SD",
36
}
37
}
38
39
type KnownVariable uint16
40
41
const (
42
BaseURL KnownVariable = iota
43
RootURL
44
Hostname
45
Host
46
Port
47
Path
48
Query
49
File
50
Scheme
51
Input
52
Fqdn
53
Rdn
54
Dn
55
Tld
56
Sd
57
)
58
59
// GenerateVariablesWithContextArgs will create default variables with context args
60
func GenerateVariablesWithContextArgs(input *contextargs.Context, trailingSlash bool) map[string]interface{} {
61
parsed, err := urlutil.Parse(input.MetaInput.Input)
62
if err != nil {
63
return nil
64
}
65
return GenerateVariables(parsed, trailingSlash, contextargs.GenerateVariables(input))
66
}
67
68
// GenerateDNSVariables from a dns name
69
// This function is used by dns and ssl protocol to generate variables
70
func GenerateDNSVariables(domain string) map[string]interface{} {
71
parsed, err := publicsuffix.Parse(strings.TrimSuffix(domain, "."))
72
if err != nil {
73
return map[string]interface{}{"FQDN": domain}
74
}
75
76
domainName := strings.Join([]string{parsed.SLD, parsed.TLD}, ".")
77
dnsVariables := make(map[string]interface{})
78
for k, v := range KnownVariables {
79
switch k {
80
case Fqdn:
81
dnsVariables[v] = domain
82
case Rdn:
83
dnsVariables[v] = domainName
84
case Dn:
85
dnsVariables[v] = parsed.SLD
86
case Tld:
87
dnsVariables[v] = parsed.TLD
88
case Sd:
89
dnsVariables[v] = parsed.TRD
90
}
91
}
92
return dnsVariables
93
}
94
95
// GenerateVariables accepts string or *urlutil.URL object as input
96
// Returns the map of KnownVariables keys
97
// This function is used by http, headless, websocket, network and whois protocols to generate protocol variables
98
func GenerateVariables(input interface{}, removeTrailingSlash bool, additionalVars map[string]interface{}) map[string]interface{} {
99
var vars = make(map[string]interface{})
100
switch input := input.(type) {
101
case string:
102
parsed, err := urlutil.Parse(input)
103
if err != nil {
104
return map[string]interface{}{KnownVariables[Input]: input, KnownVariables[Hostname]: input}
105
}
106
vars = generateVariables(parsed, removeTrailingSlash)
107
case *urlutil.URL:
108
vars = generateVariables(input, removeTrailingSlash)
109
case urlutil.URL:
110
vars = generateVariables(&input, removeTrailingSlash)
111
default:
112
// return a non-fatal error
113
gologger.Error().Msgf("unknown type %T for input %v", input, input)
114
}
115
return generators.MergeMaps(vars, additionalVars)
116
}
117
118
func generateVariables(inputURL *urlutil.URL, removeTrailingSlash bool) map[string]interface{} {
119
parsed := inputURL.Clone()
120
parsed.Params = urlutil.NewOrderedParams()
121
port := parsed.Port()
122
if port == "" {
123
switch parsed.Scheme {
124
case "https":
125
port = "443"
126
case "http":
127
port = "80"
128
}
129
}
130
if removeTrailingSlash {
131
parsed.Path = strings.TrimSuffix(parsed.Path, "/")
132
}
133
escapedPath := parsed.EscapedPath()
134
requestPath := path.Dir(escapedPath)
135
if requestPath == "." {
136
requestPath = ""
137
}
138
139
base := path.Base(escapedPath)
140
if base == "." {
141
base = ""
142
}
143
144
if parsed.Scheme == "ws" {
145
if values := urlutil.GetParams(parsed.URL.Query()); len(values) > 0 {
146
requestPath = escapedPath + "?" + values.Encode()
147
}
148
}
149
knownVariables := make(map[string]interface{})
150
for k, v := range KnownVariables {
151
switch k {
152
case BaseURL:
153
knownVariables[v] = parsed.String()
154
case RootURL:
155
if parsed.Scheme != "" {
156
knownVariables[v] = fmt.Sprintf("%s://%s", parsed.Scheme, parsed.Host)
157
} else {
158
knownVariables[v] = parsed.Host
159
}
160
case Hostname:
161
knownVariables[v] = parsed.Host
162
case Host:
163
knownVariables[v] = parsed.Hostname()
164
case Port:
165
knownVariables[v] = port
166
case Path:
167
knownVariables[v] = requestPath
168
case Query:
169
if queryParams := urlutil.GetParams(parsed.URL.Query()); len(queryParams) > 0 {
170
knownVariables[v] = "?" + queryParams.Encode()
171
} else {
172
knownVariables[v] = ""
173
}
174
case File:
175
knownVariables[v] = base
176
case Scheme:
177
knownVariables[v] = parsed.Scheme
178
case Input:
179
knownVariables[v] = parsed.String()
180
}
181
}
182
return generators.MergeMaps(knownVariables, GenerateDNSVariables(parsed.Hostname()))
183
}
184
185