├── README.md ├── docs └── go-hash-matcher-banner.gif ├── go.mod ├── main.go └── utils ├── cryptBytes.go ├── getCryptedBytes.go └── showLoading.go /README.md: -------------------------------------------------------------------------------- 1 | ![](docs/go-hash-matcher-banner.gif) 2 | 3 |

Go-Hash-Matcher

4 | A simple password cracker written in Go, designed to search for a specific hashed password in a wordlist. 5 |
6 | 7 |
8 | 9 | 10 |
11 | 12 | ![](https://img.shields.io/twitter/follow/IamLucif3r_?style=social) ![](https://img.shields.io/github/followers/IamLucif3r?label=Follow%20Me&style=social)
13 | 14 | ## Features 15 | 16 | - Utilizes goroutines for concurrent password checking to improve performance. 17 | - Supports SHA1 hashing with customizable salt. 18 | - Provides flexibility for using different hashing algorithms. 19 | 20 | ## Usage 21 | 22 | 1. Clone the repository: 23 | 24 | ```bash 25 | git clone https://github.com/IamLucif3r/Go-Hash-Matcher.git 26 | ``` 27 | 28 | 2. Navigate to the project directory: 29 | 30 | ```bash 31 | cd Go-Hash-Matcher 32 | ``` 33 | 34 | 3. Build the project: 35 | 36 | ```bash 37 | go build main.go 38 | ``` 39 | 40 | 4. Run the executable: 41 | 42 | ```bash 43 | ./main 44 | ``` 45 | 46 | Replace `main` with the name of the compiled executable if it's different. 47 | 48 | 5. The program will read passwords from the `passwords.txt` file and check for a specific hashed password. 49 | 50 | ## Configuration 51 | 52 | - Adjust the `hashType` variable to use a different hashing algorithm (e.g., SHA256). 53 | - Modify the `salt` variable to change the salt used during hashing. 54 | 55 | ## Dependencies 56 | 57 | The project uses only standard Go libraries and does not require additional dependencies. 58 | 59 | ## Contributing 60 | 61 | Feel free to contribute by opening issues, providing feedback, or submitting pull requests. 62 | 63 | 64 | -------------------------------------------------------------------------------- /docs/go-hash-matcher-banner.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IamLucif3r/Go-Hash-Matcher/ff45e146c42009884b13143703c71281fb5b359e/docs/go-hash-matcher-banner.gif -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/IamLucif3r/Go-Hash-Matcher 2 | 3 | go 1.21.5 4 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "os" 7 | "sync" 8 | "time" 9 | 10 | utils "github.com/IamLucif3r/Go-Hash-Matcher/utils" 11 | ) 12 | 13 | var wg sync.WaitGroup 14 | 15 | func checkPassword(value, search, hashType, salt string, results chan bool) { 16 | defer wg.Done() 17 | hashedPassword := utils.CryptBytes(hashType, salt, []byte(value)) 18 | if hashedPassword == search { 19 | fmt.Printf("[✅] Hash Matched! Password Found : %s, hash: %s\n", value, hashedPassword) 20 | results <- true 21 | } 22 | } 23 | 24 | func main() { 25 | hashType := "SHA1" 26 | salt := "d" 27 | // Enter Hash you want to decrypt 28 | search := "$SHA1$d$uP0_QaVBpDWFeo8-dRzDqRwXQ2I" 29 | // Provide path for a list of plain text passwords 30 | wordlist := "/usr/share/wordlists/rockyou.txt" 31 | 32 | go utils.ShowLoadingSpinner() 33 | 34 | passwordListFile, err := os.Open(wordlist) 35 | if err != nil { 36 | fmt.Printf("[❗️] Error opening wordlist: %v\n", err) 37 | return 38 | } 39 | defer passwordListFile.Close() 40 | 41 | scanner := bufio.NewScanner(passwordListFile) 42 | results := make(chan bool) 43 | 44 | for scanner.Scan() { 45 | value := scanner.Text() 46 | wg.Add(1) 47 | go checkPassword(value, search, hashType, salt, results) 48 | } 49 | 50 | go func() { 51 | wg.Wait() 52 | close(results) 53 | }() 54 | 55 | select { 56 | case <-results: 57 | case <-time.After(10 * time.Second): 58 | fmt.Println("[❌] Password not found in the given timeout.") 59 | } 60 | 61 | if err := scanner.Err(); err != nil { 62 | fmt.Printf("[❗️] Error reading wordlist: %v\n", err) 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /utils/cryptBytes.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "crypto/rand" 5 | "crypto/sha1" 6 | "encoding/base64" 7 | "fmt" 8 | "strings" 9 | ) 10 | 11 | func CryptBytes(hashType, salt string, value []byte) string { 12 | if hashType == "" { 13 | hashType = "SHA1" 14 | } 15 | if salt == "" { 16 | saltBytes := make([]byte, 16) 17 | rand.Read(saltBytes) 18 | salt = base64.URLEncoding.EncodeToString(saltBytes) 19 | } 20 | hash := sha1.New() 21 | hash.Write([]byte(salt)) 22 | hash.Write(value) 23 | hashedBytes := hash.Sum(nil) 24 | result := fmt.Sprintf("$%s$%s$%s", hashType, salt, strings.TrimRight(base64.URLEncoding.EncodeToString(hashedBytes), "=")) 25 | return result 26 | } 27 | -------------------------------------------------------------------------------- /utils/getCryptedBytes.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "crypto/sha1" 5 | "encoding/base64" 6 | "strings" 7 | ) 8 | 9 | func GetCryptedBytes(hashType, salt string, value []byte) string { 10 | hash := sha1.New() 11 | hash.Write([]byte(salt)) 12 | hash.Write(value) 13 | hashedBytes := hash.Sum(nil) 14 | return strings.TrimRight(base64.URLEncoding.EncodeToString(hashedBytes), "=") 15 | } 16 | -------------------------------------------------------------------------------- /utils/showLoading.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | func ShowLoadingSpinner() { 9 | ticker := time.NewTicker(100 * time.Millisecond) 10 | defer ticker.Stop() 11 | 12 | spinnerFrames := []string{"⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"} 13 | 14 | i := 0 15 | for { 16 | select { 17 | case <-ticker.C: 18 | fmt.Printf("\rChecking passwords %s", spinnerFrames[i]) 19 | i = (i + 1) % len(spinnerFrames) 20 | } 21 | } 22 | } 23 | --------------------------------------------------------------------------------