clickNgo/core/core.go
2025-02-03 20:48:19 +01:00

80 lines
1.5 KiB
Go

package core
import (
"crypto/aes"
"crypto/cipher"
"encoding/base64"
"encoding/hex"
"fmt"
"net/url"
"regexp"
"strings"
"unicode"
)
func DecryptURLs(jk string, crypted string) ([]string, error) {
key, err := convertJKToKey(jk)
if err != nil {
return []string{}, err
}
ciphertext, err := base64.StdEncoding.DecodeString(crypted)
if err != nil {
return []string{}, err
}
block, err := aes.NewCipher([]byte(key))
if err != nil {
return []string{}, err
}
if len(ciphertext)%aes.BlockSize != 0 {
return []string{}, fmt.Errorf("ciphertext has invalid length")
}
mode := cipher.NewCBCDecrypter(block, []byte(key))
mode.CryptBlocks(ciphertext, ciphertext)
return ExtractURLsFromString(fmt.Sprintf("%s", ciphertext)), nil
}
func ExtractURLsFromString(s string) []string {
URLs := []string{}
for _, line := range strings.Split(s, "\n") {
line = strings.TrimSpace(line)
line = strings.Map(func(r rune) rune {
if unicode.IsPrint(r) {
return r
}
return -1
}, line)
parsedURL, err := url.Parse(line)
if err != nil || parsedURL.Scheme == "" || parsedURL.Host == "" {
continue
}
URLs = append(URLs, line)
}
return URLs
}
func convertJKToKey(jk string) (string, error) {
re := regexp.MustCompile(`return '(\d{32})'`)
matches := re.FindStringSubmatch(jk)
if len(matches) < 2 {
return "", fmt.Errorf("no key found for jk: %s", jk)
}
base10key, err := hex.DecodeString(matches[1])
if err != nil {
return "", fmt.Errorf("jk is invalid: %s", jk)
}
return fmt.Sprintf("%s", base10key), nil
}