從Cerber勒索軟體中學習murmurhash演算法
阿新 • • 發佈:2019-02-07
?
def murmur3_x86_32(data, seed=0):[/size][/align][size=4] c1 = 0xcc9e2d51
c2 = 0x1b873593
r1 = 15
r2 = 13
m = 5
n = 0xe6546b64
length = len(data)
h1 = seed
rounded_end = (length & 0xfffffffc) # every block contain 4 bytes
for i in range(0, rounded_end, 4):
# translate to little endian load order
k1 = (ord(data[i]) & 0xff) | ((ord(data[i + 1]) & 0xff) << 8) | \
((ord(data[i + 2]) & 0xff) << 16) | (ord(data[i + 3]) << 24)
k1 *= c1
k1 = (k1 << r1) | ((k1 & 0xffffffff) >> (32-r1)) # ROTL32(k1,15)
k1 *= c2
h1 ^= k1
h1 = (h1 << r2) | ((h1 & 0xffffffff) >> (32-r2)) # ROTL32(h1,13)
h1 = h1 * m + n
# the last block which is < 4 bytes
k1 = 0
val = length & 0x03
# the last block is 3 bytes
if val == 3:
k1 = (ord(data[rounded_end + 2]) & 0xff) << 16
# the last block is 2 bytes
if val in [2, 3]:
k1 |= (ord(data[rounded_end + 1]) & 0xff) << 8
# the last block is 1 bytes
if val in [1, 2, 3]:
k1 |= ord(data[rounded_end]) & 0xff # translate to little endian load order
k1 *= c1
k1 = (k1 << r1) | ((k1 & 0xffffffff) >> (32-r1))
k1 *= c2
h1 ^= k1
# finalization
h1 ^= length
h1 ^= ((h1 & 0xffffffff) >> 16)
h1 *= 0x85ebca6b
h1 ^= ((h1 & 0xffffffff) >> 13)
h1 *= 0xc2b2ae35
h1 ^= ((h1 & 0xffffffff) >> 16)
# for 32 bit, get the last 32 bits
return h1 & 0xffffffff 對樣本中的呼叫 murmurhash的地方下斷,可以看到對資料“65
2F3B 3C D1 40 02 4C BA 68 C0 D0”進行hash的結果為“BF35B592”
通過我們的指令碼驗證,對比結果,可以看到我們指令碼的執行結果也為“BF35B592”
cerber勒索軟體中對murmurhash演算法的使用
cerber勒索軟體對murmurhash函式的使用有兩點我們要搞清楚。 1. Murmurhash函式的seed值為什麼? 2. 勒索軟體呼叫murmurhash的作用是什麼?
對於第一個問題: 通過對cerber軟體中murmurhash演算法的逆向,可以看到seed的值為0,在下面的程式碼中的edx的值就為murmurhash演算法的初始化的seed值
對於第二個問題
通過上圖可以看出,cerber勒索軟體中共有5處使用了murmurhash函式,實際上只在三個函式中呼叫了murmurhash函式,呼叫murmurhash函式的函式為: 40B074解密出勒索使用的config內容後,解析config內容 409ADE解密字串函式中使用 401DB9加密檔案時,生成murmurhash儲存在加密後的檔案中
總結
本文只是對cerber勒索軟體中的murmurhash演算法進行了分析,對這款勒索軟體家族的描述可以參考網路上的其他文章。由於本人也是第一次聽說murmur演算法,文章為自己分析cerber勒索遇到新的加密演算法時的一點學習總結,有分析不恰當的地方,還望海涵。
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
c2 = 0x1b873593
r1 = 15
r2 = 13
m = 5
n = 0xe6546b64
length = len(data)
h1 = seed
rounded_end = (length & 0xfffffffc) # every block contain 4 bytes
for i in range(0, rounded_end, 4):
# translate to little endian load order
k1 = (ord(data[i]) & 0xff) | ((ord(data[i + 1]) & 0xff) << 8) | \
((ord(data[i + 2]) & 0xff) << 16) | (ord(data[i + 3]) << 24)
k1 *= c1
k1 = (k1 << r1) | ((k1 & 0xffffffff) >> (32-r1)) # ROTL32(k1,15)
k1 *= c2
h1 ^= k1
h1 = (h1 << r2) | ((h1 & 0xffffffff) >> (32-r2)) # ROTL32(h1,13)
h1 = h1 * m + n
# the last block which is < 4 bytes
k1 = 0
val = length & 0x03
# the last block is 3 bytes
if val == 3:
k1 = (ord(data[rounded_end + 2]) & 0xff) << 16
# the last block is 2 bytes
if val in [2, 3]:
k1 |= (ord(data[rounded_end + 1]) & 0xff) << 8
# the last block is 1 bytes
if val in [1, 2, 3]:
k1 |= ord(data[rounded_end]) & 0xff # translate to little endian load order
k1 *= c1
k1 = (k1 << r1) | ((k1 & 0xffffffff) >> (32-r1))
k1 *= c2
h1 ^= k1
# finalization
h1 ^= length
h1 ^= ((h1 & 0xffffffff) >> 16)
h1 *= 0x85ebca6b
h1 ^= ((h1 & 0xffffffff) >> 13)
h1 *= 0xc2b2ae35
h1 ^= ((h1 & 0xffffffff) >> 16)
# for 32 bit, get the last 32 bits
return h1 & 0xffffffff 對樣本中的呼叫
cerber勒索軟體中對murmurhash演算法的使用
cerber勒索軟體對murmurhash函式的使用有兩點我們要搞清楚。 1. Murmurhash函式的seed值為什麼? 2. 勒索軟體呼叫murmurhash的作用是什麼?
對於第一個問題: 通過對cerber軟體中murmurhash演算法的逆向,可以看到seed的值為0,在下面的程式碼中的edx的值就為murmurhash演算法的初始化的seed值
對於第二個問題
通過上圖可以看出,cerber勒索軟體中共有5處使用了murmurhash函式,實際上只在三個函式中呼叫了murmurhash函式,呼叫murmurhash函式的函式為: 40B074解密出勒索使用的config內容後,解析config內容 409ADE解密字串函式中使用 401DB9加密檔案時,生成murmurhash儲存在加密後的檔案中
-
對於40B074處的演算法使用:
-
對於409ADE解密字串的使用
-
對於加密檔案函式401DB9中的使用
總結
本文只是對cerber勒索軟體中的murmurhash演算法進行了分析,對這款勒索軟體家族的描述可以參考網路上的其他文章。由於本人也是第一次聽說murmur演算法,文章為自己分析cerber勒索遇到新的加密演算法時的一點學習總結,有分析不恰當的地方,還望海涵。