@@ -9,24 +9,25 @@ import (
9
9
"encoding/base64"
10
10
"encoding/binary"
11
11
"encoding/hex"
12
- "unicode/utf16"
13
12
"flag"
14
13
"fmt"
15
- "log"
16
- "hash"
17
- "os"
18
- "sync"
19
- "time"
20
- "hash/crc32"
21
- "hash/crc64"
22
- "strconv"
23
14
"github.com/alexedwards/argon2id"
24
- "golang.org/x/crypto/md4"
25
15
"golang.org/x/crypto/bcrypt"
16
+ "golang.org/x/crypto/blake2b"
17
+ "golang.org/x/crypto/blake2s"
18
+ "golang.org/x/crypto/md4"
26
19
"golang.org/x/crypto/ripemd160"
27
20
"golang.org/x/crypto/sha3"
28
- "golang.org/x/crypto/blake2s"
29
- "golang.org/x/crypto/blake2b"
21
+ "hash"
22
+ "hash/crc32"
23
+ "hash/crc64"
24
+ "io"
25
+ "log"
26
+ "os"
27
+ "strconv"
28
+ "sync"
29
+ "time"
30
+ "unicode/utf16"
30
31
)
31
32
32
33
// version history
@@ -38,50 +39,49 @@ import (
38
39
// v2022-12-21.1400-goroutine; added multiple new algo's including hashcat mode equivalents
39
40
// v2022-12-23.1200-goroutine; added argon2id (very slow), added sync / wait group for future use, change h/s readout from millions to thousands,
40
41
// v2022-12-24.1800-optimize; optimized all hashing functions, tweaked buffer size
42
+ // v2023-03-15.0900-optimize; added "stdout", fixed "lines/sec" to show "M lines/sec", tweaked output buffer for stdout, tweaked sha2xxx flags to allow "shaxxx", ex: "sha512"
41
43
42
- // TODO:
44
+ // TODO:
43
45
// continue to add more hash functions
44
- // add "-o stdout" flag to print hashes to stdout
45
- // continue optimizing hash functions for better performance (ex: ntlm is currently slower than md5)
46
+ // continue optimizing hash functions for better performance
46
47
// fine tune goroutines for better performance with read --> hash function --> write
47
- // add feature to allow hash cracking in addition to hash generation (future program: hashgenie)
48
48
49
49
func versionFunc () {
50
- funcBase64Decode ("Q3ljbG9uZSBoYXNoIGdlbmVyYXRvciB2MjAyMi0xMi0yNC4xODAwLW9wdGltaXplCg ==" )
50
+ funcBase64Decode ("Q3ljbG9uZSBoYXNoIGdlbmVyYXRvciB2MjAyMy0wMy0xNS4wOTAwLW9wdGltaXplCg ==" )
51
51
}
52
52
53
53
// help function
54
54
func helpFunc () {
55
- versionFunc ()
56
- str := "Example Usage:\n " +
57
- "\n ./hashgen -m md5 -w wordlist.txt -o output.txt\n " +
58
- "\n Function: \t Hashcat Mode:\n " +
59
- "argon2id (very slow!)\n " +
60
- "base64encode\n " +
61
- "base64decode\n " +
62
- "bcrypt \t \t 3200\n " +
63
- "blake2s-256\n " +
64
- "blake2b-256\n " +
65
- "blake2b-384\n " +
66
- "blake2b-512 \t 600\n " +
67
- "crc32 \t \t 11500\n " +
68
- "crc64\n " +
69
- "md4 \t \t 900\n " +
70
- "md5 \t \t 0\n " +
71
- "ntlm \t \t 1000\n " +
72
- "plaintext \t 99999\n " +
73
- "ripemd-160 \t 6000\n " +
74
- "sha1 \t \t 100\n " +
75
- "sha2-224 \t 1300\n " +
76
- "sha2-384 \t 10800\n " +
77
- "sha2-256 \t 1400\n " +
78
- "sha2-512 \t 1700\n " +
79
- "sha2-512-224\n " +
80
- "sha2-512-256\n " +
81
- "sha3-224 \t 17300\n " +
82
- "sha3-256 \t 17400\n " +
83
- "sha3-384 \t 17400\n " +
84
- "sha3-512 \t 17400\n "
55
+ versionFunc ()
56
+ str := "Example Usage:\n " +
57
+ "\n ./hashgen -m md5 -w wordlist.txt -o output.txt\n " +
58
+ "\n Function: \t Hashcat Mode:\n " +
59
+ "argon2id (very slow!)\n " +
60
+ "base64encode\n " +
61
+ "base64decode\n " +
62
+ "bcrypt \t \t 3200\n " +
63
+ "blake2s-256\n " +
64
+ "blake2b-256\n " +
65
+ "blake2b-384\n " +
66
+ "blake2b-512 \t 600\n " +
67
+ "crc32 \t \t 11500\n " +
68
+ "crc64\n " +
69
+ "md4 \t \t 900\n " +
70
+ "md5 \t \t 0\n " +
71
+ "ntlm \t \t 1000\n " +
72
+ "plaintext \t 99999\n " +
73
+ "ripemd-160 \t 6000\n " +
74
+ "sha1 \t \t 100\n " +
75
+ "sha2-224 \t 1300\n " +
76
+ "sha2-384 \t 10800\n " +
77
+ "sha2-256 \t 1400\n " +
78
+ "sha2-512 \t 1700\n " +
79
+ "sha2-512-224\n " +
80
+ "sha2-512-256\n " +
81
+ "sha3-224 \t 17300\n " +
82
+ "sha3-256 \t 17400\n " +
83
+ "sha3-384 \t 17400\n " +
84
+ "sha3-512 \t 17400\n "
85
85
fmt .Println (str )
86
86
os .Exit (0 )
87
87
}
@@ -93,40 +93,40 @@ func main() {
93
93
var inputFile string
94
94
flag .StringVar (& inputFile , "w" , "" , "Input file to process" )
95
95
var outputFile string
96
- flag .StringVar (& outputFile , "o" , "" , "Output file to write hashes to" )
96
+ flag .StringVar (& outputFile , "o" , "stdout " , "Output file to write hashes to (use 'stdout' to print to console) " )
97
97
version := flag .Bool ("version" , false , "Program version:" )
98
- cyclone := flag .Bool ("cyclone" , false , "hashgen" )
99
- help := flag .Bool ("help" , false , "Prints help:" )
98
+ cyclone := flag .Bool ("cyclone" , false , "hashgen" )
99
+ help := flag .Bool ("help" , false , "Prints help:" )
100
100
flag .Parse ()
101
101
102
102
// run sanity checks for -version & -help
103
- if * version == true {
104
- versionFunc ()
105
- os .Exit (0 )
106
- } else if * cyclone == true {
107
- funcBase64Decode ("Q29kZWQgYnkgY3ljbG9uZSA7KQo=" )
108
- os .Exit (0 )
109
- } else if * help == true {
110
- helpFunc ()
111
- }
103
+ if * version == true {
104
+ versionFunc ()
105
+ os .Exit (0 )
106
+ } else if * cyclone == true {
107
+ funcBase64Decode ("Q29kZWQgYnkgY3ljbG9uZSA7KQo=" )
108
+ os .Exit (0 )
109
+ } else if * help == true {
110
+ helpFunc ()
111
+ }
112
112
// run sanity checks on algo input (-m)
113
- if len (hashFunc ) < 1 {
114
- fmt .Println ("--> missing '-m algo' <--\n " )
115
- helpFunc ()
116
- os .Exit (0 )
117
- }
113
+ if len (hashFunc ) < 1 {
114
+ fmt .Println ("--> missing '-m algo' <--\n " )
115
+ helpFunc ()
116
+ os .Exit (0 )
117
+ }
118
118
// run sanity checks on wordlist input (-w)
119
- if len (inputFile ) < 1 {
120
- fmt .Println ("--> missing '-w wordlist' <--\n " )
121
- helpFunc ()
122
- os .Exit (0 )
123
- }
119
+ if len (inputFile ) < 1 {
120
+ fmt .Println ("--> missing '-w wordlist' <--\n " )
121
+ helpFunc ()
122
+ os .Exit (0 )
123
+ }
124
124
// run sanity checks on output (-o)
125
- if len (outputFile ) < 1 {
126
- fmt .Println ("--> missing '-o filename' <--\n " )
127
- helpFunc ()
128
- os .Exit (0 )
129
- }
125
+ if len (outputFile ) < 1 {
126
+ fmt .Println ("--> missing '-o filename' <--\n " )
127
+ helpFunc ()
128
+ os .Exit (0 )
129
+ }
130
130
// open input file
131
131
input , err := os .Open (inputFile )
132
132
if err != nil {
@@ -135,12 +135,19 @@ func main() {
135
135
}
136
136
defer input .Close ()
137
137
// open output file
138
- output , err := os .Create (outputFile )
139
- if err != nil {
140
- fmt .Printf ("--> Error opening output file: %v <--\n " , err )
141
- os .Exit (1 )
138
+ var output io.Writer
139
+ if outputFile == "stdout" {
140
+ output = os .Stdout
141
+ } else {
142
+ file , err := os .Create (outputFile )
143
+ if err != nil {
144
+ fmt .Printf ("--> Error opening output file: %v <--\n " , err )
145
+ os .Exit (1 )
146
+ }
147
+ defer file .Close ()
148
+ output = file
142
149
}
143
- defer output . Close ()
150
+
144
151
// create hash functions from flag -m
145
152
var h hash.Hash
146
153
switch hashFunc {
@@ -152,17 +159,17 @@ func main() {
152
159
h = md4 .New ()
153
160
case "sha1" , "100" :
154
161
h = sha1 .New ()
155
- case "sha2-224" , "sha2_224" , "sha2224" , "1300" :
162
+ case "sha2-224" , "sha2_224" , "sha2224" , "sha224" , " 1300" :
156
163
hashFunc = "sha2-224"
157
- case "sha2-384" , "sha2_384" , "sha2384" ,"10800" :
164
+ case "sha2-384" , "sha2_384" , "sha2384" , "sha384" , "10800" :
158
165
hashFunc = "sha2-384"
159
- case "sha2-256" , "sha2_256" , "sha2256" , "1400" :
166
+ case "sha2-256" , "sha2_256" , "sha2256" , "sha256" , " 1400" :
160
167
h = sha256 .New ()
161
- case "sha2-512" , "sha2_512" , "sha2512" , "1700" :
168
+ case "sha2-512" , "sha2_512" , "sha2512" , "sha512" , " 1700" :
162
169
h = sha512 .New ()
163
- case "sha2-512-224" , "sha2_512_224" , "sha2512224" :
170
+ case "sha2-512-224" , "sha2_512_224" , "sha2512224" , "sha512224" :
164
171
h = sha512 .New512_224 ()
165
- case "sha2-512-256" , "sha2_512_256" , "sha2512256" :
172
+ case "sha2-512-256" , "sha2_512_256" , "sha2512256" , "sha512256 " :
166
173
h = sha512 .New512_256 ()
167
174
case "ripemd-160" , "ripemd_160" , "ripemd160" , "6000" :
168
175
h = ripemd160 .New ()
@@ -199,26 +206,26 @@ func main() {
199
206
default :
200
207
fmt .Printf ("--> Invalid hash function: %s <--\n " , hashFunc )
201
208
helpFunc ()
202
- os .Exit (0 )
209
+ os .Exit (0 )
203
210
}
204
-
211
+
205
212
// create read / write buffers
206
213
// input buffer
207
214
inputBuffer := bufio .NewScanner (input )
208
- // set buffer capacity to 10mb
209
- const maxCapacity = 10 * 1024 * 1024
215
+ // set input buffer
216
+ const maxCapacity = 10 * 1024 * 1024
210
217
buf := make ([]byte , maxCapacity )
211
218
inputBuffer .Buffer (buf , maxCapacity )
212
- // set output buffer to 100mb
213
- outputBuffer := bufio .NewWriterSize (output , 100 * 1024 * 1024 )
219
+ // set output buffer
220
+ outputBuffer := bufio .NewWriterSize (output , 10 * 1024 * 1024 )
214
221
215
222
// create buffered channels to receive lines <-- not currently emplimented
216
223
//lines := make(chan string, 10*1024*1024)
217
224
//linesHash := make(chan string, 10*1024*1024)
218
225
219
226
// create WaitGroup to wait for goroutines to finish
220
227
var wg sync.WaitGroup
221
-
228
+
222
229
// create goroutine bool channel
223
230
done := make (chan bool )
224
231
// start hashgen goroutine
@@ -325,7 +332,7 @@ func main() {
325
332
hashString := strconv .FormatUint (hash , 16 )
326
333
outputBuffer .WriteString (hashString + "\n " )
327
334
linesHashed ++
328
- }
335
+ }
329
336
} else if hashFunc == "base64encode" {
330
337
// base64encode
331
338
for inputBuffer .Scan () {
@@ -392,8 +399,9 @@ func main() {
392
399
}
393
400
}
394
401
elapsedTime := time .Since (startTime )
395
- linesPerSecond := float64 (linesHashed ) / elapsedTime .Seconds () * 0.001 // convert to thousand hashes per second
396
- log .Printf ("Finished hashing %d lines in %v (%.3f lines/sec)\n " , linesHashed , elapsedTime , linesPerSecond )
402
+ runTime := float64 (elapsedTime .Seconds ())
403
+ linesPerSecond := float64 (linesHashed ) / elapsedTime .Seconds () * 0.000001 // convert to thousand hashes per second
404
+ log .Printf ("Finished hashing %d lines in %.3f sec (%.3f M lines/sec)\n " , linesHashed , runTime , linesPerSecond )
397
405
done <- true
398
406
}()
399
407
@@ -409,10 +417,12 @@ func main() {
409
417
410
418
// base64 decode function used for displaying encoded messages
411
419
func funcBase64Decode (line string ) {
412
- str , err := base64 .StdEncoding .DecodeString (line )
413
- if err != nil {
420
+ str , err := base64 .StdEncoding .DecodeString (line )
421
+ if err != nil {
414
422
log .Println ("--> Text doesn't appear to be base64 encoded. <--" )
415
- os .Exit (0 )
416
- }
417
- fmt .Printf ("%s\n " , str )
423
+ os .Exit (0 )
424
+ }
425
+ fmt .Printf ("%s\n " , str )
418
426
}
427
+
428
+ // end code
0 commit comments