-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathmain.go
120 lines (92 loc) · 3.14 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
package main
import (
"bufio"
"fmt"
"os"
"strings"
"time"
"math"
"io"
"flag"
)
func main() {
var inputFilePath string
var outputFilePath string
var hibpFilePath string
flag.StringVar(&inputFilePath, "input", "", "Specify input file containing hashed passwords")
flag.StringVar(&outputFilePath, "output", "", "Specify output file for leaked hashes")
flag.StringVar(&hibpFilePath, "hibp", "", "Specify Have I Been Pwned NTLM/SHA1 text file")
flag.Parse()
startTimer := time.Now()
hibp, err := os.OpenFile(hibpFilePath, os.O_RDONLY, 0600)
if err != nil {
fmt.Println(err)
return
}
hibpHashOnly, err := os.OpenFile("./temp_hashonly.txt", os.O_CREATE|os.O_RDWR|os.O_TRUNC, 0644)
if err != nil {
fmt.Println(err)
return
}
hibpFileScanner := bufio.NewScanner(hibp)
hibpHashOnlywriter := bufio.NewWriter(hibpHashOnly)
for hibpFileScanner.Scan() {
hash := strings.Split(hibpFileScanner.Text(), ":")[0]
_, err := hibpHashOnlywriter.WriteString(hash + "\n")
if err != nil {
fmt.Printf("Got error while writing to a file. Err: %s", err.Error())
}
}
hibpHashOnlywriter.Flush()
hibp.Close()
fmt.Printf("file converted with only hash in %s\n", time.Since(startTimer))
hashs, err := os.Open(inputFilePath)
if err != nil {
fmt.Println(err)
return
}
defer hashs.Close()
leaked, err := os.OpenFile(outputFilePath, os.O_CREATE|os.O_RDWR|os.O_TRUNC, 0644)
if err != nil {
fmt.Println(err)
}
defer leaked.Close()
hashCount := 1
hashLeakedCount := 0
hashsFileScanner := bufio.NewScanner(hashs)
// read first line to determine size and type of hash
hashsFileScanner.Scan()
hash := strings.ToUpper(hashsFileScanner.Text())
var hashLength int64 = int64(len(hash)) // 40 for SHA1 or 32 NTLM
hashBuffer := make([]byte, hashLength)
hibpHashOnlyStat, _ := hibpHashOnly.Stat()
for hashsFileScanner.Scan() {
var start int64 = 0
var end int64 = hibpHashOnlyStat.Size()
for {
pos := start + ( int64(math.Floor(float64((end - start) / (hashLength + 1)) / 2 )) * (hashLength + 1) )
hibpHashOnly.Seek(pos, io.SeekStart)
hibpHashOnly.Read(hashBuffer)
hashExtract := string(hashBuffer[:hashLength])
//fmt.Printf("hash %s vs hashExtract %s\n", hash, hashExtract)
if hash == hashExtract {
leaked.WriteString(hashExtract + "\n")
hashLeakedCount++
//fmt.Printf("hash %s leaked\n", hash)
break
}
if pos <= start || pos >= end {
//fmt.Printf("hash %s didn't leaked\n", hash)
break
}
if hash > hashExtract {
start = pos
} else {
end = pos
}
}
hash = strings.ToUpper(hashsFileScanner.Text())
hashCount++
}
fmt.Printf("%d password hashs analyzed in %s and %d leaked\n", hashCount, time.Since(startTimer), hashLeakedCount)
}