diff --git a/README.md b/README.md new file mode 100644 index 0000000..f22e444 --- /dev/null +++ b/README.md @@ -0,0 +1,12 @@ +Gremlin +======= + +This is small proof of concept to crack any PDF file encrypted with PESEL number as password. + +Before you run it please download all dependencies + + go mod download + +To use it just run + + go run main.go /PathFile/To/Pdf/File diff --git a/algorithm/control_sum.go b/algorithm/control_sum.go new file mode 100644 index 0000000..4e0879b --- /dev/null +++ b/algorithm/control_sum.go @@ -0,0 +1,29 @@ +package algorithm + +import "strconv" + +func getLastDigit(number int) int { + strNumber := strconv.Itoa(number) + lastDigit := strNumber[len(strNumber)-1:] + result, _ := strconv.Atoi(lastDigit) + return result +} + +func ControlSum(peselArr [10]int) int { + result := peselArr[0]*1 + + peselArr[1]*3 + + peselArr[2]*7 + + peselArr[3]*9 + + peselArr[4]*1 + + peselArr[5]*3 + + peselArr[6]*7 + + peselArr[7]*9 + + peselArr[8]*1 + + peselArr[9]*3 + lastDigit := getLastDigit(result) + if lastDigit == 0 { + return 0 + } else { + return 10 - getLastDigit(result%10) + } +} diff --git a/algorithm/decrypt.go b/algorithm/decrypt.go new file mode 100644 index 0000000..564b64b --- /dev/null +++ b/algorithm/decrypt.go @@ -0,0 +1,44 @@ +package algorithm + +import ( + "fmt" + "os" + "sync" + + "github.com/unidoc/unipdf/v3/model" +) + +func DecryptPdf(filePath string, passChannel chan string, wg *sync.WaitGroup) error { + f, err := os.Open(filePath) + if err != nil { + return err + } + + defer f.Close() + + pdfReader, err := model.NewPdfReader(f) + if err != nil { + return err + } + + isEncrypted, err := pdfReader.IsEncrypted() + if err != nil { + return err + } + + if isEncrypted { + for password := range passChannel { + auth, err := pdfReader.Decrypt([]byte(password)) + if err != nil { + return err + } + if auth { + fmt.Println(password) + wg.Done() + } else { + fmt.Errorf("Wrong password") + } + } + } + return nil +} diff --git a/algorithm/generator.go b/algorithm/generator.go new file mode 100644 index 0000000..0dc4833 --- /dev/null +++ b/algorithm/generator.go @@ -0,0 +1,30 @@ +package algorithm + +import ( + "fmt" + "strconv" + "time" +) + +func GeneratePeselsForDate(date time.Time, passChannel chan string) { + peselDate := date.Format("060102") + if date.Year() >= 2000 { + peselDate = peselDate[:2] + "2" + peselDate[3:] + } + for i := 0; i < 10000; i++ { + peselWithoutValidation := peselDate + fmt.Sprintf("%04d", i) + checksum := ControlSum(peselIntArray(peselWithoutValidation)) + pesel := peselWithoutValidation + strconv.Itoa(checksum) + passChannel <- pesel + } + fmt.Println("Nothing found for: ", date) + close(passChannel) +} + +func peselIntArray(pesel string) [10]int { + var peselArray [10]int + for idx, digit := range pesel { + peselArray[idx] = int(digit) - '0' + } + return peselArray +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..5997e00 --- /dev/null +++ b/go.mod @@ -0,0 +1,22 @@ +module github.com/galuszkak/pesel + +go 1.17 + +require github.com/unidoc/unipdf/v3 v3.32.0 + +require ( + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/konsorten/go-windows-terminal-sequences v1.0.2 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/sirupsen/logrus v1.5.0 // indirect + github.com/stretchr/testify v1.6.1 // indirect + github.com/unidoc/pkcs7 v0.1.0 // indirect + github.com/unidoc/timestamp v0.0.0-20200412005513-91597fd3793a // indirect + github.com/unidoc/unitype v0.2.1 // indirect + golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0 // indirect + golang.org/x/image v0.0.0-20211028202545-6944b10bf410 // indirect + golang.org/x/sys v0.0.0-20200413165638-669c56c373c4 // indirect + golang.org/x/text v0.3.6 // indirect + golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect + gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..e78669e --- /dev/null +++ b/go.sum @@ -0,0 +1,58 @@ +github.com/adrg/strutil v0.1.0/go.mod h1:pXRr2+IyX5AEPAF5icj/EeTaiflPSD2hvGjnguilZgE= +github.com/adrg/sysfont v0.1.1/go.mod h1:19nTHzfIn/HbngFMet+yNAvwSQYtOJYMI7vWexLWyNw= +github.com/adrg/xdg v0.2.1/go.mod h1:ZuOshBmzV4Ta+s23hdfFZnBsdzmoR3US0d7ErpqSbTQ= +github.com/boombuler/barcode v1.0.0/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s= +github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/montanaflynn/stats v0.6.6/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/sirupsen/logrus v1.5.0 h1:1N5EYkVAPEywqZRJd7cwnRtCb6xJx7NH3T3WUTF980Q= +github.com/sirupsen/logrus v1.5.0/go.mod h1:+F7Ogzej0PZc/94MaYx/nvG9jOFMD2osvC3s+Squfpo= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/trimmer-io/go-xmp v1.0.0/go.mod h1:Aaptr9sp1lLv7UnCAdQ+gSHZyY2miYaKmcNVj7HRBwA= +github.com/unidoc/freetype v0.0.0-20220130190903-3efbeefd0c90/go.mod h1:mJ/Q7JnqEoWtajJVrV6S1InbRv0K/fJerPB5SQs32KI= +github.com/unidoc/pkcs7 v0.0.0-20200411230602-d883fd70d1df/go.mod h1:UEzOZUEpJfDpywVJMUT8QiugqEZC29pDq7kdIZhWCr8= +github.com/unidoc/pkcs7 v0.1.0 h1:9bQfbWMYsIfUP8PyhTcBudOsvbLpNH0MBv4U0P/jDTE= +github.com/unidoc/pkcs7 v0.1.0/go.mod h1:UEzOZUEpJfDpywVJMUT8QiugqEZC29pDq7kdIZhWCr8= +github.com/unidoc/timestamp v0.0.0-20200412005513-91597fd3793a h1:RLtvUhe4DsUDl66m7MJ8OqBjq8jpWBXPK6/RKtqeTkc= +github.com/unidoc/timestamp v0.0.0-20200412005513-91597fd3793a/go.mod h1:j+qMWZVpZFTvDey3zxUkSgPJZEX33tDgU/QIA0IzCUw= +github.com/unidoc/unipdf/v3 v3.32.0 h1:GpQAHDFpQJatXf/iH6ryP1J0GnwPyXhIFuIS219cg1o= +github.com/unidoc/unipdf/v3 v3.32.0/go.mod h1:OUIt+FTxVqRJl3OFuqiPTPaxPwoYUjkmqPiRRh/SfLo= +github.com/unidoc/unitype v0.2.1 h1:x0jMn7pB/tNrjEVjy3Ukpxo++HOBQaTCXcTYFA6BH3w= +github.com/unidoc/unitype v0.2.1/go.mod h1:mafyug7zYmDOusqa7G0dJV45qp4b6TDAN+pHN7ZUIBU= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0 h1:hb9wdF1z5waM+dSIICn1l0DkLVDT3hqhhQsDNUmHPRE= +golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/image v0.0.0-20211028202545-6944b10bf410 h1:hTftEOvwiOq2+O8k2D5/Q7COC7k5Qcrgc2TFURJYnvQ= +golang.org/x/image v0.0.0-20211028202545-6944b10bf410/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200413165638-669c56c373c4 h1:opSr2sbRXk5X5/givKrrKj9HXxFpW2sdCiP8MJSKLQY= +golang.org/x/sys v0.0.0-20200413165638-669c56c373c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/main.go b/main.go new file mode 100644 index 0000000..f573969 --- /dev/null +++ b/main.go @@ -0,0 +1,33 @@ +package main + +import ( + "fmt" + "os" + "sync" + "time" + + "github.com/galuszkak/pesel/algorithm" +) + +func main() { + channel := make(chan string) + wg := sync.WaitGroup{} + wg.Add(1) + if len(os.Args) != 2 { + fmt.Println("You need to provide path to PDF\nExample: go run main.go ./PIT.pdf ") + os.Exit(1) + } + filePath := os.Args[1] + // We are only interested in people older than 18 years + // So start date 2004/2/29 + // Also we want to include people from 18 to 60 years = 42 years + // 365 days * 42years + startDate := time.Date(2004, time.February, 29, 0, 0, 0, 0, time.UTC) + allDays := 365 * 42 + for i := 0; i < allDays; i++ { + go algorithm.GeneratePeselsForDate(startDate, channel) + go algorithm.DecryptPdf(filePath, channel, &wg) + startDate = startDate.AddDate(0, 0, -1) + } + wg.Wait() +}