Skip to content

Commit ec7c12d

Browse files
committed
Initial commit
0 parents  commit ec7c12d

File tree

4 files changed

+181
-0
lines changed

4 files changed

+181
-0
lines changed

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
.idea
2+
domains.txt
3+
wordlist.txt
4+
out.txt

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2021 Nenad Popovic
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
mkpath
2+
------
3+
Make paths using a wordlist
4+
5+
Read a wordlist file and generate paths for given domain or list of domains.
6+
Input from wordlist file is lowercased and unique words are processed. Additionally, wordlist can be
7+
filtered using regex.
8+
9+
```
10+
Usage of mksub:
11+
-d string
12+
Input domain
13+
-df string
14+
Input domain file, one domain per line
15+
-l int
16+
Path level to generate (default 1) (default 1)
17+
-o string
18+
Output file (optional)
19+
-r string
20+
Regex to filter words from wordlist file
21+
-w string
22+
Wordlist file
23+
```
24+
25+
### Example
26+
27+
##### wordlist.txt
28+
```
29+
dev
30+
DEV
31+
*
32+
foo/bar
33+
prod
34+
```
35+
```shell script
36+
> go run mksub.go -d example.com -l 2 -w input.txt -r "^[a-zA-Z0-9\.-_]+$"
37+
example.com/dev/
38+
example.com/foo/bar/
39+
example.com/prod/
40+
example.com/foo/bar/dev/
41+
example.com/prod/dev/
42+
example.com/dev/dev/
43+
example.com/dev/foo/bar/
44+
example.com/foo/bar/foo/bar/
45+
example.com/prod/foo/bar/
46+
example.com/dev/prod/
47+
example.com/foo/bar/prod/
48+
example.com/prod/prod/
49+
50+
```

mkpath.go

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
package main
2+
3+
import (
4+
"bufio"
5+
"flag"
6+
"fmt"
7+
"os"
8+
"regexp"
9+
"strings"
10+
)
11+
12+
func main() {
13+
domain := flag.String("d", "", "Input domain")
14+
domainFile := flag.String("df", "", "Input domain file, one domain per line")
15+
wordlist := flag.String("w", "", "Wordlist file")
16+
r := flag.String("r", "", "Regex to filter words from wordlist file")
17+
level := flag.Int("l", 1, "Subdomain level to generate (default 1)")
18+
output := flag.String("o", "", "Output file (optional)")
19+
flag.Parse()
20+
21+
inputDomains := make([]string, 0)
22+
if *domain != "" {
23+
inputDomains = append(inputDomains, *domain)
24+
}
25+
if *domainFile != "" {
26+
inputFile, err := os.Open(*domainFile)
27+
if err != nil {
28+
fmt.Println(err.Error())
29+
os.Exit(1)
30+
}
31+
defer inputFile.Close()
32+
scanner := bufio.NewScanner(inputFile)
33+
for scanner.Scan() {
34+
inputDomains = append(inputDomains, scanner.Text())
35+
}
36+
}
37+
if len(inputDomains) == 0 {
38+
fmt.Println("No input provided")
39+
os.Exit(1)
40+
}
41+
42+
wordlistFile, err := os.Open(*wordlist)
43+
if err != nil {
44+
fmt.Println(err.Error())
45+
os.Exit(1)
46+
}
47+
defer wordlistFile.Close()
48+
49+
var reg *regexp.Regexp
50+
if *r != "" {
51+
reg, err = regexp.Compile(*r)
52+
if err != nil {
53+
fmt.Println(err.Error())
54+
os.Exit(1)
55+
}
56+
}
57+
58+
var outputFile *os.File
59+
if *output != "" {
60+
outputFile, err = os.Create(*output)
61+
if err != nil {
62+
fmt.Println(err.Error())
63+
os.Exit(1)
64+
}
65+
defer outputFile.Close()
66+
}
67+
68+
wordSet := make(map[string]bool)
69+
scanner := bufio.NewScanner(wordlistFile)
70+
71+
for scanner.Scan() {
72+
word := strings.ToLower(scanner.Text())
73+
if reg != nil {
74+
if !reg.Match([]byte(word)) {
75+
continue
76+
}
77+
}
78+
if _, isOld := wordSet[word]; word != "" && !isOld {
79+
wordSet[word] = true
80+
}
81+
}
82+
83+
results := make([]string, 0)
84+
for i := 0; i < *level; i += 1 {
85+
toMerge := results[0:]
86+
if len(toMerge) == 0 {
87+
for word := range wordSet {
88+
results = append(results, word)
89+
}
90+
} else {
91+
for _, sd := range toMerge {
92+
for word := range wordSet {
93+
results = append(results, fmt.Sprintf("%s.%s", word, sd))
94+
}
95+
}
96+
}
97+
}
98+
for _, domain := range inputDomains {
99+
for _, subpath := range results {
100+
fmt.Println(domain + "/" + subpath + "/")
101+
if outputFile != nil {
102+
_, _ = outputFile.WriteString(domain + "/" + subpath + "/" + "\n")
103+
}
104+
}
105+
}
106+
}

0 commit comments

Comments
 (0)