qq闪照恢复--go

闪照缓存目录:

文件管理/Android/data/com.tencent.mobileqq/xxx/Cache_xxxxxxxxx_fp

code

爆破DES 8字节密钥,每字节仅需考虑9种字符("02468@BDF"),9**8=43046721 种可能

// reference: https://keuin.cc/blog/cracking-encrypted-qq-flash-photos
//
//	https://github.com/keuin/mobileqq-flash-photo-cracker
package main

import (
	"bufio"
	"bytes"
	"crypto/cipher"
	"crypto/des"
	"crypto/md5"
	"flag"

	"fmt"
	"io"
	"os"
	"time"
)

const (
	keychars      string = "02468@BDF"
	KEYSPACE_SIZE int    = 43046721 //9**8

)

var (
	jpg_magic    = []byte{0xff, 0xd8, 0xff}
	// png_magic    = []byte{0x89, 0x50, 0x4e, 0x47}
	fp_magic     = []byte{0x45, 0x4E, 0x43, 0x52, 0x59, 0x50, 0x54, 0x3A} //ENCRYPT:
	bruteThreads int

	outPath   string
	fpPath    string
	isFindKey bool = false

	done chan int
)

func checkPad(block *cipher.Block, lastData []byte) (bool, []byte) {
	buf := make([]byte, 8)
	(*block).Decrypt(buf, lastData[:8])
	var pad_size = buf[7]
	if pad_size > 8 {
		return false, nil
	}
	for i := byte(8 - pad_size); i < pad_size; i++ {
		if buf[i] != pad_size {
			return false, nil
		}
	}
	return true, buf[:8-pad_size]
}
func testDec(key, encData []byte) bool {
	block, err := des.NewCipher(key)
	if err != nil {
		return false
	}
	headerData := make([]byte, 8)
	block.Decrypt(headerData, encData[:8])
	// if bytes.Equal(headerData[:4], png_magic) || bytes.Equal(headerData[:3], jpg_magic) {
	if  bytes.Equal(headerData[:3], jpg_magic) {
		fmt.Printf("[+]DES key:%s <---dec---> magic:%s\n", key, headerData)
		isPad, lastpart := checkPad(&block, encData[len(encData)-8:])
		if !isPad {
			fmt.Println("[!]DES key Incorrect!")
			return false
		}
		if isFindKey {
			return false
		}
		isFindKey = true
		// fmt.Printf("[*]DES key:%s\n", key)
		buf := make([]byte, len(encData)-16)
		bs := block.BlockSize()
		dst := buf
		data := encData[8 : len(encData)-8]
		for len(data) > 0 {
			block.Decrypt(dst, data[:bs])
			data = data[bs:]
			dst = dst[bs:]
		}
		x := append(headerData, buf...)
		x = append(x, lastpart...)
		writeData(outPath, x)
		fmt.Printf("[*]key:%s<--------->md5:%X\n", key, md5.Sum(x))
		fmt.Println("[*]save to:", outPath)
		return true
	}
	return false
}

func worker(a, b int, encData []byte) {
	var (
		isFind bool
		// k      []byte
	)
	start := time.Now()
	for i := a; i < b; i++ {
		if isFindKey {
			break
		}
		// isFind, k = testDec([]byte(Keys[i]))
		isFind = testDec(genKey(i), encData)
		if isFind {
			isFindKey = true
			fmt.Printf("[+]genKey(%v)\n", i)
			// fmt.Println("[-]find key:", hex.EncodeToString(k))
			break
		}
	}
	elapsed := time.Since(start)
	fmt.Printf("[-][%v-%v] time:%v\n", a, b, elapsed)
	done <- 1
}

// #define FILL_KEY(buf, key, i) \
//         do { ((buf)[7-(i)] = keychars[(key)%9u]); (key) /= 9u; } while(0)

func genKey(a int) []byte {
	var s [8]byte
	for i := 0; i < 8; i++ {
		s[7-i] = keychars[a%9]
		a /= 9
	}
	return s[:]
}
func writeData(fpath string, data []byte) {
	fi, err := os.Create(fpath)
	if err != nil {
		fmt.Println(err)
		return
	}
	defer fi.Close()
	_, err = fi.Write(data)
	if err != nil {
		fmt.Println(err)
		return
	}
}
func readData(fpath string) []byte {
	fi, err := os.Open(fpath)
	if err != nil {
		fmt.Println(err)
		return nil
	}
	defer fi.Close()

	r := bufio.NewReader(fi)
	tmp := make([]byte, 8)
	n, err := r.Read(tmp)
	if err != nil && err != io.EOF && n != 8 {
		fmt.Println(err)
		return nil
	}
	if !bytes.Equal(tmp, fp_magic) {
		return nil
	}
	var chunks []byte
	buf := make([]byte, 4096)
	for {
		n, err := r.Read(buf)
		if err != nil && err != io.EOF {
			panic(err)
		}
		if n == 0 {
			break
		}
		chunks = append(chunks, buf[:n]...)
	}
	return chunks
}
func doRun() {
	done = make(chan int, bruteThreads)
	range_size := int(KEYSPACE_SIZE / bruteThreads)
	encData := readData(fpPath)
	if encData == nil {
		return
	}
	for i := 0; i < bruteThreads-1; i++ {
		go worker(range_size*i, range_size*i+range_size, encData)
	}
	go worker(range_size*(bruteThreads-1), KEYSPACE_SIZE, encData)
	//wait
	for i := 0; i < cap(done); i++ {
		<-done
	}
	fmt.Println("end")
}

func init() {
	flag.StringVar(&outPath, "out", "", "(op)-->out path")
	flag.StringVar(&fpPath, "in", "", "[must]-->in path")
	flag.IntVar(&bruteThreads, "threads", 10, "(op)-->brute threads(Goroutine)")
	flag.Parse()
	if fpPath == "" {
		flag.Usage()
		os.Exit(-1)
	}
	if outPath == "" {
		outPath = fpPath + "_dec.png"
	}
}
func main() {
	doRun()
}

log

main.exe -in pic.xb -out out.png -threads 40
[+]DES key:2B0F2880 <---dec---> magic:���� �Ex
[-][31208872-32285040] time:20.0654193s
[-][40894384-41970552] time:20.0654193s
[-][3228504-4304672] time:20.0947397s
[-][19371024-20447192] time:20.0684109s
[-][16142520-17218688] time:20.0684109s
[-][0-1076168] time:20.0947397s
[-][29056536-30132704] time:20.0670064s
[-][4304672-5380840] time:20.0953299s
[-][35513544-36589712] time:20.0670064s
[-][5380840-6457008] time:20.0947397s
[-][8609344-9685512] time:20.0953299s
[-][2152336-3228504] time:20.0953299s
[-][9685512-10761680] time:20.0947397s
[-][1076168-2152336] time:20.0953299s
[-][21523360-22599528] time:20.0680023s
[-][36589712-37665880] time:20.0670064s
[-][18294856-19371024] time:20.0690011s
[-][34437376-35513544] time:20.0680023s
[-][39818216-40894384] time:20.0670064s
[-][25828032-26904200] time:20.0883133s
[-][32285040-33361208] time:20.0654193s
[-][22599528-23675696] time:20.0685076s
[-][12914016-13990184] time:20.0726921s
[-][30132704-31208872] time:20.0675117s
[-][13990184-15066352] time:20.0715966s
[-][20447192-21523360] time:20.0695064s
[-][17218688-18294856] time:20.0695064s
[-][23675696-24751864] time:20.0685076s
[-][6457008-7533176] time:20.0958352s
[-][11837848-12914016] time:20.0715966s
[-][27980368-29056536] time:20.0685076s
[-][37665880-38742048] time:20.0685076s
[-][33361208-34437376] time:20.0685076s
[-][15066352-16142520] time:20.0695064s
[-][41970552-43046721] time:20.0953316s
[-][38742048-39818216] time:20.0664162s
[-][24751864-25828032] time:20.0685076s
[-][26904200-27980368] time:20.0685076s
[-][10761680-11837848] time:20.0958352s
[*]key:2B0F2880<--------->md5:2B1F2980A362CBD2A67251C2229BBEF5
[*]save to: out.png
[+]genKey(8025192)
[-][7533176-8609344] time:20.1167501s
end
posted @ 2023-06-25 23:27  DirWangK  阅读(313)  评论(0编辑  收藏  举报