crargo/crargo.go

114 lines
2.4 KiB
Go

package main
import (
"bufio"
"fmt"
"log"
"os"
"strconv"
"sync/atomic"
"time"
"github.com/yeka/zip"
)
func crack(tid int, file []byte, fn string, passwords []string, found **string, stop *bool, total *uint64, exited *int32) {
fmt.Println("Thread", tid, ": starting with", len(passwords), "passwords...")
r, err := zip.OpenReader(fn)
if err != nil {
log.Fatal(err)
}
f := r.File[len(r.File)-1]
fmt.Println("Filename:", f.Name)
for i := 0; i < len(passwords); i++ {
if *stop {
goto end
}
cur_pass := passwords[i]
f.SetPassword(cur_pass)
r, err := f.Open()
if err == nil {
*found = &passwords[i]
r.Close()
goto end
}
atomic.AddUint64(total, 1)
}
end:
fmt.Println("Thread", tid, ": stopped.")
atomic.AddInt32(exited, 1)
}
func main() {
if len(os.Args) != 4 {
log.Fatal("Invalid arguments. Usage: go run crargo.go [file path] [dictionary path] [thread count]")
}
fn := os.Args[1]
dictfn := os.Args[2]
var dict []string
threads, err := strconv.Atoi(os.Args[3])
if err != nil || threads <= 0 {
log.Fatal("Invalid thread count: \"", os.Args[3], "\"")
}
fmt.Println("Cracking \"", fn, "\" with dict \"", dictfn, "\" using ", threads, " threads...")
fmt.Println("Reading archive...")
fb, err := os.ReadFile(fn)
if err != nil {
log.Fatal(err)
}
fmt.Println("Reading dictionary...")
dictf, err := os.Open(dictfn)
if err != nil {
log.Fatal(err)
}
scanner := bufio.NewScanner(dictf)
for scanner.Scan() {
dict = append(dict, scanner.Text())
}
if err := scanner.Err(); err != nil {
log.Fatal(err)
}
fmt.Println("Processed", len(dict), "dictionary entries.")
each_thread := len(dict) / threads
var found *string = nil
var stop bool = false
var total uint64 = 0
var exited int32 = 0
for i := 0; i < threads; i++ {
go crack(i, fb, fn, dict[each_thread*i:each_thread*(i+1)], &found, &stop, &total, &exited)
}
var sec int = 0
for {
time.Sleep(1 * time.Second)
sec++
if found != nil {
fmt.Print("Found password: \"", *found, "\"\n")
stop = true
for int(atomic.LoadInt32(&exited)) < threads {
}
break
} else if int(atomic.LoadInt32(&exited)) == threads {
fmt.Println("No password found!")
break
} else {
tot := atomic.LoadUint64(&total)
fmt.Println("main: total tries: ", tot, "(", tot/uint64(sec), " req/s)")
}
}
}