Created
December 30, 2015 08:35
-
-
Save geekman/e506fe45b55a8f5a9885 to your computer and use it in GitHub Desktop.
32c3CTF 2015 bruteforce tool for "config.bin"
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* bruteforce-cfg1.go | |
* to bruteforce CFG1 encryption passwords for 32c3CTF "config.bin" | |
* | |
* @zxcvgm | |
*/ | |
package main | |
import ( | |
brutedict "github.com/dieyushi/golang-brutedict" | |
"crypto/aes" | |
"crypto/md5" | |
"io/ioutil" | |
"encoding/binary" | |
"bytes" | |
"sync" | |
"fmt" | |
"os" | |
) | |
func main() { | |
file, err := os.Open(os.Args[1]) | |
if err != nil { | |
fmt.Println(err) | |
return | |
} | |
defer file.Close() | |
file.Seek(4 + 4 + 8 + 7 + 1 + 2, os.SEEK_SET) | |
// padding size. not used in the end | |
var padding uint16 | |
binary.Read(file, binary.BigEndian, &padding) | |
data_hash := make([]byte, 16) | |
file.Seek(4, os.SEEK_CUR) | |
file.Read(data_hash) | |
// read header to compute checksum | |
headerBytes := make([]byte, 0x30) | |
file.ReadAt(headerBytes, 0) | |
for i := 8; i < 16; i++ { | |
headerBytes[i] = 0 | |
} | |
fmt.Printf("hdr hash = %x\n", md5.Sum(headerBytes)) | |
// header is 0x30 bytes | |
file.Seek(0x30, os.SEEK_SET) | |
src, err := ioutil.ReadAll(file) | |
fmt.Printf("data hash = %x\n", data_hash) | |
try_pwds := make(chan string, 2048) | |
var wg sync.WaitGroup | |
for i := 0; i < 4; i++ { | |
wg.Add(1) | |
go func() { | |
for pwd := range try_pwds { | |
//fmt.Printf("trying %s\n", pwd) | |
cksum := decryptHash(pwd, src) | |
if bytes.Equal(data_hash, cksum[:]) { | |
fmt.Printf("found password! %s\n", pwd) | |
os.Exit(0) | |
} | |
} | |
wg.Done() | |
}() | |
} | |
// generate passwords here | |
try_pwds <- "dummy" | |
// password len is hardcoded here | |
bd := brutedict.New(true, true, true, 5, 5) | |
defer bd.Close() | |
for { | |
id := bd.Id() | |
if id != "" { | |
try_pwds <- id | |
} else { | |
break | |
} | |
} | |
close(try_pwds) | |
wg.Wait() | |
//cksum := decryptHash("dummy", src) | |
//fmt.Printf("computed cksum %x\n", cksum) | |
//fmt.Printf("matches? %s\n", bytes.Equal(data_hash, cksum[:])) | |
} | |
// decrypt and hash at the same time | |
func decryptHash(keyStr string, data []byte)[]byte { | |
key := make([]byte, 32) | |
dst := make([]byte, aes.BlockSize) | |
copy(key, keyStr) | |
//fmt.Printf("key: %x\n", key) | |
c, err := aes.NewCipher(key) | |
if err != nil { | |
fmt.Println(err) | |
return nil | |
} | |
hash := md5.New() | |
n := 0 | |
l := len(data) | |
for n < l { | |
c.Decrypt(dst, data[n:n+aes.BlockSize]) | |
//fmt.Printf("offset %d\n", n) | |
//fmt.Printf("dec %x\n", dst) | |
hash.Write(dst) | |
n += aes.BlockSize | |
} | |
return hash.Sum(nil) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment