Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
103 changes: 103 additions & 0 deletions ddp_example.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
// Dynamic decryption procedure example - (c) 2005 - 2006 Omar A. Herrera Reyna
// This code is released under GNU General Public License v3.0
//
// The following Go program illustrates an implementation of a DDP.
// It mirrors the original C example but uses Go's standard libraries.
// The encrypted payload is decrypted only when the key derived from
// the current UTC hour, month and year matches the expected value.
// When successful, the program prints the decrypted bytes.
// Note: Executing the decrypted bytes as code is not included here.

package main

import (
"crypto/cipher"
"crypto/md5"
"encoding/hex"
"fmt"
"golang.org/x/crypto/blowfish"
"time"
)

const (
scodeSize = 172 + 8
)

var (
keyXOR = [8]byte{0x0F, 0x20, 0x6A, 0x04, 0x10, 0x0D, 0x6E, 0x08}
scodeMD5 = [16]byte{0x81, 0xED, 0xD3, 0x62, 0xC6, 0xE3, 0x89, 0x4F,
0xD5, 0xA5, 0x6C, 0x95, 0xCE, 0x55, 0x25, 0xE0}
encryptedPayload = []byte{
0xD7, 0x5A, 0x9A, 0x75, 0x12, 0x8C, 0x44, 0xC0, 0xC3, 0xEB, 0xBC, 0x32, 0x86, 0xD8, 0xB2, 0xD4,
0xAF, 0xB6, 0x36, 0xB4, 0x24, 0x4D, 0x7F, 0x2F, 0x6D, 0x70, 0x32, 0xA7, 0xDD, 0xCC, 0xAB, 0x0C,
0x5F, 0x9E, 0x79, 0x26, 0x70, 0xA5, 0x6F, 0xAC, 0xB4, 0xB6, 0x71, 0x13, 0xBE, 0xDB, 0xDA, 0x0F,
0xAD, 0x1C, 0x10, 0x8D, 0x31, 0x18, 0x34, 0x5E, 0xEA, 0x74, 0xC7, 0xD2, 0x55, 0x86, 0xB8, 0xFA,
0x40, 0x47, 0x0E, 0x78, 0xA5, 0xAB, 0x45, 0x8E, 0x08, 0x0C, 0xDA, 0x68, 0xD6, 0x42, 0x54, 0x99,
0xE6, 0x54, 0xA1, 0xFC, 0x48, 0xAB, 0xBA, 0x9E, 0x62, 0x6D, 0x52, 0x3C, 0x49, 0xCA, 0x2A, 0xAB,
0x63, 0x0B, 0xCD, 0x1A, 0x3C, 0xF7, 0x15, 0x2E, 0xB1, 0x4D, 0x15, 0x11, 0xEA, 0x78, 0x27, 0x3B,
0x33, 0x81, 0xD3, 0x9D, 0x8D, 0x9B, 0xE7, 0xBB, 0x0C, 0xC5, 0x97, 0x8C, 0x8E, 0x38, 0x49, 0xE7,
0xFD, 0xAB, 0x13, 0x28, 0x9F, 0x45, 0xAC, 0x1C, 0xE0, 0x62, 0xC3, 0x82, 0x47, 0xB8, 0x4A, 0xA3,
0xB0, 0x14, 0x2C, 0xFA, 0xC4, 0xE1, 0x51, 0x6A, 0x15, 0x77, 0xDF, 0xA0, 0x3F, 0x24, 0x98, 0x36,
0x7B, 0x2D, 0xC2, 0x22, 0x82, 0x76, 0x9A, 0xBC, 0x81, 0xBF, 0x09, 0x01, 0x9C, 0xBE, 0xB2, 0x54,
0xEB, 0xF2, 0xFC, 0x7D, 0xD1, 0x77, 0x44, 0xDB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
}
)

func deriveKey(t time.Time) [8]byte {
var keyTime [8]byte
keyTime[0] = byte(t.Hour())
keyTime[1] = byte(t.Month() - 1) // tm_mon is 0-based
year := t.Year() - 1900 // tm_year is years since 1900
keyTime[2] = byte(year)
keyTime[3] = byte(year >> 8)
keyTime[4] = keyTime[0]
keyTime[5] = keyTime[1]
keyTime[6] = keyTime[2]
keyTime[7] = keyTime[3]

var key [8]byte
for i := 0; i < 8; i++ {
key[i] = keyTime[i] ^ keyXOR[i]
}
return key
}

func decryptPayload(key [8]byte) ([]byte, error) {
block, err := blowfish.NewCipher(key[:])
if err != nil {
return nil, err
}
decrypted := make([]byte, len(encryptedPayload))
iv := make([]byte, blowfish.BlockSize)
mode := cipher.NewCBCDecrypter(block, iv)
paddedLen := ((scodeSize + blowfish.BlockSize - 1) / blowfish.BlockSize) * blowfish.BlockSize
buf := make([]byte, paddedLen)
copy(buf, encryptedPayload[:scodeSize])
mode.CryptBlocks(decrypted[:paddedLen], buf)
copy(decrypted[paddedLen:], encryptedPayload[paddedLen:])
return decrypted, nil
}

func main() {
var decrypted []byte
for {
time.Sleep(10 * time.Second)
key := deriveKey(time.Now().UTC())
d, err := decryptPayload(key)
if err != nil {
fmt.Println("decrypt error:", err)
continue
}
hash := md5.Sum(d[8:scodeSize])
if hash == scodeMD5 {
decrypted = d
fmt.Printf("CORRECT KEY = %X\n", key)
break
}
}

fmt.Println("Encrypted payload:")
fmt.Println(hex.Dump(encryptedPayload))
fmt.Println("Decrypted payload:")
fmt.Println(hex.Dump(decrypted[8:]))
}
5 changes: 5 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module ddp

go 1.23.8

require golang.org/x/crypto v0.39.0
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
golang.org/x/crypto v0.39.0 h1:SHs+kF4LP+f+p14esP5jAoDpHU8Gu/v9lFRK6IT5imM=
golang.org/x/crypto v0.39.0/go.mod h1:L+Xg3Wf6HoL4Bn4238Z6ft6KfEpN0tJGo53AAPC632U=