在计算机科学中,我们通常认为信息是一种数据或指令的集合,泛指我们通过载体传播的内容.
熵是一个热力学概念,是形容物质混乱程度的单位,当物质混乱程度越高的时候熵值越高.在上个世纪40年度,香农将熵引入到信息论中,把信息中排除冗余后的平均信息量定义为信息熵.
我们假定有一列信息abaaabbababa...
,其中字母a
出现的概率是p,则字母b
出现的概率是(1-p),那么当信息的长度为N的时候,信息中就会存在pN个a
,以及(1-p)个b
,那么这个信息的排列方式就有N!/(pN)!((1-p)N)!
种,对于a
的自信息量就是Pa=-p*log2(p)
,那么整个信息列的熵就是S=-p*log2(p)-(1-p)*log2(1-p)
,这里用log2做底数是因为只有ab两种情况.
那么现在我们对整个公式进行抽象,可以得到
如果把2也当作是一个变量的话,我们可以进一步得出
这就是大名鼎鼎的香农公式了.
信息熵目前被广泛应用在各种压缩场景种,对于长度相同的信息,熵值p越大,则表明信息内容越有规律,可压缩的体积就越大;p越小,则信息内容越随机,可压缩的体积就越小.
对于非PE文件,例如恶意脚本,为了逃避杀软检测经常使用加密\压缩等手段,无论如何处理都会增大信息的随机性,那么我们就可以利用信息熵来做对应检测了.
一个文本信息的基本单位是字节,一个字节的范围是0~255,那么我们就可以得到公式
代码:
样本:
我们分别对Base64前后的数据进行计算,可以得到
信息熵会明显增大,但是这里不是绝对的,因为这个信息熵是标识信息的复杂度的,所以在某些加密方法中,会显著降低信息熵,例如:
他的信息熵只有2.3509156
,我们就可以根据这个原理做一个期望,一段符合自然语言语法的信息,他的信息熵范围是可预期的,同样长度的信息,如果信息熵低于或者高于,都有可能是一段混淆加密的信息.
当然如果混淆算法经过特殊处理,是可以计算到一个接近正常的信息熵,那么我们需要更多的维度去判断,这里我们可以使用一个密码学的概念 巧合指数
以英文字母为例,从26个字母中随机拿出一个字母的概率是1/26,随机选择两个字母,选择出相同字母对的概率是
而在自然语言中,英文的巧合指数是一个数学期望的,大概等于
抽象后我们可以通过这样一个公式来计算
![图片描述](upload/attach/202106/258629_7284V9EXTWSZVB8.png)
其中fi标识某字母在该段文字中出现的次数
而我们常用的脚本语言也是接近自然语言语法,所以他的巧合指数也是可以获得一个期望的,我之前简单计算过,大概是在0.046~0.047
之间
贴代码:
样本我们依然选择上面的:
之后我们分别计算他们的巧合指数
由于样本长度不足所以不会有太明显的区别,我另外对一个线上样本做了计算
![图片描述](upload/attach/202106/258629_RVPEDV8JB7B3ZE7.png)
![图片描述](upload/attach/202106/258629_KYGMTGZHB4YBGYM.png)
巧合指数分别为0.1249589
和0.0310315
,明显上面的会远远高于我们的期望.
这一步我写的比较简单,直接计算的H(Y|X),其实是可以从条件熵和联合熵分别去计算,废话不说上代码:
突然翻到很早以前写的一段测试程序,很早之前是打算用来判断一段信息是中文还是英文,是不是符合自然语言的,逐步完善知识后发现,其实可以恶意脚本识别的一个子集,本来打算儿童节当天发出来,一直拖到现在,就当抛砖引玉了,谢谢观看.
log2(
1
/
pa)
+
log2(
1
/
pb)
+
...
+
log2(
1
/
pn)
=
∑ log2(
1
/
pn)
log2(
1
/
pa)
+
log2(
1
/
pb)
+
...
+
log2(
1
/
pn)
=
∑ log2(
1
/
pn)
S
=
log(
1
/
pa)
+
log(
1
/
pb)
+
...
+
log(
1
/
pn)
=
∑ log(
1
/
pn)
=
∑
-
p
*
log(p)
S
=
log(
1
/
pa)
+
log(
1
/
pb)
+
...
+
log(
1
/
pn)
=
∑ log(
1
/
pn)
=
∑
-
p
*
log(p)
I(n)
=
(S(a
/
256
))
+
(S(b
/
256
))....(S(n
/
256
))
I(n)
=
(S(a
/
256
))
+
(S(b
/
256
))....(S(n
/
256
))
double CEntropy::calculate()
{
double entropy
=
0
;
DWORD dwMapSize
=
g_GlobalInfo.GetSize();
for
(
int
i
=
0
; i <
256
; i
+
+
)
{
double p_x
=
double(g_GlobalInfo.count(((char)i)))
/
dwMapSize;
if
(p_x >
0
)
entropy
+
=
-
p_x
*
(log(p_x));
}
return
entropy;
}
double CEntropy::calculate()
{
double entropy
=
0
;
DWORD dwMapSize
=
g_GlobalInfo.GetSize();
for
(
int
i
=
0
; i <
256
; i
+
+
)
{
double p_x
=
double(g_GlobalInfo.count(((char)i)))
/
dwMapSize;
if
(p_x >
0
)
entropy
+
=
-
p_x
*
(log(p_x));
}
return
entropy;
}
aGVsbG8gd29yZA
=
=
hello word
aGVsbG8gd29yZA
=
=
hello word
encode_base64_entropy
=
3.0351414
decode_base64_entropy
=
2.1535325
encode_base64_entropy
=
3.0351414
decode_base64_entropy
=
2.1535325
Chr
(
104
)
+
Chr
(
101
)
+
Chr
(
108
)
+
Chr
(
108
)
+
Chr
(
111
)
+
Chr
(
9
)
+
Chr
(
119
)
+
Chr
(
111
)
+
Chr
(
114
)
+
Chr
(
100
)
Chr
(
104
)
+
Chr
(
101
)
+
Chr
(
108
)
+
Chr
(
108
)
+
Chr
(
111
)
+
Chr
(
9
)
+
Chr
(
119
)
+
Chr
(
111
)
+
Chr
(
114
)
+
Chr
(
100
)
double CLanguageIC::calculate()
{
DWORD64 _char_count
=
0
;
DWORD64 _total_char_count
=
0
;
for
(
int
i
=
0
; i <
256
; i
+
+
)
{
DWORD64 charcount
=
g_GlobalInfo.count(((char)i));
_char_count
+
=
charcount
*
(charcount
-
1
);
_total_char_count
+
=
charcount;
}
double ic
=
0
;
if
(_total_char_count
-
1
!
=
0
)
ic
=
double(_char_count)
/
(_total_char_count
*
(_total_char_count
-
1
));
calculate_char_count();
return
ic;
}
double CLanguageIC::calculate()
{
DWORD64 _char_count
=
0
;
DWORD64 _total_char_count
=
0
;
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课
最后于 2021-6-5 17:53
被wuxiwudi编辑
,原因: