80 lines
1.5 KiB
Go
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
|
|
}
|