decode.go (1880B)
1 package main 2 3 import ( 4 "log" 5 "os" 6 7 "github.com/abtrout/tdo" 8 ) 9 10 func main() { 11 bs, err := tdo.DecodePipedInput() 12 if err != nil { 13 log.Fatalf("Failed to read layer input: %v", err) 14 } 15 16 /* 17 // The key is 32 bits, and the plaintext is presumably a layer input. 18 // Hence we know how it will start. 19 key := make([]byte, 32) 20 knownPrefix := "==[ Layer 4/6: " 21 for i, b := range knownPrefix { 22 key[i] ^= bs[i] ^ byte(b) 23 } 24 25 // Bruteforce the rest of the key. We'll operate on the first 26 // 320 characters, since the plaintext also contains an ASCII85 27 // encoded payload which will mess up the frequencies. 28 search := bs[:320] 29 for i := len(knownPrefix); i < len(key); i++ { 30 var cand byte 31 var rank int 32 for j := 0; j < 256; j++ { 33 if gr := rankGuess(byte(j), i, search); gr > rank { 34 cand = byte(j) 35 rank = gr 36 log.Printf("Updated best guess %d with rank %d", j, gr) 37 } else { 38 log.Printf("Skipping %d", j) 39 } 40 } 41 key[i] = cand 42 log.Println("Key %d: candidate %d, rank %d", i, cand, rank) 43 } 44 */ 45 46 // MANUAL OVERRIDE::: After bruteforcing, I am hand tweaking the key 47 // based on the prefix I see in the decoded data. My guesses weren't 48 // perfect, but they were close! 49 key := make([]byte, 32) 50 prefix := "==[ Layer 4/6: Network Traffic ]" 51 for i, b := range prefix { 52 key[i] ^= bs[i] ^ byte(b) 53 } 54 out := repeatingKeyXOR(key, bs) 55 56 if _, err := os.Stdout.Write(out); err != nil { 57 log.Fatalf("Failed to write decoded output: %v", err) 58 } 59 } 60 61 /* 62 const freqs = "ULDRHS NIOATEuldrhs nioate" 63 64 func rankGuess(k byte, idx int, bs []byte) int { 65 var rank int 66 for i := 0; i < len(bs)/32; i++ { 67 b := bs[idx+(32*i)] 68 rank += 1 + strings.IndexByte(freqs, b^k) 69 } 70 return rank 71 } 72 */ 73 74 func repeatingKeyXOR(key, ct []byte) []byte { 75 res := make([]byte, len(ct)) 76 for i, b := range ct { 77 res[i] = b ^ key[i%len(key)] 78 } 79 return res 80 }