Crypto_Papers_Read_&_Recurrent

本博客将不可避免的产生:

  • 致命笔误
  • 直接复制
  • 不懂装懂
  • 懒得排版
  • 证明显然
  • 逻辑混乱
  • 中式翻译

[TOC]

0x01 RSA私钥过大的漏洞

Link

使用过小的RSA私钥指数引发的危险在十多年前就已经为人所知。用户虽然已知这些威胁,但依然希望从实质上降低解密时间,可能会倾向于使用一个与很大的私钥相关的小负素数。这篇论文展示了Wiener, Boneh & Durfee, Blomer & May的针对小私钥指数的攻击,以及由上述攻击延申的对含多个素数的RSA的攻击,同样适用于私钥指数非常大的情况

1.1 低加密指数攻击

考虑公钥指数 的RSA。如果明文大小在 区间内,解密仅需简单的对密文 开三次方即可,因为 。考虑处于 区间内的明文。相应的,在有限域的表示里,。令 ,解密仅需计算出 的三次方,即 ​ 。

1.2 连分数攻击( Wiener )

针对RSA小私钥指数的Wiener 攻击,可以轻而易举的扩展到针对大私钥指数的攻击。

定理1. 令RSA的模数为,私钥指数 满足 ,则公钥 已知的情况下,在多项式时间 内可以求得私钥。

由RSA公式: ,可化为 。令 ,等式也可以写成 为正,且 。根据连分数的性质可求得

image-20240129210633885

因此, 的一个连分数项。通过连分数算法我们可以计算所有 连分数的子项,验证正确的 。令 连分数的子项,我们可以计算 并尝试分解 。当 时,,就能实现分解 分解后,计算 ,自然地

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
from Crypto.Util.number import getPrime, long_to_bytes as ltb, bytes_to_long as btl 
DEBUG = True
flag = b'AL3XEI_FAKE_FLAG'

p,q = [getPrime(512) for _ in "pq"]
D = getPrime(250)
phi = ( p - 1 ) * ( q - 1 )
n = p * q
d = phi - D
e = int(pow(d, -1, phi))
m = btl(flag)
c = pow( m, e, n )

print(f"n = { n }")
print(f"e = { e }")
print(f"c = { c }")




if DEBUG:
print(D < int(( 1 / 3 ) * ( n ** ( 1 / 4) ))) # True
print(d > int(( 1 / 3 ) * ( n ** ( 1 / 4) ))) # True
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
from Crypto.Util.number import getPrime, long_to_bytes as ltb, bytes_to_long as btl 
from gmpy2 import invert, powmod

n =
e =
c =


for kD in continued_fraction(e / n).convergents():
k = kD.numer()
D = kD.denom()
try:
if ( e * D + 1) % k == 0:
phi = ( e * D + 1) // k
d = phi - D
if (e * d) % phi == 1:
m = powmod(c, d, n)
if ltb(m) == b'AL3XEI_FAKE_FLAG':
print(ltb(m))
break

except Exception:
continue
# b'AL3XEI_FAKE_FLAG'

1.3 小逆元攻击( Boneh & Durfee )

Boneh & Durfee 提出的小私钥指数攻击是建立在解决小逆元问题上的。也即,给定整数 ,求较小的 使得 成立。特别的,对于RSA,令 ,且 。我们希望能找到 满足 上述方程的一个解是 是正整数,满足 。求得这个解就能恢复 ,就能通过 求得私钥指数。Boneh & Durfee 攻击能够成立的界是

定理2. 对针对RSA小私钥指数的,基于小逆元攻击的方法,如果在 情况下成立,则在 ​ 情况下也成立。

由RSA公式: ,可化为 。等式也可以写成 是正整数。令 ,通过模 化简上式得: 就可以回到与 Boneh & Durfee 相同的证明开端了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
from Crypto.Util.number import getPrime, long_to_bytes as ltb, bytes_to_long as btl 
from gmpy2 import invert, powmod

DEBUG = True
flag = b'flag{AL3XEI_FAKE_FLAG}'

p,q = [getPrime(1024) for _ in "pq"]
D = getPrime(540)
phi = ( p - 1 ) * ( q - 1 )
n = p * q
d = phi - D
e = invert( d , phi )
m = btl(flag)
c = powmod( m, e, n )

print(f"n = { n }")
print(f"e = { e }")
print(f"c = { c }")

if DEBUG:
print(D > int(( 1 / 3 ) * ( n ** ( 1 / 4) ))) # True
print(D < int(n ** 0.292)) # True
print(d > int(( 1 / 3 ) * ( n ** ( 1 / 4) ))) # True
1
2
3
4
5
6
7
8
9
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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
from Crypto.Util.number import long_to_bytes
import itertools


def small_roots(f, bounds, m=1, d=None):
if not d:
d = f.degree()

R = f.base_ring()
N = R.cardinality()

f /= f.coefficients().pop(0)
f = f.change_ring(ZZ)

G = Sequence([], f.parent())
for i in range(m + 1):
base = N ^ (m - i) * f ^ i
for shifts in itertools.product(range(d), repeat=f.nvariables()):
g = base * prod(map(power, f.variables(), shifts))
G.append(g)

B, monomials = G.coefficients_monomials()
monomials = vector(monomials)

factors = [monomial(*bounds) for monomial in monomials]
for i, factor in enumerate(factors):
B.rescale_col(i, factor)

B = B.dense_matrix().LLL()

B = B.change_ring(QQ)
for i, factor in enumerate(factors):
B.rescale_col(i, 1 / factor)

H = Sequence([], f.parent().change_ring(QQ))
for h in filter(None, B * monomials):
H.append(h)
I = H.ideal()
if I.dimension() == -1:
H.pop()
elif I.dimension() == 0:
roots = []
for root in I.variety(ring=ZZ):
root = tuple(R(root[var]) for var in f.variables())
roots.append(root)
return roots

return []


n =
e =
c =


P = Zmod(ZZ(e))["k,s"]
k, s = P.gens()
f = 1 + k * (n - s)
rs = small_roots(f, (2**540, 2**1025), m=4, d=5)
print(rs)
k, s = map(int, rs[0])
phi = n - s
d = pow(e, -1, phi)
m = pow(c, d, n)
print(long_to_bytes(int(m)))
# b'flag{AL3XEI_FAKE_FLAG}'

1.4 含多个素数的 RSA

接下来的攻击将上述RSA攻击扩展到了含多个素数的形式。

定理3. 是含 个素数(大小相近)的RSA, 为私钥指数,且满足 。则公钥 已知的情况下,在多项式时间 内可以求得私钥。

证明过程与 Wiener 攻击近乎一致,不再阐述。

定理4. 对针对含多个素数的RSA小私钥指数的,基于小逆元攻击的方法,如果在 情况下成立,则在 情况下也成立。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
from Crypto.Util.number import getPrime, bytes_to_long

DEBUG = True
p,q,r = [getPrime(1024) for _ in "pqr"]
n = p*q*r
l = getPrime(490)
phi = (p - 1) * (q - 1) * (r - 1)
d = phi - l
e = int(pow(d, -1, phi))

flag = b'flag{AL3XEI_FAKE_FLAG}'
m = bytes_to_long(flag)
c = pow(m, e, n)

print(f"{n = }")
print(f"{e = }")
print(f"{c = }")

if DEBUG:
print("down: ", int((1/3)*(n**(1/6))).bit_length())
print("up: ", int(pow(n, 0.292)).bit_length())
print("k:", int((e*l+1)//phi).bit_length())
print("s:", int(-(- p*q-p*r-q*r+p+q+r-1)).bit_length(), (e*l+1)%phi)

1
2
3
4
5
6
7
8
9
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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
from Crypto.Util.number import long_to_bytes
import itertools


def small_roots(f, bounds, m=1, d=None):
if not d:
d = f.degree()

R = f.base_ring()
N = R.cardinality()

f /= f.coefficients().pop(0)
f = f.change_ring(ZZ)

G = Sequence([], f.parent())
for i in range(m + 1):
base = N ^ (m - i) * f ^ i
for shifts in itertools.product(range(d), repeat=f.nvariables()):
g = base * prod(map(power, f.variables(), shifts))
G.append(g)

B, monomials = G.coefficient_matrix()
monomials = vector(monomials)

factors = [monomial(*bounds) for monomial in monomials]
for i, factor in enumerate(factors):
B.rescale_col(i, factor)

B = B.dense_matrix().LLL()

B = B.change_ring(QQ)
for i, factor in enumerate(factors):
B.rescale_col(i, 1 / factor)

H = Sequence([], f.parent().change_ring(QQ))
for h in filter(None, B * monomials):
H.append(h)
I = H.ideal()
if I.dimension() == -1:
H.pop()
elif I.dimension() == 0:
roots = []
for root in I.variety(ring=ZZ):
root = tuple(R(root[var]) for var in f.variables())
roots.append(root)
return roots

return []


n =
e =
c =

P = Zmod(ZZ(e))["k,s"]
k, s = P.gens()
f = 1 + k * (n - s)
rs = small_roots(f, (2**490, 2**2050), m=4, d=5)
print(rs)
k, s = map(int, rs[0])
phi = n - s
d = pow(e, -1, phi)
m = pow(c, d, n)
print(long_to_bytes(int(m)))

1.5 总结

RSA私钥指数过大会导致与私钥指数过小一样不安全。特别的,对于RSA,私钥指数 都会带来不安全性。

0x02 二次生成器的密码分析

Link

为素数, 为模 有限域内的整数。二次生成器 (QCG) 是一个由等式关系 构成的伪随机数序列 。这篇论文展示了如果任意多个连续的 高位已知,就可以在多项式时间内还原初始变量 (即使在参数 未知的情况下),前提是初始变量 不在某些特殊值的小的子集里。

2.1 二次生成器

为素数, 为模 有限域内的整数。二次生成器 (QCG) 是一个由等式关系 构成的伪随机数序列 。等式中的 ​ 分别被称为乘子和偏移量。

在密码设置中,初始量 以及常量 应该被设为私钥,利用生成器生成流密码。显然,如果多个连续的 已知,求得 是很容易的。所以在这个设置中,我们只输出 的最高有效位 (msb) ,希望能让输出的序列更难预测。这篇论文展示的就是在这种情况下如何预测

假设序列 未知,但对于给定的 ,一些近似值 已知。以下分别讨论 公开和 公开, 不公开的两种情况下,如果 条件足够好, 就能在多项式内还原。

在开始前,还要定义一个参数 ,用来衡量 近似 的程度。这个参数通常假设为 。更确切地, - 近似,等价于

2.2 乘子与偏移量已知,预测二次生成器

定理1. 为素数, 为 整数且 。对任意 ,存在一个算法,当 与二次生成器产生的两个连续的值 -近似的 已知时,在多项式时间内返回 的值。

。由 ,可得 可得 因此由同余式 构成的格 含有解

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
from random import randint 
from Crypto.Util.number import *

Bits = 512
UnKnownBits = 146
flag = b'flag{AL3XEI_FAKE_FLAG}'

p = getPrime(Bits)
a, c = [randint(0, p) for _ in "ac"]

v_0 = bytes_to_long(flag)
v_1 = (a*v_0**2+c)%p
v_2 = (a*v_1**2+c)%p

print(f"a = {a}")
print(f"c = {c}")
print(f"p = {p}")
print(f"high_v1 = {v_1>>UnKnownBits}")
print(f"high_v2 = {v_2>>UnKnownBits}")
1
2
3
4
5
6
7
8
9
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
50
51
52
53
54
55
56
57
58
59
60
from Crypto.Util.number import long_to_bytes
import itertools


def small_roots(f, bounds, m=1, d=None):
if not d:
d = f.degree()

R = f.base_ring()
N = R.cardinality()

f /= f.coefficients().pop(0)
f = f.change_ring(ZZ)

G = Sequence([], f.parent())
for i in range(m + 1):
base = N ^ (m - i) * f ^ i
for shifts in itertools.product(range(d), repeat=f.nvariables()):
g = base * prod(map(power, f.variables(), shifts))
G.append(g)

B, monomials = G.coefficient_matrix()
monomials = vector(monomials)

factors = [monomial(*bounds) for monomial in monomials]
for i, factor in enumerate(factors):
B.rescale_col(i, factor)

B = B.dense_matrix().LLL()

B = B.change_ring(QQ)
for i, factor in enumerate(factors):
B.rescale_col(i, 1 / factor)

H = Sequence([], f.parent().change_ring(QQ))
for h in filter(None, B * monomials):
H.append(h)
I = H.ideal()
if I.dimension() == -1:
H.pop()
elif I.dimension() == 0:
roots = []
for root in I.variety(ring=ZZ):
root = tuple(R(root[var]) for var in f.variables())
roots.append(root)
return roots

return []
a =
c =
p =
high_v1 =
high_v2 =
PR = Zmod(ZZ(p))["l1, l2"]
l1, l2 = PR.gens()
f = a*(high_v1*(2^146)+l1)^2+c-(high_v2*(2^146)+l2)
low_v1 = ZZ(small_roots(f, (2^146, 2^146), m=3, d=4)[0][0])

v_0 = mod(((high_v1*(2^146)+low_v1)-c)*inverse_mod(a, p)%p, p).sqrt()
print(long_to_bytes(ZZ(v_0)))

2.3 乘子已知,偏移量未知,预测二次生成器

定理2. 为素数, 为 整数且 。对任意 ,存在一个算法,当 与二次生成器产生的三个连续的值 -近似的 已知时,在多项式时间内返回 ​ 的值。

,且 ,可得含已知量 和未知量 的方程: 向量 满足已知的一致性系数。为了使量标更平衡,将上式写作: 因此由同余式 构成的格 含有解

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
from random import randint 
from Crypto.Util.number import *

Bits = 256
UnKnownBits = 48
flag = b'flag{AL3XEI_FAKE_FLAG}'

p = getPrime(Bits)
a, c = [randint(0, p) for _ in "ac"]
v_0 = bytes_to_long(flag)
assert v_0<p
v_1 = (a*v_0**2+c)%p
v_2 = (a*v_1**2+c)%p
v_3 = (a*v_2**2+c)%p

print(f"a = {a}")
print(f"p = {p}")
print(f"high_v0 = {v_1>>UnKnownBits}")
print(f"high_v1 = {v_2>>UnKnownBits}")
print(f"high_v2 = {v_3>>UnKnownBits}")
1
2
3
4
5
6
7
8
9
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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
from Crypto.Util.number import long_to_bytes
import itertools


def small_roots(f, bounds, m=1, d=None):
if not d:
d = f.degree()

R = f.base_ring()
N = R.cardinality()

f /= f.coefficients().pop(0)
f = f.change_ring(ZZ)

G = Sequence([], f.parent())
for i in range(m + 1):
base = N ^ (m - i) * f ^ i
for shifts in itertools.product(range(d), repeat=f.nvariables()):
g = base * prod(map(power, f.variables(), shifts))
G.append(g)

B, monomials = G.coefficient_matrix()
monomials = vector(monomials)

factors = [monomial(*bounds) for monomial in monomials]
for i, factor in enumerate(factors):
B.rescale_col(i, factor)

B = B.dense_matrix().LLL()

B = B.change_ring(QQ)
for i, factor in enumerate(factors):
B.rescale_col(i, 1 / factor)

H = Sequence([], f.parent().change_ring(QQ))
for h in filter(None, B * monomials):
H.append(h)
I = H.ideal()
if I.dimension() == -1:
H.pop()
elif I.dimension() == 0:
roots = []
for root in I.variety(ring=ZZ):
root = tuple(R(root[var]) for var in f.variables())
roots.append(root)
return roots

return []

UnKnownBits = 48
a =
p =
high_v0 =
high_v1 =
high_v2 =

high_v0 = high_v0<<UnKnownBits
high_v1 = high_v1<<UnKnownBits
high_v2 = high_v2<<UnKnownBits

PR = Zmod(ZZ(p))["l0, l1, l2"]
l0, l1, l2 = PR.gens()
f =( a*high_v0^2-high_v1-a*high_v1^2+high_v2 ) + 2*a*high_v0*l0 - (1+2*a*high_v1)*l1 + l2 + a*(l0^2-l1^2)

ls = small_roots(f, (2^UnKnownBits, 2^UnKnownBits, 2^UnKnownBits), m=3, d=4)
v_0, v_1, v_2 = high_v0+ZZ(ls[0][0]), high_v1+ZZ(ls[0][1]), high_v2+ZZ(ls[0][2])
c = (v_1 - a*v_0^2)

sd = mod((v_0-c)*inverse_mod(a, p)%p, p).sqrt()

print(long_to_bytes(ZZ(sd)))

2.4 总结 & 尚未解决的问题

显然定理1的界 ,定理2的界 。因此是否能提高 ​ 的界值得讨论。

给出但乘子 未知的条件下也能用类似的过程预测二次生成器。

目前还不清楚当模数 未知时如何预测二次生成器。

0x03 在攻击变体 RSA 中找到具有新应用的多元多项式根的策略

Link

这篇论文展示了利用格基 Coppersmith 技术计算多元模多项式小整数根的策略。应用该策略,该论文得出在多项式时间内攻击两种 RSA 变体的方法。首先是 Qiao-Lam scheme, 其利用中国剩余定理在解密过程发挥作用。然后是共素数 RSA ,其素数生成的方法能抵抗 Wiener 攻击。

1.1 jochemsz_may 方法

论文开篇回顾了了 Coppersmith 以及 boneh Durfee 基于 Coppersmith 设计的针对 RSA 的攻击,并指出:找到一个小根的多项式 的分析严重依赖于 中出现的单项式,因此每个新的多项式都必须重新进行分析。这个工作无疑是十分繁杂的。2005年,Blomer 和 May 展示了如何寻找二元多项式小整数根的最佳界限。在本文中,我们提出了一种启发式策略,适用于所有多元多项式;无论是具有模数根还是整数根。

1.2 参数的设定

令多项式 有小根 的上界分别为 。根据论文提出的新策略,所有小根都能有效的在多项式时间 内恢复出来,前提是满足 同时,论文明确给出 ,而 的意思就是多项式的最大系数,所以 就是多项式对各 进行 代入后的最大系数。举个例子,如 ,则 ,显然最大系数在 ,即

1.3 对 共素 RSA 的攻击

定理1. 对任意 , 存在 使以下成立:令 比特 的 RSA 模数, 比特的素数,且 , 位数为 。令 , , 其中 , 则 可以在 的前提下,在多项式时间 时间内求出。

由上式可得: 联立两个式子: 。这个方程也可以写成 , 它的小根为 , 上界为 。同时也可以算出

论文给出了几个实现攻击需要的参数列表。

image-20240303165643981
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
from Crypto.Util.number import *

n = 4092
gamma = 0.4
delta = 0.1604
flag = b'AL3XEI_FAKE_FLAG'

g = getPrime(int(n*gamma))
while True:
p = getPrime(n//2)
if (p-1)%(2*g) == 0 :
break

while True:
q = getPrime(n//2)
if (q-1)%(2*g) == 0 :
break

a, b = (p-1)//(2*g), (q-1)//(2*g)
N = p*q
d = getPrime(int(n*delta))
e = inverse_mod(d, 2*g*a*b)

m = bytes_to_long(flag)
c = pow(m,e,n)
print(f'n = {n}')
print(f'e = {e}')
print(f'c = {c}')

1
2
3
4
5
6
7
8
9
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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
from sage.all import *
import itertools
from time import time
from Crypto.Util.number import long_to_bytes


# display matrix picture with 0 and X
# references: https://github.com/mimoo/RSA-and-LLL-attacks/blob/master/boneh_durfee.sage
def matrix_overview(BB):
for ii in range(BB.dimensions()[0]):
a = ('%03d ' % ii)
for jj in range(BB.dimensions()[1]):
a += '0' if BB[ii,jj] == 0 else 'X'
if BB.dimensions()[0] < 60:
a += ' '
print (a)

def sort_monomials(monomials):
x, y, z = monomials[0].parent().gens()
Mx = []
My = []
Mz = []
degx = max([monomial.degree(x) for monomial in monomials])
degy = max([monomial.degree(y) for monomial in monomials])
degz = max([monomial.degree(z) for monomial in monomials])
for i in range(degx + 1):
for j in range(degy + 1):
for k in range(degz + 1):
if k+j > i:
break
mono = x^i * y^j * z^k
if mono in monomials:
Mx += [mono]
for j in range(degy + 1):
for k in range(degz + 1):
for i in range(degx + 1):
if k > j:
break
mono = x^i * y^j * z^k
if mono in monomials and mono not in Mx:
My += [mono]
for k in range(degz + 1):
for j in range(degy + 1):
for i in range(degx + 1):
mono = x^i * y^j * z^k
if mono in monomials and mono not in (Mx+My):
Mz += [mono]
return Mx + My + Mz


def jochemsz_may_trivariate(pol, XX, YY, ZZ, WW, tau, mm):
'''
Implementation of Finding roots of trivariate polynomial [1].
Thanks @Bono_iPad
References:
[1] Ellen Jochemsz and Alexander May. "A Strategy for Finding Roots of Multivariate Polynomials with New Applications in Attacking RSA Variants"
'''
tt = floor(mm * tau)
cond = XX^(7 + 9*tau + 3*tau^2) * (YY*ZZ)^(5+9/2*tau) < WW^(3 + 3*tau)
print ('[+] Bound check: X^{7+9tau+3tau^2} * (YZ)^{5+9/2tau} < W^{3+3tau}:', )
if cond:
print( 'OK')
else:
print ('NG')

# Polynomial constant coefficient (a_0) must be 1
# XXX: can a_0 be zero?
f_ = pol
a0 = f_.constant_coefficient()

while gcd(a0, XX) != 1:
XX += 1
while gcd(a0, YY) != 1:
YY += 1
while gcd(a0, ZZ) != 1:
ZZ += 1
while gcd(a0, WW) != 1:
WW += 1

RR = WW * XX^(2*(mm-1)+tt) * (YY*ZZ)^(mm-1)

if a0 != 0:
F = Zmod(RR)
PK = PolynomialRing(F, 'xs, ys, zs')
f_ = PR(PK(f_) * F(a0)^-1)

# Construct set `S` (cf.[1] p.8)
S = set()
for i2, i3 in itertools.product(range(0, mm), repeat=2):
for i1 in range(0, 2*(mm-1) - (i2 + i3) + tt + 1):
S.add(x^i1 * y^i2 * z^i3)
m_S = []
for k in range(mm):
for j in range(mm):
for i in range(2*(mm-1) - (i2 + i3) + tt + 1):
m_S += [x^i*y^j*z^k]
S = m_S

# Construct set `M` (cf.[1] p.8)
M = set()
for i2, i3 in itertools.product(range(0, mm + 1), repeat=2):
for i1 in range(0, 2*mm - (i2 + i3) + tt + 1):
M.add(x^i1 * y^i2 * z^i3)
M_S = list(M - set(S))

m_M_S = []
deg_x = max([mono.degree(x) for mono in M_S])
deg_y = max([mono.degree(y) for mono in M_S])
deg_z = max([mono.degree(z) for mono in M_S])
for k in range(deg_z + 1):
for j in range(deg_y + 1):
for i in range(deg_x + 1):
mono = x^i*y^j*z^k
if mono in M_S:
m_M_S += [mono]
M_S = m_M_S

# Construct polynomial `g`, `g'` for basis of lattice
g = []
g_ = []
M_S = sort_monomials(M_S)
S = sort_monomials(S)
for monomial in S:
i1 = monomial.degree(x)
i2 = monomial.degree(y)
i3 = monomial.degree(z)
g += [monomial * f_ * XX^(2*(mm-1)+tt-i1) * YY^(mm-1-i2) * ZZ^(mm-1-i3)]

for monomial in M_S:
g_ += [monomial * RR]

# Construct Lattice from `g`, `g'`
monomials_G = []
monomials = []
G = g + g_
deg_x = deg_y = deg_z = 0
for g_poly in G:
monomials_G += g_poly.monomials()
deg_x = max(deg_x, g_poly.degree(x))
deg_y = max(deg_y, g_poly.degree(y))
deg_z = max(deg_z, g_poly.degree(z))
monomials_G = sorted(set(monomials_G))

for k in range(deg_z + 1):
for j in range(deg_y + 1):
for i in range(deg_x + 1):
mono = x^i*y^j*z^k
if mono in monomials_G:
monomials += [x^i*y^j*z^k]
assert len(monomials) == len(G)
monomials = sort_monomials(monomials)
dims = len(monomials)
M = Matrix(IntegerRing(), dims)
for i in range(dims):
M[i, 0] = G[i](0, 0, 0)
for j in range(dims):
if monomials[j] in G[i].monomials():
M[i, j] = G[i].monomial_coefficient(monomials[j]) * monomials[j](XX, YY, ZZ)
matrix_overview(M)
print ()
print ('=' * 128)
print ()

# LLL

start = time()
B = M.LLL()
matrix_overview(B)
print('[+] LLL cost %d sec' % (time() - start))

# Re-construct polynomial `H_i` from Reduced-lattice
H = [(i, 0) for i in range(dims)]
H = dict(H)
for i in range(dims):
for j in range(dims):
H[i] += PR((monomials[j] * B[i, j]) / monomials[j](XX, YY, ZZ))

PX = PolynomialRing(IntegerRing(), 'xn')
xn = PX.gen()
PY = PolynomialRing(IntegerRing(), 'yn')
yn = PX.gen()
PZ = PolynomialRing(IntegerRing(), 'zn')
zn = PX.gen()

# Solve for `x`
r1 = H[2].resultant(pol, y)
r2 = H[3].resultant(pol, y)
r3 = r1.resultant(r2, z)
x_roots = map(lambda t: t[0], r3.subs(x=xn).roots())
x_roots = list(x_roots)
assert len(x_roots) > 0
if len(x_roots) == 1 and x_roots[0] == 0:
print ('[-] Can\'t find non-trivial solution for `x`')
return 0, 0, 0
x_root = x_roots[0]
print ('[+] Found x0 = %d' % x_root)

# Solve for `z`
r1_ = r1.subs(x=x_root)
r2_ = r2.subs(x=x_root)
z_roots = map(lambda t: t[0], gcd(r1_, r2_).subs(z=zn).roots())
z_roots = list(z_roots)
assert len(z_roots) > 0
if len(z_roots) == 1 and z_roots[0] == 0:
print ('[-] Can\'t find non-trivial solution for `z`')
return 0, 0, 0
z_root = z_roots[0]
print ('[+] Found z0 = %d' % z_root)

# Solve for `y`
y_roots = map(lambda t: t[0], H[2].subs(x=x_root, z=z_root).subs(y=yn).roots())
y_roots = list(y_roots)
assert len(y_roots) > 0
if len(y_roots) == 1 and y_roots[0] == 0:
print ('[-] Can\'t find non-trivial solution for `y`')
return 0, 0, 0
y_root = y_roots[0]
print ('[+] Found y0 = %d' % y_root)
assert pol(x_root, y_root, z_root) == 0
return (x_root, y_root, z_root)

n =
e =
c =

gamma = 0.4
delta = 0.1604

PR.<x, y, z> = PolynomialRing(ZZ)

# Maximal value of solution `x0`, `y0`, `z0`
XX = floor(n^delta)
YY = floor(n^(delta + 0.5 - gamma))
ZZ = YY

# Norm of polynomial as vector representation
WW = floor(n^(2 + 2*delta - 2*gamma))

# Some Non-negative real ([SAN10] 3.1 (11))
tau = (1/2 + gamma - 4*delta) / (2*delta)

# Powering degree
mm = 1

# Target polynomial
pol = e^2 * x^2 + e*x*(y+z-2)-(y+z-1)-(n-1)*y*z
x0, y0, z0 = jochemsz_may_trivariate(pol, XX, YY, ZZ, WW, tau, mm)

d = x0
m = pow(c,d,n)
print(long_to_bytes(int(m)))

0X04 带有小的未知乘子的隐藏数问题:MEGA 的六次查询密码分析以及其他应用

Link

安全研究员最近提出了针对云存储提供商 MEGA 的一种攻击。该攻击通过伪装恶意服务器,在与客户端进行 512 次登录交互后会得到 RSA 私钥。这篇论文展示了由 MEGA 协议漏洞获取更多隐私的攻击攻击,只需与客户端进行 6 次登录交互即可恢复私钥。该联合攻击涉及多种密码分析技术。特别的,这篇论文还提出了一种隐藏数问题变体的解法,该变体涉及小的未知乘子。

4.1 HNP-SUM 简介

论文的一项创新工作是解决了带有小的未知乘子的隐藏数问题 (以下简称为 HNP-SUM) 。

定义1. (HNP-SUM) 对于给定的整数 ,存在整数 满足

如何恢复 签名的值 (ti 互素)。

定理1. 对 HNP-SUM 出现的 以及随机生成的 ,当 时,存在算法使HNP-SUM 可在多项式内求解。

4.2 求解 HNP-SUM

对于 的情况,给定 满足 经过变换得到 由于 的界固定,对于 存在个小的解 。通过构造格 定理2. 对于 HNP-SUM 问题的 情况下,若 ​ 成立,可在多项式时间内求解。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from Crypto.Util.number import *
from lbc_toolkit import hnp

m = b'AL3XEI_FAKE_FLAG'
N, E, T = random_prime(2^722), 2^180, 2^180
print(T^3*E<N)

x = bytes_to_long(m)
_T = [randrange(1, T) for _ in "01"]
_E = [randrange(0, E) for _ in "01"]
A = [(t * x + e) % N for t, e in zip(_T, _E)]

print(f'N = {N}')
print(f'_T = {_T}')
print(f'A = {A}')
print(f'E = {E}')

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from lbc_toolkit import hnp
from Crypto.Util.number import *

N =
_T =
A =
E =
sol = hnp(N, _T, A, E, verbose=True)
print(long_to_bytes(sol))

# [hnp] Lattice dimensions: (4, 4)
# [hnp] Lattice reduction took 0.005s
# b'AL3XEI_FAKE_FLAG'

对于 的情况也可以做拓展。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from Crypto.Util.number import *
from lbc_toolkit import hnp

m = b'AL3XEI_FAKE_FLAG'
N, E, T = random_prime(2^360), 2^50, 2^50
print(T^6*E<N)

x = bytes_to_long(m)
_T = [randrange(1, T) for _ in range(5)]
_E = [randrange(0, E) for _ in range(5)]
A = [(t * x + e) % N for t, e in zip(_T, _E)]

print(f'N = {N}')
print(f'_T = {_T}')
print(f'A = {A}')
print(f'E = {E}')

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from lbc_toolkit import hnp
from Crypto.Util.number import *

N =
_T =
A =
E =
sol = hnp(N, _T, A, E, verbose=True)
print(long_to_bytes(sol))

# [hnp] Lattice dimensions: (7, 7)
# [hnp] Lattice reduction took 0.013s
# b'AL3XEI_FAKE_FLAG'

4.3 应用:对 MEGA 的攻击

MEGA 工作 (以及实施对 MEGA 攻击) 的环境中,服务器持有客户端 RSA 私钥的密文副本,加密方式是 AES-ECB mode,密钥由用户密码派生生成。

在 MEGA 的登录协议中,服务器向客户端发送了一个使用 AES-ECB mode 加密的 RSA 私钥。 客户端解密 RSA 私钥,使用此 RSA 私钥解密 session ID 得到 RSA 公钥 ,并发送给服务器一个应答值。RSA 私钥包含

客户端返回服务器的值是

令 RSA 的公钥为 的因数为 。公钥指数与私钥指数分别为 。公钥由客户端定义,在网络客户端上 , 而在 SDK 上 。私钥的编码为

1
l(q) ∥ q ∥ l(p) ∥ p ∥ l(d) ∥ d ∥ l(u) ∥ u ∥ P
  • l(x) 将值 x 的比特长度编码为一个 2 字节的整数
  • 所有整数以大端格式存储
  • P长8字节,作为填充,具体值攻击者未知
  • q 是 1024 位,故 l(q) = 0x400,且由于明文大小已知,它在明文中的偏移量也可预测
  • d 包含了 d, dp, dq
  • 1024 位的 u 值跨越了 9 个 AES 明文块,其中第一个和最后一个包含长度和填充字段

私钥加密后 656 字节/ 41 个 AES 块,使用 AES-ECB 加密后

1
ct1 ∥ ct2 ∥...∥ ct41 = EAES(pt1) ∥ EAES(pt2) ∥...∥ EAES(pt41)。

实质上,客户端返回服务器的值是对 进行了一次 RSA-CRT 的解密。

1
2
3
4
5
6
m_p = c^(d_p) mod p
m_q = c^(d_q) mod q
t = (m_p - m_q) mod p
h = (t * u) mod p
m' = h * q + m_q
SID = m'[2:44] # 去掉 padding 校验位

0x05 基于网络的入侵检测数据集调查

5.0 摘要

标记的数据集对于训练和评估基于异常的网络入侵检测系统是必要的。这项工作对基于网络的入侵检测的数据集进行了重点文献调查,并详细描述了基于数据包和流量的网络数据。该文确定了15种不同的属性,以评估个别数据集对特定评估方案的适用性。这些属性涵盖了广泛的标准,并被归为五类,如数据量或提供结构化搜索的记录环境。基于这些属性,对现有数据集进行了全面的概述。这个概述还强调了每个数据集的特殊性。此外,这项工作还简要介绍了基于网络的数据的其他来源,如流量生成器和数据存储库。最后,我们讨论了我们的观察,并为使用和创建基于网络的数据集提供一些建议。

5.1 引言

IT安全是一个重要的问题,人们在入侵和内部威胁检测的研究方面花费了很多精力。在处理安全相关数据(Chandola等人,2006;Garcia等人,2014;Rehák等人,2008;Ring等人,2017)、检测僵尸网络(Beigi等人。2014;Stevanovic和Pedersen,2015;Wang和Pascha- lidis,2017;Yin等人,2018),端口扫描(Jung等人,2004;Ring等人,2018),暴力攻击(Hellemons等人,2012;Javed和Paxson,2013;Najafabadi等人,2014;Sperotto等人,2009)等等已经发表了很多工作。所有这些工作的共同点是,他们重新要求有代表性的基于网络的数据集。此外,基准数据集是评估和比较不同网络入侵检测系统(NIDS)质量的良好基础。给定一个标记的数据集,其中每个数据点被分配到正常或攻击类别,被检测到的攻击数量或错误警报的数量可以作为评价标准。不幸的是,周围没有太多具有代表性的数据集。根据Sommer和Pax-son(2010)的说法,缺乏有代表性的公开数据集是基于异常的入侵检测的最大挑战之一。Małowidzki等人(2015)和Haider等人(2017)也有类似的说法。然而,社区正在努力解决这个问题,因为在过去的几年里,已经发布了几个入侵检测数据集。特别是,澳大利亚网络安全中心发布了UNSW-NB15 ( Moustafa and Slay, 2015) 数据集,科堡大学发布了CIDDS-001 ( Ring et al., 2017c) 数据集,或者新不伦瑞克大学发布了CICIDS 2017 ( Sharafaldin et al., 2018) 数据集。未来可以预期会有更多的数据集。然而,现有的数据集没有整体索引,很难跟踪最新的发展。

这项工作对现有基于网络的入侵检测数据集进行了文献调查。首先,对基础数据进行了更详细的调查。基于网络的数据以基于数据包或基于数据流的格式出现。基于流的数据只包含关于网络连接的元信息,而基于包的数据还包含有效载荷。然后,本文分析并分组了不同的数据集属性,这些属性在文献中经常被用来评估基于网络的数据集的质量。本调查的主要贡献是对基于网络的数据集进行了详尽的文献综述,并分析了哪些数据集符合哪些数据集属性。本文重点关注数据集内的攻击场景,并强调数据集之间的关系。此外,我们还简要介绍了流量生成器和数据存储库,作为典型数据集以外的网络流量来源,并提供了一些意见和建议。作为一个主要的好处,这项调查建立了一个数据集属性的集合,作为比较现有数据集和确定合适的数据集的基础,鉴于具体的评估方案。此外,我们创建了一个网站1,其中提到了所有提到的数据集和数据存储库,我们打算更新这个网站(https://www.informatik.uni-wuerzburg.de/datascience/datasets/nids-ds,感觉数据不是很全啊)。

本文的其余部分组织如下。下一节讨论了相关工作。第三节更详细地分析了基于数据包和流量的网络数据。第4节讨论了典型的数据集属性,这些属性在文献中经常被用来评估入侵检测数据集的质量。第5节概述了现有的数据集,并根据第4节确定的属性检查每个数据集。第6节简要介绍了基于网络数据的其他来源。第7节讨论了观察结果和建议,然后本文以总结的形式结束。

5.2 相关工作

本节回顾了关于基于网络的入侵检测数据集的相关工作。应该注意的是,本文没有考虑基于主机的入侵检测数据集,如ADFA ( Creech and Hu, 2013 )。有兴趣的读者可以在Glass Vanderlan等人(2018)中找到关于基于主机的入侵检测数据的详细信息。

Małowidzki等人(2015)讨论了缺失的数据集是入侵检测的一个重要问题,设定了对好的数据集的要求,并列出了可用的数据集。Koch等人(2014)提供了另一个入侵检测数据集的概述,分析了13个数据源,并根据8个数据集的属性对它们进行了评估。Nehinbe(2011)对IDS和入侵防御系统(IPS)的数据集进行了严格的评估。作者检查了来自不同来源的7个数据集(如DARPA数据集和DEFCON数据集),强调了它们的局限性,并提出了创建更真实的数据集的方法。由于许多数据集是在过去的四年里发表的,我们继续以前的工作(Koch等人,2014;Małowidzki等人,2015;Nehinbe,2011)从2011年到2015年,但提供了一个比前辈更多的最新和更详细的概述。

虽然许多数据集论文(例如CIDDS002(Ring等人,2017)、ISCX(Shiravi等人,2012)或UGR'16(MaciáFernández等人,2018))只是简要介绍了一些入侵检测数据集,但Sharafaldin等人(2018)提供了一个更详尽的回顾。他们的主要贡献是一个生成入侵检测数据集的新框架。Sharafaldin等人还分析了11个可用的入侵检测数据集,并根据11个数据集属性对其进行了评估。与早期的数据集论文相比,我们的工作重点是对现有的基于网络的数据集提供一个全新的概述,而不是贡献一个额外的数据集。

最近的其他论文也涉及到基于网络的数据集,但主要关注点不同。Bhuyan等人(2014)对网络异常检测进行了全面回顾。作者描述了九个现有的数据集,并分析了现有异常检测方法所使用的数据集。同样,Nisioti等人(2018)专注于入侵检测的无监督方法,并简要地提到了12个现有的基于网络的数据集。Yavanoglu和Aydos(2017)分析和比较了最常用的入侵检测数据集。然而,他们的评论只包含7个数据集,包括其他数据集,如HTTP CSIC 2010(Giménez等人,2010)。总而言之,这些作品往往有不同的研究目标,而且只略微涉及到基于网络的数据集。

5.3数据

通常情况下,网络流量是以基于数据包或基于流量的格式进行捕获。在数据包层面上捕获网络流量,通常是通过在网络设备上镜像端口来完成。基于数据包的数据包含完整的有效载荷信息。基于数据流的数据是更聚合的,通常只包含网络连接的元数据。Wheelus等人通过一个说明性的比较强调了这种区别。"捕获的数据包检查和网络流量之间的区别的一个很好的例子是,通过徒步穿越森林来观察森林,而不是乘坐热气球飞越森林"(Wheelus等人,2014)(挺形象的,有没有内部载荷就是这个区别)。在这项工作中,引入了第三个类别(其他数据)。其他类别没有标准的格式,每个数据集都不一样。

3.1基于包的数据

img

基于数据包的数据通常以pcap格式捕获,包含有效载荷。可用的元数据取决于使用的网络和传输协议。有许多不同的协议,其中最重要的是TCP、UDP、ICMP和IP。图1说明了不同的报头。TCP是一个可靠的传输协议,包括元数据,如序列号、确认号、TCP标志或校验值。UDP是一个无连接的传输协议,它的报头比TCP小,只包含四个字,即源端口、目的端口、长度和校验值。与TCP和UDP相比,ICMP是一个支持性协议,包含状态信息,因此更小。通常,在传输协议的头旁边还有一个IP头。IP头提供了源和目的IP地址等信息,也显示在图1中。

3.2基于流的数据

img

基于流量的网络数据是一种更浓缩的格式,主要包含网络连接的元信息。基于流量的数据将在一个时间窗口内共享某些属性的所有数据包汇总为一个流量,通常不包括任何有效载荷。默认的五元组定义,即源IP地址、源端口、目的IP地址、目的端口和传输协议(Claise,2008),是基于流量的数据中广泛使用的属性匹配标准。流量可以以单向或双向的格式出现。单向格式将所有从主机A到主机B的、具有上述属性的数据包聚合成一个流。所有从主机B到主机A的数据包被聚合成另一个单向流。相比之下,双向流总结了主机A和B之间的所有数据包,无论方向如何。典型的基于流的格式是NetFlow(Claise,2004),IP FIX(Claise,2008),sFlow(Phaal,2004)和OpenFlow(McKeown等人,2008)。表1给出了基于流量的网络流量的典型属性的概述。根据具体的流量格式和流量导出器,可以提取额外的属性,如每秒的字节数、每包的字节数、第一个包的TCP标志,甚至有效载荷的计算熵。此外,有可能通过nfdump 2或YAF等工具将基于数据包的数据转换为基于流量的数据(但反之亦然)。3 对流量输出器之间的差异感兴趣的读者可以在Haddadi和Zincir Heywood(2016)中找到更多细节,以及对不同流量输出器如何影响僵尸网络的分析。

3.3其他数据

这一类包括所有既不是纯粹的基于数据包也不是基于流量的数据集。这一类的例子可能是基于流量的数据集,这些数据集被基于数据包的数据或基于主机的日志文件的额外信息所丰富。KDD CUP 1999(Stolfo,2018)数据集是这一类别的著名代表。每个数据点都有基于网络的属性,如传输的源字节数或TCP标志,但也有基于主机的属性,如失败的登录次数。因此,这一类的每个数据集都有自己的属性集。由于每个数据集都必须单独进行分析,我们不对可用的属性做任何一般性的陈述。

5.4 数据属性

为了能够并排比较不同的入侵检测数据集,并帮助研究人员找到适合其特定评估场景的数据集,有必要定义共同的属性作为评估基础。因此,我们探讨文献中用于评估入侵检测数据集的典型数据集属性。一般概念FAIR(Wilkinson等人,2016)定义了学术数据应满足的四个原则,即可查找性、可访问性、互操作性和可重复使用性。在赞同这一总体概念的同时,这项工作使用更详细的数据集属性来提供基于网络的入侵检测数据集的重点比较。一般来说,不同的数据集强调不同的数据集属性。例如,UGR'16数据集(MaciáFernández等人,2018年)强调了较长的记录时间,以捕获周期性效应,而ISCX数据集(Shiravi等人,2012年)则侧重于准确的标签。由于我们的目标是研究基于网络的入侵检测数据集的更普遍的属性,我们试图统一和概括文献中使用的属性,而不是采用所有的这些属性。例如,一些方法评估特定类型的攻击,如DoS(拒绝服务)或浏览器注入的存在。某些攻击类型的存在可能是评估这些特定攻击类型的检测方法的相关属性,但对其他方法来说是没有意义的。因此,我们使用一般的属性来描述恶意网络流量的存在(见表3)。第5节提供了关于数据集中不同攻击类型的更多细节,以及对其他特定属性的讨论。

我们没有像Haider等人(2017)或Sharafaldin等人(2018)那样制定一个评价分数,因为我们不想判断不同数据集属性的重要性。在我们看来,某些属性的重要性取决于具体的评价场景,不应该在调查中进行普遍评判。相反,应该让读者能够找到适合他们需要的数据集。因此,我们将下面讨论的数据集属性分为五类,以支持系统的搜索。图2总结了所有的数据集属性和它们的数值范围。

img

4.1一般信息

以下四个属性反映了数据集的一般信息,即创建年份、可用性、正常和恶意网络流量的存在。

4.1.1. 创建年份

由于网络流量受到概念漂移的影响,而且每天都有新的攻击场景出现,因此入侵检测数据集的年份发挥着重要作用。该属性描述了创建年份。数据集的基础网络流量被捕获的年份比其发布的年份更适合于及时性。

4.1.2. 公开可用性

入侵检测数据集应公开提供,作为比较不同入侵检测方法的基础。此外,数据集的质量只有在公开可用的情况下才能被第三方检查。表3包含了这一属性的三种不同特征:是、O.R.(应要求)和否。应要求是指在向作者或负责人发送消息后,将允许访问。

4.1.3. 正常用户行为

此属性表示数据集中是否有正常的用户行为,其值为yes或no。值是表示数据集内有正常的用户行为,但它不对攻击的存在作任何陈述。一般来说,IDS的质量主要由其攻击检测率和误报率决定。因此,正常用户行为的存在对于评估一个IDS是必不可少的。然而,没有正常的用户行为并不意味着数据集不能使用,而是表明它必须与其他数据集或现实世界的网络流量合并。这样的合并步骤通常被称为叠加或加盐(Aviv and Haeberlen, 2011; Celik et al., 2011)。

4.1.4. 攻击流量

IDS数据集应该包括各种攻击场景。该属性表明数据集内存在恶意网络流量,如果数据集至少包含一次攻击,则其值为 "是"。表4提供了关于具体攻击类型的额外信息。

4.2数据的性质

这个类别的属性描述了数据集的格式和元信息的存在。

4.2.1. 元数据

对第三方来说,基于数据包和流量的网络流量的内容解释是困难的。因此,数据集应该伴随着元数据,以提供有关网络结构、IP地址、攻击场景等的补充信息。这一属性表明存在额外的元数据。

4.2.2. 格式

网络入侵检测数据集以不同的格式出现。我们大致将其分为三种格式(见第3节)。(1) 基于数据包的网络流量(例如,pcap)包含带有有效载荷的网络流量。(2) 基于流的网络流量(如NetFlow)只包含关于网络连接的元信息。(3) 其他类型的数据集可能包含。(3) 其他类型的数据集可能包含,例如,基于流量的跟踪,以及来自基于数据包的附加属性,甚至来自基于主机的日志文件。

4.2.3. 匿名性 (或加密)

通常,入侵检测数据集可能由于隐私原因而不被公布,或者只以匿名的形式提供。此属性表明数据是否被匿名化,以及哪些属性受到影响。表3中的值no表示没有进行匿名处理。值是(IPs)意味着IP地址被匿名化或从数据集中重新移出。同样地,是(有效载荷)表示有效载荷信息被匿名化或从基于数据包的网络流量中删除。

4.3数据体量

这一类的属性从数量和持续时间方面来描述数据集的特点。

4.3.1. 数量 count

属性count描述了一个数据集的大小,可以是包含的数据包/流量/点的数量,也可以是以Gigabyte(GB)为单位的物理大小。

4.3.2. 持续时间 Duration

数据集应该涵盖很长一段时间的网络流量,以捕捉周期性的影响(例如,白天与晚上或工作日与周末)(MaciáFernández等人,2018)。属性Duration提供了每个数据集的记录时间。

4.4记录环境

这一类的属性描述了捕获数据集的网络环境和条件。

4.4.1. 流量的种类

流量种类属性描述了网络流量的三种可能来源:真实、模拟或合成。真实意味着真实的网络流量是在生产性网络环境中捕获的。仿真的意思是,真实的网络流量是在测试平台或仿真网络环境中捕获的。合成指的是网络流量是合成的(例如,通过流量生成器),而不是由真实(或虚拟)的网络设备捕获的。

4.4.2. 网络类型

中小型公司的网络环境与互联网服务提供商(ISP)有着本质的区别。因此,不同的环境需要不同的安全系统,评估数据集应适应特定的环境。这一属性描述了创建各自数据集的基础网络环境。

4.4.3. 完整的网络

该属性采用Sharafaldin等人(2018)的观点,表示数据集是否包含有多个主机、路由器等网络环境的完整网络流量。如果数据集只包含来自单一主机(如蜜罐)的网络流量,或只包含网络流量中的某些协议(如只包含SSH流量),则该值被设置为否。

4.5评估

以下属性与使用基于网络的数据集的入侵检测方法的评估有关。更确切地说,这些属性表示预定义子集的可用性、数据集的平衡性和标签的存在。

4.5.1. 预定义分集

有时很难比较不同IDS的质量,即使它们是在同一数据集上评估的。在这种情况下,必须澄清是否使用了相同的子集进行训练和评估。如果一个数据集带有用于训练和评估的预定义子集,这个属性就提供了信息。

4.5.2. 平衡性

通常,机器学习和数据挖掘方法被用于基于异常的入侵检测。在这类方法(如决策树分类器)的训练阶段,数据集在其类别标签方面应该是平衡的。因此,数据集应包含每个类别(正常和攻击)的相同数量的数据点。然而,现实世界的网络工作流量是不平衡的,与攻击流量相比,它包含更多的用户行为,也没有恶意。这一属性表明数据集在其类别标签方面是否平衡。在使用数据挖掘算法之前,应该通过适当的预评估来平衡不平衡的数据集。He和Garcia(2009)对从不平衡的数据中学习进行了很好的概述。

4.5.3. 标签化

标记的数据集对于训练有监督的方法以及评估有监督和无监督的入侵检测方法是必要的。这一属性表示数据集是否被标记。如果至少有两个类别,即恶意和攻击,这个属性就被设置为是。这个属性的可能值是:yes, yes with BG. (yes with background), yes (IDS), indirect, 和 no 。Yes with background意味着有一个第三类背景,属于该类背景的数据包、流量或数据点可能是正常的或处于粘性状态。yes (IDS),意味着某种入侵检测系统被用来创建数据集的标签,数据集的一些标签可能是错误的,因为入侵检测系统可能不存在缺陷。indirect意味着数据集没有明确的标签,但可以通过额外的日志文件自行创建标签。

5.5 数据集

我们认为,在寻找适当的基于网络的数据集时,数据集的属性 "标签 "和 "格式 "是最具决定性的属性。入侵检测方法(监督或无监督)决定了是否需要标签以及需要哪种数据(数据包、流量或其他)。因此,表2提供了所有基于网络的数据集在这两个属性方面的分类。表3对基于网络的入侵检测数据集与第4节的数据集属性进行了更详细的概述。在寻找基于网络的数据集时,特定攻击场景的存在是一个重要方面。因此,表3指出了攻击流量的存在,而表4提供了数据集内特定攻击的细节。关于数据集的论文描述了不同抽象层次的攻击。例如,Vasudevan等人(2011年)在他们的数据集(SSENET2011)中对攻击流量的描述如下。"Nmap、Nessus、Angry IP扫描器、Port Scanner、Metaploit、Backtrack OS、LOIC等,是参与者用来发动攻击的一些工具。与此相反,Ring等人在他们的报告中明确指出了执行端口扫描的数量和不同类型。 在他们的CIDDS002数据集中,指定了不同类型的执行端口扫描(Ring等人,2017)。因此,在表4中,攻击描述的抽象水平可能有所不同。对所有攻击类型的详细描述超出了这项工作的范围。相反,我们请感兴趣的读者参考开放性论文“From Intrusion Detection to an In trusion Response System: Fundamentals, Requirements, and Future Directions”,作者Anwar等人(2017)

此外,一些数据集是其他数据集的修改或组合。图3显示了几个著名的数据集之间的相互关系。

img
img

5.1按字母顺序排列的基于网络的数据集

AWID(Kolias等人,2016)。AWID是一个公开可用的数据集,主要是针对802.11网络。它的创造者使用了一个小型的网络环境(11个客户),并以基于数据包的形式捕获了WLAN流量。在一个小时内,捕获了3700万个数据包。从每个数据包中提取了156个属性。恶意网络流量是通过对802.11网络执行16种特定攻击而产生的。AWID被标记并分成训练和测试子集。

Booters(Santanna等人,2015)。Booters是由犯罪分子提供的分布式服务(DDoS)攻击,作为一种服务。Santanna等人(2015年)发布了一个数据集,其中包括9个不同的Booters攻击的痕迹,这些攻击是针对他们网络环境中的一个空路IP地址执行的。由此产生的数据集被记录在基于数据包的矩阵中,包括超过250GB的网络流量。每个数据包都没有标记,但不同的Booters攻击被分割成不同的文件。该数据集是公开的,但由于隐私原因,Booters的名字是匿名的。

Botnet(Beigi等人,2014)。Botnet数据集是现有数据集的组合,是公开可用的。Botnet的创建者使用(Aviv和Haeberlen,2011)的叠加方法,将ISOT(Saad等人,2011)、ISCX 2012(Shiravi等人,2012)和CTU13(Garcia等人,2014)的数据集(部分)结合起来。由此产生的数据集包含各种僵尸网络和正常用户行为。僵尸网络数据集被分为5.3GB的训练子集和8.5GB的测试子集,都是基于数据包的格式。

CICDoS ( Jazi et al., 2017 )。CICDoS是加拿大网络安全研究所的数据集,是公开可用的。作者的意图是创建一个带有应用层DoS攻击的入侵检测数据集。因此,研究人员在应用层执行了8种不同的DoS攻击。正常的用户行为是通过将产生的痕迹与ISCX 2012(Shiravi等人,2012)数据集的无攻击流量相结合而产生的。由此产生的数据集以基于数据包的格式提供,包含24小时的网络流量。

CICIDS2017(Sharafaldin等人,2018)。CICIDS 2017是在一个模拟环境中创建的,为期5天,包含基于数据包和基于双ctional流量格式的网络流量。对于每个流量,作者提取了80多个属性,并提供关于IP地址和攻击的额外元数据。正常的用户行为是通过脚本执行的。该数据集包含广泛的攻击类型,如SSH蛮力、心脏出血、僵尸网络、DoS、DDoS、网络和渗透攻击。CICIDS 2017是公开可用的。

CIDDS001 ( Ring et al., 2017c )。CIDDS001数据集是2017年在一个模拟的小企业环境中捕获的,包含了四周的基于流量的单向网络工作流量,并附有一份详细的技术报告,其中包含了额外的信息。作为特殊功能,该数据集包含了一个在互联网上被攻击的外部服务器。与蜜罐不同的是,这个服务器也经常被来自模拟环境的客户使用。正常和恶意的用户行为是通过GitHub上公开的python脚本执行的。这些脚本允许不断产生新的数据集,并可被其他研究使用。CIDDS001数据集是公开的,包含SSH暴力攻击、DoS和端口扫描攻击,以及从野外捕获的一些攻击。

CIDDS002 ( Ring et al., 2017 )。CIDDS002是一个端口扫描数据集,它是基于CIDDS001的脚本创建的。该数据集包含在一个模拟的小企业环境中的两周基于流量的网络工作流量。CIDDS002包含正常的用户行为以及广泛的不同的端口扫描攻击。一份技术报告提供了关于该数据集的额外元信息,其中外部IP地址被匿名化。该数据集是公开可用的。

CDX(Sangster等人,2009)。Sangster等人(2009)提出了一个概念,即从网络战争竞赛中创建基于网络的数据集,并全面讨论了这种方法的优势和劣势。CDX数据集包含了2009年一个为期四天的网络战竞赛的网络流量。这些流量是以数据包为基础记录的,可以公开使用。CDX包含正常的用户行为以及几种类型的攻击。一个额外的计划描述了关于网络结构和IP广告装扮的元数据,但单个数据包没有被标记。此外,基于主机的日志文件和IDS的警告也是可用的。

CTU13(Garcia等人,2014)。CTU13数据集是在2013年捕获的,有三种格式。它是在一个大学网络中捕获的,并区分了包含不同僵尸网络攻击的场景。网站上还提供了关于受影响主机的其他信息。流量是用三个阶段的方法来标记的。在第一阶段,所有进出受感染主机的流量被标记为僵尸网络。在第二阶段,符合特定过滤器的流量被标记为正常流量。其他的流量被标记为背景。因此,后台流量可能是正常的或恶意的。作者建议将他们的数据集分成训练和测试子集(Garcia等人,2014)。

DARPA(Lippmann等人,2000a,b)。DARPA 1998/99数据集是最受欢迎的入侵检测数据集,是在麻省理工学院林肯实验室的模拟网络工作环境中创建的。DARPA 1998和DARPA 1999数据集分别包含7周和5周的基于数据包的网络流量,包括各种类型的攻击,如DoS、缓冲区溢出、端口扫描或rootkits。其他信息和下载链接可以在网站上找到。尽管(或因为)它们的广泛分布,这些数据集经常被批评为人为的攻击注入或大量的冗余(McHugh, 2000; Tavallaee等人, 2009)。

DDoS 2016(Alkasassbeh等人,2016)。Alkasassbeh等人(2016)发表了一个基于数据包的数据集,该数据集是在2016年使用网络模拟器NS2创建的。关于模拟网络环境的详细信息无法获得。DDoS 2016的数据集集中在不同类型的DDoS攻击。除了正常的网络流量外,该数据集还包含四种不同类型的DDoS攻击。UDP洪水、smurf、HTTP洪水和SIDDOS。该数据集包含210万个狮子包,可以在researchgate下载。

IRSC(Zuech等人,2015)。IRSC数据集是在2015年记录的,使用了一种创造性的方法。捕获了具有正常用户行为的真实网络流量和来自互联网的攻击。除此以外,还手动运行了额外的攻击。IDS SNORT 16和人工检查被用于标记。由于该数据集出于保密的考虑没有公开,我们无法填写表3中的所有属性。

ISCX 2012(Shiravi等人,2012)。ISCX数据集是在2012年创建的,在一个模拟的网络环境中捕捉了一周的流量。作者使用了一种动态的方法来生成入侵检测数据集,其中包括非恶意以及恶意的网络行为。所谓的α文件定义了攻击场景,而β文件则描述了正常的用户行为,如写邮件或浏览网页。这些配置文件被用来创建一个基于数据包和基于双向流量的新数据集。这种动态方法允许不断产生新的数据集。ISCX可以在网站上下载,包含各种类型的攻击,如SSH暴力攻击、DoS或DDoS。

ISOT(Saad等人,2011)。ISOT数据集是在2010年创建的,它结合了匈牙利爱立信研究院流量实验室(Szabóet al., 2008)和劳伦斯伯克利国家实验室(LBNL)(Pang et al., 2005)的正常网络流量和hon eynet项目法国分部的恶意网络流量。ISOT被用于检测P2P僵尸网络(Saad等人,2011)。由此产生的数据集是公开的,包含11GB的pcap格式的基于数据包的数据。

KDD CUP 99 ( Stolfo, 2018 )。KDD CUP 99是基于DARPA的数据集,也是入侵检测最广泛的数据集之一。由于它既不是标准的数据包,也不是基于流量的格式,它属于其他类别。该数据集包含关于TCP连接的基本属性和高级属性,如失败的登录次数,但没有IP地址。KDD CUP 99包含了20多种不同类型的攻击(例如DoS或缓冲区溢出),并附带一个明确的测试子集。该数据集包括500万个数据点,可以免费下载。

Kent 2016 ( Kent, 2015a ), ( Kent, 2015b )。这个数据集是在洛斯阿拉莫斯国家实验室的网络上采集了58天。它包含了大约1.3亿个基于单向流量的网络流量,以及一些基于主机的日志文件。为了保护隐私,网络流量被大量地匿名化。该数据集没有标示,可以在网站上下载。

Kyoto 2006+(Song等人,2011)。Kyoto 2006+是一个公开的蜜罐数据集,包含真实的网络流量,但只包括少量和小范围的现实正常用户行为。Kyoto 2006+被归类为其他,因为IDS Bro 23被用来将基于数据包的流量转换成一种叫做会话的新格式。每个会话包括24个属性,其中14个是受KDD CUP 99数据集启发而形成的统计特征。剩下的10个属性是典型的基于流量的属性,如IP地址(以匿名形式)、端口或持续时间。一个标签属性表示攻击的存在。数据被捕获超过三年。由于记录时间异常长,该数据集包含约9300万个会话。

LBNL(Pang等人,2005)。关于入侵检测数据集的研究经常提到LBNL的数据集。因此,为了完整起见,这个数据集也被添加到列表中。创建LNBL数据集的主要动机是分析企业网络内的网络流量特征,而不是发布入侵检测数据。根据其创建者的说法,该数据集仍可作为安全研究人员的背景流量,因为它几乎完全包含正常的用户行为。该数据集没有标签,但出于隐私原因进行了匿名化处理,并包含100多个小时的基于数据包的网络流量。该数据集可以在网站上下载。

NDSec1(Beer等人,2017)。NDSec1数据集是可以评论的,因为它被设计为网络工作安全的攻击构成。根据作者的说法,这个数据集可以被重新使用,以使用过度铺设的方法(Aviv和Haeberlen,2011)的攻击来盐化现有的网络流量。NDSec1是根据要求公开提供的,并在2016年以基于数据包的格式捕获。它包含额外的syslog和win dows事件日志信息。NDSec 1的攻击构成包括僵尸网络、暴力攻击(针对FTP、HTTP和SSH)、DoS(HTTP泛滥、SYN泛滥、UDP泛滥)、ex ploits、端口扫描、欺骗以及XSS/SQL注入。

NGIDSDS(Haider等人,2017)。NGIDSDS数据集包含基于数据包格式的网络流量以及基于主机的日志文件。它是在模拟环境中生成的,使用IXIA完美风暴工具来生成正常的用户行为以及来自七个不同攻击系列的攻击(例如DoS或蠕虫)。因此,生成数据的质量主要取决于IXIA Perfect Storm的硬件。标记的数据集包含大约100万个数据包,并且是公开可用的。

NSLKDD(Tavallaee等人,2009)。NSLKDD 增强了 KDD CUP 99。对KDD CUP 99数据集的一个主要批评是大量的冗余(Tavallaee等人,2009)。因此,NSLKDD的作者从KDD CUP 99数据集中删除了重复的数据,并创建了更复杂的子集。由此产生的数据集包含大约150,000个数据点,并被分为预定的训练和测试子集,用于入侵检测方法。NSLKDD使用的属性与KDD CUP 99相同,属于其他类别。然而,应该注意的是,NSLKDD的基础网络流量可以追溯到1998年。该数据集是公开可用的。

PUIDS(Singh等人,2015)。PUIDS数据集是NSLKDD数据集的衍生品。作者开发了一个基因分析器,它可以提取输入数据集的统计数据,并使用这些统计数据来生成新的合成实例。作为一个序列,Singh等人(2015)的工作可以被看作是一个traf fic生成器,用于创建PUIDS,其中包含约20万个数据点,具有与NSLKDD数据集相同的属性和格式。由于NSLKDD是基于KDD CUP 1999,而KDD CUP又是从DARPA 1998中提取的,因此创建年份被设定为1998年,因为流量生成器的输入是在那时采集的。

PUF(Sharma等人,2018)。最近,Sharma等人(2018)发布了基于流量的PUF数据集,该数据集在校园网络中捕获了三天,只包含DNS连接。在总共298,463个单一流量中,有38,120个是恶意的,而其余的则反映了正常的用户活动。所有的流量都是用入侵防御系统的日志标记的。由于隐私原因,数据集中的IP地址被删除。作者打算将PUF公开。

SANTA(Wheelus等人,2014)。SANTA数据集是在一个ISP环境中捕获的,包含真实的网络工作流量。网络流量是通过手动程序标记的,并以所谓的基于会话的格式存储。这种数据格式类似于NetFlow,但富含额外的属性,这些属性是通过使用基于数据包的形成来计算的。作者花了很多精力来生成额外的属性,这些属性应该能增强入侵检测方法。SANTA是不公开的。

SSENet2011(Vasudevan等人,2011)。SSENet2011是在一个模拟环境中捕获的,历时四个小时。它包含几个攻击,如DoS或端口扫描。参与者的浏览活动产生了正常的用户行为。每个数据点都由24个属性来描述。由于Tstat工具被用来从基于数据包的流量中提取调整后的数据点,因此该数据集被划分为其他类别。我们没有发现关于公开的信息。

SSENet2014(Bhattacharya and Selvakumar, 2014)。SSENet2014是通过从SSENet2011(Vasudevan等人,2011)的基于数据包的文件中提取属性创建的。因此,与SSENet2011一样,该数据集被归类为其他。作者为每个数据点提取了28个属性,描述基于主机和网络的属性。创建的属性与KDD CUP 1999一致。SSENet2014包含200,000个标记的数据点,并被分为训练和测试子网。SSENet2014是唯一已知的具有平衡训练子集的数据集。同样,也没有找到关于公开可用性的信息。

SSHCure(Hofstede等人,2014)。Hofstede等人(2014)提出了SSHCure,一个用于SSH攻击检测的工具。为了评估他们的工作,作者在一个大学网络中捕获了两个数据集(每个数据集的时间为一个月)。由此产生的数据集是公开的,并且只包含SSH网络工作流量。基于流量的网络流量没有被直接拉到。相反,作者提供了额外的基于主机的日志文件,可用于检查SSH登录尝试是否成功。

TRAbID ( Viegas et al., 2017 )。Viegas等人在2017年提出了TRA bID数据库( Viegas et al., 2017 )。该数据库包含16个不同的场景,用于评估IDS。每个场景都是在一个模拟环境中捕获的(1个蜜罐服务器和100个客户端)。在每个场景中,流量被捕捉了30分钟,一些攻击被切断。为了标记网络流量,作者使用了客户的IP广告词。所有客户都是Linux机器。一些客户专门进行攻击,而大多数客户专门处理用户对蜜罐服务器的正常请求。正常的用户行为包括HTTP、SMTP、SSH和SNMP流量,而恶意的网络流量包括端口扫描和DoS攻击。TRAbID是公开可用的。

TUIDS(Gogoi等人,2012),(Bhuyan等人,2015)。La beled TUIDS数据集可分为三个部分。TUIDS入侵数据集,TUIDS协调扫描数据集和TU IDS DDoS数据集。正如名字已经表明的那样,这些数据集包含了正常的用户行为,主要是端口扫描或DDoS等攻击。数据是在一个包含大约250个客户的模拟环境中产生的。流量是以基于数据包和基于双向流量的格式捕获的。每个子集的时间跨度为7天,所有三个子集都包含大约25万个流量。不幸的是,原始出版物中的数据集链接似乎已经过时了。然而,作者对电子邮件请求作出了回应。

Twente(Sperotto等人,2009)。Sperotto等人(2009)在2008年发表了第一批基于流量的入侵检测数据集之一。这个数据集跨越了六天的流量,涉及一个提供网络、FTP和SSH服务的hon eypot服务器。由于这种方法,该数据集只包含来自蜜罐的网络流量,几乎所有的流量都是恶意的,没有也没有恶意的用户行为。作者分析了基于数据包格式的日志文件和流量,以标注该数据集的流量。该数据集是公开的,由于隐私问题,IP地址被删除。

UGR'16(MaciáFernández等人,2018)。UGR'16是一个基于单线流量的数据集。它的重点在于捕捉ISP环境中的周期性效应。因此,它跨越了四个月的时间,包含169亿个单向流量。IP地址是匿名的,流量被标记为非恶意、背景或攻击。作者在该数据集中明确地执行了几种攻击(僵尸网络、DoS和端口扫描)。相应的流量被标记为攻击,其他一些攻击被识别并被手动标记为攻击。注入的正常用户行为和符合特定模式的流量被标记为正常。然而,大多数流量被标记为背景,这可能是正常的,也可能是一种攻击。该数据集是公开可用的。

UNIBS 2009(Gringoli等人,2009)。与LBNL(Pang等人,2005)一样,UNIBS 2009数据集不是为入侵检测而创建的。由于UNIBS 2009在其他工作中被引用,所以仍然被添加到列表中。Gringoli等人(2009)使用该数据集,根据其基于流量的网络流量来识别应用程序(如网络浏览器、Skype或邮件客户端)。UNIBS 2009包含了大约79,000个没有恶意行为的流量。由于标签只是描述了流量的应用协议,网络流量没有被归类为正常或攻击。因此,分类方案中的属性标签被设置为无。该数据集是公开可用的。

Unified Host and Network Data Set ( Turcotte等人,2017)。该数据集包含基于主机和网络的数据,这些数据是在真实环境中捕获的,即LANL(洛斯阿拉莫斯国家实验室)企业网络。出于隐私原因,IP地址和时间戳等属性在基于流量的双向网络流量文件中被匿名化。网络流量的收集期为90天,没有标签。该数据集是公开可用的。

UNSWNB15(Moustafa和Slay,2015)。UNSWNB15数据集包括基于数据包的正常和恶意网络流量,它是在一个小型模拟环境中使用IXIA Perfect Storm工具创建的,历时31小时。它包含九个不同的攻击系列,如后门、DoS、漏洞、模糊器或蠕虫。该数据集也可以用基于流量的格式提供,并有额外的属性。UNSWNB15带有预定义的训练和测试分割。该数据集包括45个不同的IP地址,并且是公开可用的。

5.6 其他数据源

除了基于网络的数据集,还有其他一些基于数据包和流量的网络流量的数据源。在下文中,我们将很快讨论数据存储库和流量生成器。

6.1数据存储库

除了传统的数据集,在互联网上还可以找到一些数据存储库。由于这些资源库的类型和结构有很大的不同,我们不做表格的比较。相反,我们按字母顺序给出一个简短的文字概述。储存库已于2019年2月26日进行了实际检查。

AZSecure。AZSecure是亚利桑那大学的一个网络数据存储库,供研究界使用。它包括各种pcap、arff和其他格式的数据集,其中有些是有标签的,有些则没有。AZSecure en compasses,其中包括CTU13数据集(Garcia等人,2014)或统一主机和网络数据集(Turcotte等人,2017)。该存储库得到了管理,并包含一些最近的数据集。

CAIDA。CAIDA收集了不同类型的数据集,具有不同程度的可用性(公开访问或应要求),并提供一个搜索引擎。一般来说,需要填写一个表格来获得一些公共数据集的访问权。此外,大多数基于网络的数据集只能通过IMPACT(见下文)登录申请,因为CAIDA支持IMPACT作为数据提供者。储存库被管理并更新了新的数据。

Contagiodump. Contagiodump是一个关于恶意软件转储的博客。每年都有几个帖子,最后一个帖子是在2018年3月20日。该网站包含,除其他外,恶意软件分析的pcap文件的集合。

http://covert.io。http://Covert.io是Jason Trost的一个关于安全和机器学习的博客。该博客维护着不同的教程列表、GitHub存储库、研究论文和其他有关安全、大数据和机器学习的博客,同时也收集了各种基于安全的数据资源。最新的条目是由Jason Trost于2017年8月14日发布的。

DEF CON CTF档案。DEF CON是一个受欢迎的年度黑客大会。该活动包括夺旗(CTF)比赛,每个团队都必须捍卫自己的网络工作,对抗其他团队,同时入侵对手的网络。比赛通常被记录下来,并在网站上以数据包的形式提供。鉴于比赛的性质,记录的数据大多只包含攻击流量,很少有正常用户行为。该网站是最新的,每年都会更新CTF比赛的新数据。

IMPACT。IMPACT Cyber Trust,以前被称为PRE DICT,是一个由数据提供者、网络安全搜索者以及协调者组成的社区。IMPACT是管理和更新的。网站上提供了一个数据目录,以浏览社区提供的数据集。数据提供者是(除其他外)DARPA、麻省理工学院林肯实验室或UCSD应用互联网数据分析中心(CAIDA)。然而,这些数据集只能通过ac数下载,而ac数只能由美国国土安全部批准的八个选定国家的研究人员申请。由于德国不在批准的地点之列,因此不能对数据集作进一步的说明。

互联网流量档案。互联网流量档案馆是由ACM SIG COMM主办的互联网流量追踪库。该列表包括四个广泛的基于匿名的数据包追踪。特别是,有效载荷已被删除,所有的时间戳都是相对于第一个数据包的,而IP地址已被改为数字表示。这些基于数据包的数据集是20多年前采集的,可以不受限制地下载。

Kaggle。Kaggle是一个分享和发布数据集的在线平台。该平台包含基于安全的数据集,如KDD CUP 99,并有一个搜索功能。它还允许注册用户上传和探索数据分析模型。

恶意软件流量分析。恶意软件流量分析是一个资源库,其中包含与网络流量分析有关的博客文章和练习,例如识别恶意活动。练习伴随着基于数据包的网络流量,通过所提供的练习答案来间接标注。可下载的文件有一个密码,可以从网站上获得。储存库是最新的,几乎每天都有新的博客文章发布。

中大西洋地区CCDC。与DEFCON CTF类似,MACCDC是由美国国家网络监控中心主办的年度比赛,比赛中捕获的基于数据包的流量被提供出来。参赛队伍必须保证他们的网络所提供的服务不被任何方式打断。与DEFCON CTF档案相似,MACCDC数据几乎只包含攻击流量,很少有正常用户行为。最新的比赛是在2018年举行的。

MAWILab。MAWILab档案库包含了长期以来在美国和日本之间的链接上捕获的大量网络流量。自2007年以来的每一天,资源库都包含了基于数据包格式的15分钟追踪。出于隐私原因,IP地址被匿名化,数据包的有效载荷被省略。使用不同的异常检测方法对捕获的网络流量进行标记(Fontugne等人,2010)。

MWS。反恶意软件工程研讨会(MWS)是日本一个关于恶意软件的年度研讨会。工作坊伴随着几个MWS数据集,其中包括基于数据包的网络数据和基于主机的日志文件。然而,这些数据集只在由日本工业界和学术界的研究人员组成的MWS社区内共享(Hatada等人,2015)。最新的研讨会在2018年举行。

NETRECSEC。NETRECSEC维护着互联网上公开可用的pcap文件的综合列表。与SecRepo类似,NETRECSEC参考了这项工作中提到的许多存储库,但也纳入了其他来源,如蜜罐转储或CTF事件。它的及时性只能间接判断,因为NETRECSEC还提到了2018年的数据痕迹。

OpenML。OpenML是一个更新的平台,用于分享机器学习数据集。它还包含基于安全的数据集,如KDD CUP 99。 该平台有一个搜索功能,并伴随着其他可能性,如创建科学任务。

RIPE Data Repository。RIPE Data Repository承载了许多数据集。然而,几年来没有新的数据集被纳入其中。为了获得访问权,用户需要创建一个账户并接受数据集的条款和条件。该存储库还反映了怀卡托互联网流量存储的一些数据(见下文)。

SecRepo。SecRepo 列出了不同的安全相关数据样本,由 Mike Sconzo 维护。该列表按以下类别提供。网络、恶意软件、系统、文件、密码、威胁信息和其他。这个非常详细的列表包含了对典型数据集的参考,如DARPA,但也包含了许多存储库(如NETRECSEC)。该网站最后一次更新是在2018年11月20日。

Simple Web。Simple Web提供了一个数据库集合和网络管理教程和软体的信息。该数据库包括不同格式的痕迹,如基于数据包或流量的网络流量。它由Univer sity of Twente主持,由DACS(通信系统的设计和分析)小组成员维护,并根据该小组的新成果进行更新。

UMassTraceRepository。UMassTraceRepository为研究界提供了一些网络traf fic的痕迹。其中一些痕迹是由档案馆的供应者自己收集的,而其他的则是捐赠的。该档案包括来自不同来源的19个基于数据包的数据集。最近的数据集是在2018年采集的。

VAST Challenge。IEEE视觉分析科学和技术(VAST)挑战赛是一个年度竞赛,目的是通过竞赛推动视觉分析领域的发展。在一些挑战中,网络流量数据被提供给竞赛任务。例如,2011年VAST竞赛的第二个小型挑战涉及一个IDS日志,包括基于数据包的pcap格式的网络流量。在2012年的后续VAST挑战中也使用了类似的设置。此外,2013年的一个VAST挑战涉及基于流量的网络流量。

WITS:Waikato Internet Traffic Storage.。该网站旨在列出由WAND再搜索组拥有的所有互联网痕迹。这些数据集通常是基于数据包的格式,可以从怀卡托的服务器上免费下载。然而,该存储库已经很久没有更新了。

6.2流量生成器

入侵检测研究的另一个网络流量来源是流量生成器。流量生成器是创建合成网络流量的模型。在大多数情况下,流量生成器使用用户定义的参数或提取真实网络流量的基本属性来创建新的合成网络流量。数据集和数据存储库提供固定的数据,而流量生成器允许生成可适应某些网络结构的网络流量。

例如,流量生成器FLAME(Brauckhoff等人,2008)和ID2T(Vasilomanolakis等人,2016)使用真实网络流量作为输入。这种输入流量应作为正常用户行为的基线。然后,FLAME和ID2T通过编辑输入流量的值或在考虑典型攻击模式的情况下注入合成流量来增加恶意的网络流量。Siska等人(2010)提出了一个基于图形的流量生成器,它从真实的网络流量中提取流量模板。然后,他们的生成器使用这些流量模板,以创建新的基于流量的合成网络流量。Ring等人(2019)将GANs用于生成合成网络流量。作者使用改进的Wasserstein Generative Adversar ial Networks(WGANGP)来创建基于流量的网络流量。WGANGP用真实的网络流量进行训练,学习流量特性。训练结束后,WGANGP能够创建具有类似特征的新的基于流量的合成网络流量。Erlacher和Dressler的流量生成器GENESIDS(Erlacher和Dressler,2018)根据用户定义的攻击描述生成HTTP攻击流量。还有许多额外的流量生成器,为了简洁起见,这里不做讨论。除了这些流量生成器,还有许多其他的流量生成器,这里不做讨论。相反,我们参考Molnár等人(2013)的流量生成器概述。

Brogi和Tong(2017)提出了另一个想法,在某种意义上类似于流量生成器。从因隐私问题而共享数据集的问题出发,他们提出了Moirai,一个允许用户共享完整场景而不是数据集的框架。Moirai背后的想法是在虚拟机中重放攻击场景,这样用户就可以在飞行中产生数据。

第三种方法也被归入流量生成器的大背景中,是支持用户标记真实网络流量的框架。Rajasinghe等人提出了这样一个框架,名为INSecSDCS(Rajasinghe等人,2018),它在网络设备上捕获网络流量,或使用pcap文件中准备好的网络流量作为输入。然后,INSecSDCS将数据流划分为时间窗口,用适当的属性对数据点进行分类,并根据用户定义的攻击者IP地址列表对网络流量进行标注。因此,INSecSDCS的重点是对网络工作流量进行标记和提取有意义的属性。Aparicio Navarro等人(2014)提出了一种使用无监督的基于异常的IDS的自动数据集标签方法。由于没有IDS能够将每个数据点分类到正确的类别,作者采取了一些中间措施来减少假阳性和真阴性的数量。IDS为每个数据点分配正常和攻击类别的信念值。如果这两个类别的信念值之间的差异小于预定的阈值,则该数据点将从数据集中删除。这种方法提高了标签的质量,但可能会丢弃数据集中最有趣的数据点。

5.7 意见和建议

标记的数据集对于训练有监督的数据挖掘方法(如分类算法)是不可避免的,并且有助于评估有监督和无监督的数据挖掘方法。因此,基于标签的网络数据集可以用来比较不同的NIDS的质量。然而,在任何情况下,数据集必须是有代表性的,以适合这些任务。社区已经意识到基于网络的真实数据的重要性,这项调查表明,有许多这样的数据来源(数据集、数据存储库和流量生成器)。此外,这项工作建立了一个数据集属性的集合,作为比较现有数据集和确定合适的数据集的基础,给定具体的评估方案。在下文中,我们将讨论有关使用现有数据集和创建新数据集的一些方面。

完美的数据集。不断增加的攻击场景,伴随着新的和更复杂的软件和网络结构,导致要求数据集应包含最新的和真实的网络流量。由于没有完美的IDS,数据点的标记应该由人工检查,而不是完全由IDS完成。因此,完美的基于网络的数据集是最新的、正确的、公开的、包含各种攻击和正常用户行为以及有效载荷的真实网络流量,并且跨越很长一段时间。然而,这样的数据集并不存在,而且(可能)永远不会被创建。如果隐私问题可以得到满足,并且现实世界的网络流量(基于数据包的格式)可以在足够长的时间内被记录下来,那么对这种流量进行准确的标记将是非常耗时的。因此,由于新的攻击场景不断出现,标记过程将花费大量时间,以至于数据集稍显过时。然而,一些可用的数据集满足了完美数据集的一些特性。此外,大多数应用并不要求完美的数据集,满足某些特性的数据集往往就足够了。例如,在评估一个新的端口扫描检测算法时,不需要一个数据集包含所有类型的攻击,或者在评估一个特定服务器的安全性时,不需要完整的网络配置。因此,我们希望这项工作能够支持研究人员为其特定的评估场景找到合适的数据集。

使用几个数据集。如上所述,不存在完美的基于网络的数据集。然而,这项调查显示,有几个数据集(和其他数据源)可以用于基于数据包和流量的网络流量。因此,我们建议用户用一个以上的数据集来评估他们的入侵检测方法,以避免对某个数据集的过度拟合,减少某个数据集的人为因素的影响,并在一个更普遍的背景下评估他们的方法。除此之外,Hofstede等人(2018)表明,基于流量的网络流量在实验室环境和生产网络之间有所不同。因此,另一种方法可以同时使用,分别模拟的合成数据集和真实世界的网络流量来强调这些要点。

为了确保第三方的可重复性,我们建议用至少一个公开的数据集来评估入侵检测方法。此外,我们想对CICIDS 2017、CIDDS001、UGR'16和UNSW NB15数据集的使用提出一般性建议。这些数据集可能适用于一般的评估环境。CICIDS 2017和UNSWNB15包含广泛的攻击场景。CIDDS001包含详细的元数据,可供深入调查。UGR'16因其巨大的流量而脱颖而出。然而,应该考虑到这一建议反映了我们的个人观点。该建议并不意味着其他数据集是不合适的。例如,由于CTU13和ISCX2012数据集的使用年限越来越长,我们只是避免将其纳入我们的建议中。此外,其他数据集如AWID或Botnet更适合于某些评估场景。

预定义子集。此外,我们想就基于异常的NIDS的评估做一个说明。机器学习和数据挖掘方法经常使用所谓的10倍交叉验证(Han等人,2011)。这种方法将数据集划分为十个大小相等的子集。一个子集用于测试,其他九个子集用于训练。这个过程要重复十次,这样每个子集都被用于测试一次。然而,这种直接分割数据集的做法对入侵检测的意义有限。例如,端口扫描数据集CIDDS002(Ring等人,2017)包含两周的网络流量,以流量为基础进行垫。这个数据集中的每个端口扫描可能会引起成千上万的流量。使用10倍交叉验证会导致的情况是,每种攻击的一些流量可能出现在训练数据集中。因此,测试数据中的攻击检测被简化了,而概括性却没有得到正确的评估。在这种情况下,对于CIDDS002数据集,最好是在第一周进行训练,在第二周进行测试(反之亦然)。在这种方法上定义子集也可以考虑网络流量随时间变化的概念漂移的影响。另一种创建合适子集的方法可能是根据流量特征(如源IP地址)来分割整个数据集。然而,这样的子集必须被精心设计,以保持数据集的基本网络结构。例如,一个只有代表客户的源IP地址而没有分离器的训练数据集是不合适的。基于这些观察,我们建议在应用域IT安全方面创建有意义的训练和测试分割。因此,基准数据集应该以预定义的训练和测试分割方式发布,以方便对相同数据评估的不同方法进行比较。

更紧密的合作。这项研究表明(见第5节),许多数据集在过去几年中已经发表,而且社区正在不断地创建新的入侵检测数据集。此外,社区可以从更紧密的合作和单一的普遍接受的平台中受益,以分享入侵检测数据集,没有任何访问限制。例如,Cermak等人(2018)致力于建立这样一个共享入侵检测数据集的平台。同样,Ring等人(2017c)发表了他们的脚本,用于模拟正常的用户行为和攻击,这样就可以被第三方使用和改进。所有提到的数据集和数据存储库的简短摘要可以在我们的网站上找到,我们打算用即将到来的基于网络的数据集更新这个网站。

标准格式。大多数基于网络的入侵检测方法需要标准的输入数据格式,不能处理预处理的数据。此外,其他类别的数据集(第3.3节)是否能实时计算是个问题,这可能会影响它们在NIDS中的作用。因此,我们建议以标准的基于数据包或基于流量的格式提供基于网络的数据集,因为它们是在真实的网络环境中捕获的。同时,许多基于异常的方法(如Wang等人,2010年或Zhang等人,2008年)在其他类别的数据集中实现了较高的检测率,这表明计算的属性对入侵检测是有希望的。因此,我们建议同时发布基于网络的标准格式的数据集和用于将数据集转换为其他格式的脚本。这种方法有两个好处。首先,用户可以决定他们是否要将数据集转移到其他格式,更多的研究人员可以使用相应的数据集。第二,这些脚本也可以应用于未来的数据集。

匿名化。匿名化是另一个重要的问题,因为这可能使基于网络的数据集的分析变得复杂。因此,应该仔细评估哪些属性必须被抛弃,哪些属性可以以匿名形式公布。许多作者证明了只使用有效载荷的小部分的有效性。例如,Mahoney(2003)提出了一种入侵检测方法,它使用每个数据包的前48字节,从IP头开始。流量输出器YAF(Inacio and Tram mell, 2010)允许通过提取有效载荷的前n个字节或计算有效载荷的熵来创建这种属性。一般来说,有几种匿名化的方法。例如,Xu等人(2002)提出了一种预保留的IP地址匿名化技术。Tcpmkpub(Pang等人,2006)是一个基于数据包的网络流量的匿名化工具,它允许对一些属性(如IP地址)进行匿名化,也可以计算出头检查和的新值。我们参考Kelly等人(2008)对基于网络的数据的匿名化技术进行了更全面的回顾。

公开。我们建议公布基于网络的数据集。只有公开的数据集才能被第三方使用,从而作为评估NIDS的基础。同样,数据集的质量也只有在公开可用的情况下才能被第三方检查。最后但同样重要的是,我们建议公布更多的元数据,以便第三方能够更详细地分析数据及其结果。

5.8 总结

标记的基于网络的数据集对于训练和评估NIDS是必要的。本文对现有的基于网络的入侵检测数据集进行了文献调查。为此,对基于网络的标准数据格式进行了更详细的分析。此外,还确定了15种可用于评估数据集适用性的属性。这些属性被分为五类。一般信息、数据的性质、数据量、记录环境和评估。

本文的主要贡献是对34个数据集的全面概述,指出了每个数据集的特殊性。因此,本文特别关注数据集内的攻击场景及其相互关系。此外,每个数据集都根据第一步制定的分类方案的属性进行评估。这一详细的调查旨在支持读者为他们的目的确定数据集。对数据集的审查表明,研究界已经注意到缺乏公开可用的基于网络的数据集,并试图通过在过去几年中发布相当数量的数据集来克服这一不足。由于有几个研究小组活跃在这一领域,预计很快会有更多的入侵检测数据集和改进。

作为网络流量的进一步来源,流量生成器和数据存储库将在第6节讨论。流量生成器创建合成的网络流量,并可用于为特定场景创建适应的网络流量。数据存储库是互联网上不同网络痕迹的集合。与第5节中的数据集相比,10个数据存储库提供了有限的文件、非标签数据集或特定场景的网络流量(例如,专门的FTP连接)。然而,在寻找合适的数据时,应该考虑到这些数据源,特别是对于特殊的场景。最后,我们讨论了对使用和生成基于网络的入侵检测数据集的一些意见和建议。我们鼓励用户在多个数据集上评估他们的方法,以避免对某一数据集的过度拟合,并减少某一数据集的人工假象的影响。此外,我们主张采用标准格式的数据集,包括预定义的训练和测试子集。总的来说,可能不会有一个完美的数据集,但有许多非常好的数据集可用,社区可以从更紧密的合作中受益