Skip to content

Commit c7be868

Browse files
committed
Username bruteforce generation option added (mode=generate etc)
1 parent 5bc12f4 commit c7be868

File tree

2 files changed

+101
-6
lines changed

2 files changed

+101
-6
lines changed

main.go

+31-6
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,12 @@ func main() {
5656

5757
dumpDSE := flag.Bool("dump", false, "Just dump the rootDSE, no bruteforcing")
5858

59+
// bruteforce usernames
60+
mode := flag.String("mode", "static", "password generator (static: read from file/stdin | generate: bruteforce len/charset)")
61+
minlen := flag.Int("minlength", 1, "Minimum length of generated usernames")
62+
maxlen := flag.Int("maxlength", 5, "Maximum length of generated usernames")
63+
charset := flag.String("charset", "abcdefghijklmnopqrstuvwxyz0123456789.@", "Characters to use in bruteforcing")
64+
5965
// evasive maneuvers
6066
throttle := flag.Int("throttle", 0, "Only do a request every N ms, 0 to disable")
6167
maxrequests := flag.Int("maxrequests", 0, "Disconnect and reconnect a connection after n requests, 0 to disable")
@@ -87,7 +93,7 @@ func main() {
8793

8894
var pbmax int
8995
input := os.Stdin
90-
if *inputname != "" {
96+
if *mode == "static" && *inputname != "" {
9197
input, err = os.Open(*inputname)
9298
if err != nil {
9399
log.Fatalf("Can't open %v: %v", *inputname, err)
@@ -117,6 +123,12 @@ func main() {
117123
input.Seek(0, io.SeekStart)
118124
pb.Finish()
119125
}
126+
} else if *mode == "generate" {
127+
for curlength := *minlen; curlength <= *maxlen; curlength++ {
128+
sg := NewStringGen(*charset, curlength)
129+
pbmax += int(sg.Complexity())
130+
}
131+
fmt.Printf("Generating %v usernames ranging in length from %v to %v\n", pbmax, *minlen, *maxlen)
120132
}
121133

122134
names := bufio.NewScanner(input)
@@ -435,15 +447,16 @@ func main() {
435447
}()
436448

437449
var pb *progressbar.ProgressBar
438-
if pbmax != 0 {
450+
if *outputname != "" && pbmax != 0 {
439451
pb = progressbar.NewOptions(pbmax,
440452
progressbar.OptionSetDescription("Usernames nom'ed"),
441453
progressbar.OptionShowIts(),
442454
)
443455
}
444456

445-
go func() {
446-
var line int
457+
var line int
458+
switch *mode {
459+
case "static":
447460
for names.Scan() {
448461
if pb != nil && line%500 == 0 {
449462
pb.Set(line)
@@ -458,8 +471,20 @@ func main() {
458471
}
459472
line++
460473
}
461-
close(inputqueue)
462-
}()
474+
case "generate":
475+
for curlength := *minlen; curlength <= *maxlen; curlength++ {
476+
sg := NewStringGen(*charset, curlength)
477+
for sg.Next() {
478+
inputqueue <- sg.String()
479+
line++
480+
481+
if pb != nil && line%500 == 0 {
482+
pb.Set(line)
483+
}
484+
}
485+
}
486+
}
487+
close(inputqueue)
463488

464489
jobs.Wait()
465490
close(outputqueue)

stringgen.go

+70
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
package main
2+
3+
import "math"
4+
5+
type StringGen struct {
6+
charset string // The set of characters to choose from
7+
charsetlen int // Length of charset
8+
9+
length int // lenght of the generated string
10+
11+
indexdata []int // Index data for where we are in each byte
12+
data []byte // The actual bytes that make up the string
13+
done int // If a leading position is done, we increment this
14+
first bool
15+
}
16+
17+
func NewStringGen(charset string, length int) *StringGen {
18+
sg := StringGen{
19+
charset: charset,
20+
charsetlen: len(charset),
21+
22+
length: length,
23+
24+
indexdata: make([]int, length),
25+
data: make([]byte, length),
26+
27+
done: 0,
28+
first: true,
29+
}
30+
return &sg
31+
}
32+
33+
func (sg *StringGen) Complexity() int64 {
34+
return int64(float32(math.Pow(float64(sg.charsetlen), float64(sg.length))))
35+
}
36+
37+
func (sg *StringGen) Next() bool {
38+
if sg.first {
39+
for i := 0; i < sg.length; i++ {
40+
sg.data[i] = sg.charset[0]
41+
}
42+
sg.first = false
43+
return true
44+
}
45+
46+
if sg.done == sg.charsetlen {
47+
return false
48+
}
49+
50+
for i := sg.length - 1; i >= 0; i-- {
51+
if sg.indexdata[i] == sg.charsetlen-1 {
52+
sg.indexdata[i] = 0
53+
sg.data[i] = sg.charset[0]
54+
} else {
55+
sg.indexdata[i]++
56+
sg.data[i] = sg.charset[sg.indexdata[i]]
57+
58+
if sg.done == i && sg.indexdata[i] == sg.charsetlen-1 {
59+
sg.done++
60+
}
61+
62+
break
63+
}
64+
}
65+
return true
66+
}
67+
68+
func (sg *StringGen) String() string {
69+
return string(sg.data)
70+
}

0 commit comments

Comments
 (0)