Skip to content

Instantly share code, notes, and snippets.

@ix64

ix64/mega.go Secret

Created May 28, 2023 09:14
Mega Key Brute-Force Attack
package main
import (
"bytes"
"context"
"crypto/aes"
"crypto/cipher"
"encoding/base64"
"encoding/binary"
"errors"
"log"
"math"
"runtime"
"sync"
)
func main() {
log.Println("Start Running")
a, err := newAttempt(
"NQf1ctaRp0DwVAPJYybfRvoGQ_OOYJ8YOfZDXbqa0KpalCK-KHJSdTya0Eo-k01r87bdu6yfCaCNbUFsUSC1ng",
"eWhpXnJOmswYAY_Vx93VF2moxjM4uQuhv_7hII",
5,
)
if err != nil {
log.Fatal(err)
}
ret, err := a.runMultiThread(runtime.NumCPU())
if err != nil {
log.Fatal(err)
}
log.Println("FOUND: ", ret)
}
type attempt struct {
cipherText []byte
keyPrefix string
keyRestLen int
}
func newAttempt(cipherText string, keyPrefix string, keyRestLen int) (*attempt, error) {
cipherBytes, err := base64.RawURLEncoding.DecodeString(cipherText)
if err != nil {
return nil, err
}
return &attempt{
cipherText: cipherBytes,
keyPrefix: keyPrefix,
keyRestLen: keyRestLen,
}, nil
}
func (a *attempt) runMultiThread(threads int) (retKey string, retErr error) {
times := int(math.Pow(64, float64(a.keyRestLen)))
timePerThread := times / threads
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
wg := sync.WaitGroup{}
for i := 0; i < threads; i++ {
i := i
go func() {
key, err := a.runWorker(ctx, i*timePerThread, (i+1)*timePerThread)
if err == nil {
retKey = key
cancel()
} else if err != context.Canceled {
retErr = err
}
wg.Done()
}()
wg.Add(1)
}
wg.Wait()
if retKey == "" {
retErr = errors.New("key not found")
}
return
}
func (a *attempt) runWorker(ctx context.Context, start, end int) (string, error) {
outBuf := make([]byte, len(a.cipherText))
for i := start; i < end; i++ {
keyStr := a.keyPrefix + index2Base64Str(i, a.keyRestLen)
key, err := deriveKey(keyStr)
if err != nil {
return "", err
}
if err := a.decodeAttr(key, outBuf); err != nil {
return "", err
}
if bytes.HasPrefix(outBuf, []byte("MEGA")) {
return keyStr, nil
}
if i%1000000 == 0 {
if err := ctx.Err(); err != nil {
return "", err
}
}
}
return "", nil
}
func (a *attempt) decodeAttr(key []byte, outBuf []byte) error {
block, err := aes.NewCipher(key)
if err != nil {
return err
}
emptyIV := make([]byte, 16)
dec := cipher.NewCBCDecrypter(block, emptyIV)
dec.CryptBlocks(outBuf, a.cipherText)
return nil
}
func index2Base64Str(i int, width int) string {
const encodeURL = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"
buf := make([]byte, width)
for j := 0; j < width; j++ {
buf[j] = encodeURL[i%64]
i /= 64
}
return string(buf)
}
func deriveKey(keyStr string) (key []byte, err error) {
aByte, err := base64.RawURLEncoding.DecodeString(keyStr)
if err != nil {
return nil, err
}
aU32 := make([]uint32, 8)
for i := 0; i < 8; i++ {
aU32[i] = binary.BigEndian.Uint32(aByte[i*4 : (i+1)*4])
}
keyU32 := []uint32{
aU32[0] ^ aU32[4],
aU32[1] ^ aU32[5],
aU32[2] ^ aU32[6],
aU32[3] ^ aU32[7],
}
keyByte := make([]byte, 16)
for i := 0; i < 4; i++ {
keyByte[i*4] = byte(keyU32[i] >> 24)
keyByte[i*4+1] = byte(keyU32[i] >> 16)
keyByte[i*4+2] = byte(keyU32[i] >> 8)
keyByte[i*4+3] = byte(keyU32[i])
}
return keyByte, nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment