为您推荐:
精华内容
最热下载
问答
  • 5星
    5.42MB weixin_42146888 2021-02-03 04:26:26
  • 4星
    17.46MB magicnono 2020-07-14 22:04:12
  • 17.45MB weixin_38746387 2019-11-26 15:29:55
  • 5星
    44KB weixin_42160398 2021-03-11 22:42:40
  • 30.8MB tingmengyun8941 2018-04-24 13:43:47
  • 5KB weixin_42174176 2021-02-05 16:35:22
  • 5.3MB qq_25648915 2019-01-20 14:46:44
  • 5星
    17KB weixin_37855803 2017-09-04 10:03:35
  • 4星
    23MB confused_ya 2019-01-05 20:24:37
  • 3星
    66.32MB a81836620 2017-11-26 16:09:34
  • 364KB qq_25648915 2019-01-20 14:49:05
  • 3.2MB qq_39480875 2020-03-29 16:13:44
  • 1.57MB weixin_42098251 2021-07-03 17:16:51
  • 27.91MB weixin_38587155 2021-04-01 14:55:33
  • 17.45MB xiaohuihui22218 2018-05-07 17:11:53
  • KDD99数据集的特征(Features)介绍 首发于我的博客:寒山雨的个人博客 KDD99是一个用来从正常连接中监测非正常连接的数据集。产出于1999年Thrid International Knowlegde Discovery and Data Mining Tools ...

    KDD99数据集的特征(Features)介绍

    首发于我的博客:寒山雨的个人博客

    KDD99是一个用来从正常连接中监测非正常连接的数据集。产出于1999年Thrid International Knowlegde Discovery and Data Mining Tools Competition,其目的是建立一个稳定的的入侵检测系统。

    KDD99包含了置入攻击的军事网络环境中的记录。攻击可以分类为:

    • DoS攻击:Denial of Service
    • R2U:Remote to User
    • U2R:User to Root
    • 探针攻击:Probing

    KDD99数据集是 DARPA数据集特征提取(Feature Extract) 版本( DARPA 是原始数据集)KDD99对每个连接提取了 41 个特征,使用Bro-IDS工具对数据贴标签。

    其41个特征可以按以下方式分类:

    • 1-9 TCP连接的基本特征
    • 10-22 TCP连接的内容特征
    • 23-31 基于时间的网络流量统计特征,使用2秒的时间窗(Traffic features computed using a two-second time window)
    • 32-41 基于主机的网络流量统计特征,主机特征(Host features),用来评估持续时间在两秒钟以上的攻击

    TCP连接的基本特征

    feature namedescriptiontype
    durationlength (number of seconds) of the connection
    连接的持续时间,以秒(s)为单位
    [0 ~ 58329]
    它的定义是从TCP连接以3次握手建立算起,到FIN/ACK连接结束为止的时间;若为UDP协议类型,则将每个UDP数据包作为一条连接。(数据集中出现大量的duration=0 的情况,是因为该条连接的持续时间不足1秒.)
    continuous
    连续
    protocol_typetype of the protocol, e.g. tcp, udp, etc.
    协议类型,此数据集中有三种:
    TCP, UDP, ICMP
    discrete
    离散
    servicenetwork service on the destination, e.g., http, telnet, etc.
    连接目的端的网络服务。有70+种:
    aol, auth, bgp, courier, csnet_ns, ctf, daytime, discard, domain, domain_u, echo, eco_i, ecr_i, efs, exec, finger, ftp, ftp_data, gopher, harvest, hostnames, http, http_2784, http_443, http_8001, imap4, IRC, iso_tsap, klogin, kshell, ldap, link, login, mtp, name, netbios_dgm, netbios_ns, netbios_ssn, netstat, nnsp, nntp, ntp_u, other, pm_dump, pop_2, pop_3, printer, private, red_i, remote_job, rje, shell, smtp, sql_net, ssh, sunrpc, supdup, systat, telnet, tftp_u, tim_i, time, urh_i, urp_i, uucp, uucp_path, vmnet, whois, X11, Z39_50
    discrete
    离散
    src_bytesnumber of data bytes from source to destination
    从源主机到目的主机数据的字节数
    [0 ~ 1379963888]
    continuous
    连续
    dst_bytesnumber of data bytes from destination to source
    从目的主机到源主机数据的字节数
    [0 ~ 1309937401]
    continuous
    连续
    flagnormal or error status of the connection
    连接状态正常或错误的标志,共11中
    OTH, REJ, RSTO, RSTOS0, RSTR, S0, S1, S2, S3, SF, SH
    表示该连接是否按照协议要求开始或完成。例如SF表示连接正常建立并终止;S0表示只接到了SYN请求数据包,而没有后面的SYN/ACK。其中SF表示正常,其他10种都是error。
    11种状态的详细解释,参考文章[4]
    discrete
    离散
    land1 if connection is from/to the same host/port; 0 otherwise
    1: 连接来自/到同一主机/端口
    0: 其它
    discrete
    离散
    wrong_fragmentnumber of ``wrong’’ fragments
    “错误”片段的数量
    [0 ~ 3]
    continuous
    连续
    urgentnumber of urgent packets
    urgent加急包数量
    [0 ~ 14]
    continuous
    连续

    Table 1: Basic features of individual TCP connections.

    表1:TCP连接的基本特征

    TCP连接的内容特征

    feature namedescriptiontype
    hotnumber of ``hot’’ indicators
    访问系统敏感文件和目录的次数
    [0 ~ 101]
    例如访问系统目录,建立或执行程序等
    continuous
    连续
    num_failed_loginsnumber of failed login attempts
    登录尝试失败的次数。
    [0 ~ 5]
    continuous
    连续
    logged_in1 if successfully logged in
    0 otherwise
    1:成功登录
    0:其它
    discrete
    离散
    num_compromisednumber of ``compromised’’ conditions
    ’compromised’条件出现的次数
    [0 ~ 7479]
    continuous
    连续
    root_shell1 if root shell is obtained; 0 otherwise
    1:获得root shell
    0:其它
    discrete
    离散
    su_attempted1 if ``su root’’ command attempted; 0 otherwise
    1:出现’su root’
    0:其它
    discrete
    离散
    num_rootnumber of ``root’’ accesses
    root用户访问次数
    [0 ~ 7468]
    continuous
    连续
    num_file_creationsnumber of file creation operations
    文件创建操作的次数
    [0 ~ 100]
    continuous
    连续
    num_shellsnumber of shell prompts
    使用shell命令的次数
    [0 ~ 5]
    continuous
    连续
    num_access_filesnumber of operations on access control files
    访问控制文件的次数
    [0 ~ 9]
    continuous
    连续
    num_outbound_cmdsnumber of outbound commands in an ftp session
    一个FTP会话种出现连接的次数
    数据集种这一特征出现次数为0
    continuous
    连续
    is_hot_login1 if the login belongs to the ``hot’’ list; 0 otherwise
    1:登录属于’hot’列表
    0:其它
    如超级用户或管理员登录
    discrete
    离散
    is_guest_login1 if the login is a ``guest’'login; 0 otherwise
    1:guest登录
    0:其它
    discrete
    离散

    Table 2: Content features within a connection suggested by domain knowledge.

    表2:TCP连接的内容特征

    基于时间的网络流量统计特征

    feature namedescriptiontype
    countnumber of connections to the same host as the current connection in the past two seconds
    Note: The following features refer to these same-host connections.
    过去两秒内,与当前连接具有相同的目标主机的连接数。
    [0 ~ 511]
    注意: 以下特征连接到相同主机
    continuous
    连续
    srv_countnumber of connections to the same service as the current connection in the past two seconds
    Note: The following features refer to these same-service connections.
    过去两秒内,与当前连接具有相同服务的连接数
    [0 ~ 511]
    注意: 以下特征连接到相同服务
    continuous
    连续
    serror_rate% of connections that have ``SYN’’ errors
    过去两秒内,在与当前连接具有相同目标主机的连接中,出现“SYN” 错误的连接的百分比
    [0.00 ~ 1.00]
    continuous
    连续
    rerror_rate% of connections that have ``REJ’’ errors
    过去两秒内,在与当前连接具有相同目标主机的连接中,出现“REJ” 错误的连接的百分比
    [0.00 ~ 1.00]
    continuous
    连续
    same_srv_rate% of connections to the same service
    过去两秒内,在与当前连接具有相同目标主机的连接中,与当前连接具有相同服务的连接的百分比
    [0.00 ~ 1.00]
    continuous
    连续
    diff_srv_rate% of connections to different services
    过去两秒内,在与当前连接具有相同目标主机的连接中,与当前连接具有不同服务的连接的百分比
    [0.00 ~ 1.00]
    continuous
    连续
    srv_serror_rate% of connections that have ``SYN’’ errors
    过去两秒内,在与当前连接具有相同服务的连接中,出现“SYN” 错误的连接的百分比
    [0.00 ~ 1.00]
    continuous
    连续
    srv_rerror_rate% of connections that have ``REJ’’ errors
    过去两秒内,在与当前连接具有相同服务的连接中,出现“REJ” 错误的连接的百分比
    [0.00 ~ 1.00]
    continuous
    连续
    srv_diff_host_rate% of connections to different hosts
    过去两秒内,在与当前连接具有相同服务的连接中,与当前连接具有不同目标主机的连接的百分比
    [0.00 ~ 1.00]
    continuous
    连续
    • count、serror_rate、rerror_rate、same_srv_rate、diff_srv_rate这5个特征是 same host特征,前提都是与当前连接具有相同目标主机的连接;

    • srv_count、srv_serror_rate、srv_rerror_rate、srv_diff_host_rate这4个特征是same service特征,前提都是与当前连接具有相同服务的连接。

    Table 3: Traffic features computed using a two-second time window.

    表 3:基于时间的网络流量统计特征

    基于主机的网络流量统计特征

    feature namedescriptiontype
    dst_host_count前100个连接中,与当前连接具有相同目标主机的连接数
    [0 ~ 255]
    连续
    dst_host_srv_count前100个连接中,与当前连接具有相同目标主机相同服务的连接数
    [0 ~ 255]
    连续
    dst_host_same_srv_rate前100个连接中,与当前连接具有相同目标主机相同服务的连接所占的百分比
    [0.00 ~ 1.00]
    连续
    dst_host_diff_srv_rate前100个连接中,与当前连接具有相同目标主机不同服务的连接所占的百分比
    [0.00 ~ 1.00]
    连续
    dst_host_same_src_port_rate前100个连接中,与当前连接具有相同目标主机相同源端口的连接所占的百分比
    [0.00 ~ 1.00]
    连续
    dst_host_srv_diff_host_rate前100个连接中,与当前连接具有相同目标主机相同服务的连接中,与当前连接具有不同源主机的连接所占的百分比
    [0.00 ~ 1.00]
    连续
    dst_host_serror_rate前100个连接中,与当前连接具有相同目标主机的连接中,出现SYN错误的连接所占的百分比
    [0.00 ~ 1.00]
    连续
    dst_host_srv_serror_rate前100个连接中,与当前连接具有相同目标主机相同服务的连接中,出现SYN错误的连接所占的百分比
    [0.00 ~ 1.00]
    连续
    dst_host_rerror_rate前100个连接中,与当前连接具有相同目标主机的连接中,出现REJ错误的连接所占的百分比
    [0.00 ~ 1.00]
    连续
    dst_host_srv_rerror_rate前100个连接中,与当前连接具有相同目标主机相同服务的连接中,出现REJ错误的连接所占的百分比
    [0.00 ~ 1.00]
    连续

    表 4:基于主机的网络流量统计特征(KDD99官网的task部分没找到对应表格)

    其它

    KDD99在研究者当中十分流行,研究者也对其本身做了很多工作:

    • [*]减少特征数量,从最初的41个特征中选择最有用的特征
    • [*]指出了KDD99的不足之处
      1. KDD99面临不平衡的分类方法问题。测试集和训练集的概率分布是不同的,由于在训练集中加入新的攻击,攻击和正常流量的类别的平衡会被打破。[?]
      2. 数据集太老了,可能存在过时的问题
      3. 有研究表明,该数据集存在导致对异常检测性能的过高估计的可能性

    参考资料

    [1]. CHAABOUNI N, MOSBAH M, ZEMMARI A, et al. Network Intrusion Detection for IoT Security Based on Learning Techniques [J]. Ieee Communications Surveys and Tutorials, 2019, 21(3): 2671-701.
    [2]. KDD Cup 1999 Data
    [3]. KDD99数据集与NSL-KDD数据集介绍 BTW: 这篇博客对 KDD99 和 NSL-KDD 写的很详细
    [4]. Song J, Takakura H, Okabe Y. Description of kyoto university benchmark data[J]. Available at link: http://www.takakura.com/Kyoto_data/BenchmarkData-Description-v5.pdf [Accessed on 15 March 2016], 2006.
    [5]. Özgür A, Erdem H. A review of KDD99 dataset usage in intrusion detection and machine learning between 2010 and 2015[J]. PeerJ Preprints, 2016, 4: e1954v1.

    展开全文
    qq_33949991 2021-03-06 16:42:03
  • 5星
    572KB weixin_42681774 2021-10-04 12:53:01
  • 147KB weixin_38552083 2021-05-20 14:59:26
  • 8.86MB weixin_45862742 2020-06-09 17:10:46
  • 4星
    4.82MB nice12341234 2018-04-27 10:10:57
  • 我们的任务是根据KDD99数据集训练神经网络来判别网络入侵。 1、 关于KDD99数据集的介绍,参见博客:https://blog.csdn.net/com_stu_zhang/article/details/6987632。我对该数据集的了解也是主要来自于该博客。所以...

    我们的任务是根据KDD99数据集训练神经网络来判别网络入侵。

    1、

    关于KDD99数据集的介绍,参见博客:https://blog.csdn.net/com_stu_zhang/article/details/6987632。我对该数据集的了解也是主要来自于该博客。所以关于该数据集不再做描述。

    2、

    任务主要分为三个部分,分别是数据处理,模型训练,分类预测。

    现在开始一部分一部分的讲。

    2.1、 数据处理

    KDD99的数据中有数字有字符串,标签也是字符串,同时,数字当中也是范围都不一样,有的是01离散数据,有的跨度为0到几百万,这样的数据训练肯定是不行的。所以在训练之前,需要对数据进行预处理。

    首先,将字符串转换为离散的数字。我们可以先读数据,找出所有存在的字符串。这个比较简单,我将结果直接列出来了。并写成一个函数方便后面获取。

    def get_col_types():
        protocol_type = ['icmp', 'tcp', 'udp']
        service_type = ['IRC', 'X11', 'Z39_50', 'auth', 'bgp', 'courier', 'csnet_ns', 'ctf', 'daytime', 'discard', 'domain',
                        'domain_u', 'echo', 'eco_i', 'ecr_i', 'efs', 'exec', 'finger', 'ftp', 'ftp_data', 'gopher',
                        'hostnames', 'http', 'http_443', 'icmp', 'imap4', 'iso_tsap', 'klogin', 'kshell', 'ldap', 'link',
                        'login', 'mtp', 'name', 'netbios_dgm', 'netbios_ns', 'netbios_ssn', 'netstat', 'nnsp', 'nntp',
                        'ntp_u', 'other', 'pm_dump', 'pop_2', 'pop_3', 'printer', 'private', 'red_i', 'remote_job', 'rje',
                        'shell', 'smtp', 'sql_net', 'ssh', 'sunrpc', 'supdup', 'systat', 'telnet', 'tftp_u', 'tim_i',
                        'time', 'urh_i', 'urp_i', 'uucp', 'uucp_path', 'vmnet', 'whois']
        flag_type = ['OTH', 'REJ', 'RSTO', 'RSTOS0', 'RSTR', 'S0', 'S1', 'S2', 'S3', 'SF', 'SH']
        train_label_type = ['back.', 'buffer_overflow.', 'ftp_write.', 'guess_passwd.', 'imap.', 'ipsweep.', 'land.',
                            'loadmodule.', 'multihop.', 'neptune.', 'nmap.', 'normal.', 'perl.', 'phf.', 'pod.',
                            'portsweep.', 'rootkit.', 'satan.', 'smurf.', 'spy.', 'teardrop.', 'warezclient.',
                            'warezmaster.']
        test_label_type = ['apache2.', 'back.', 'buffer_overflow.', 'ftp_write.', 'guess_passwd.', 'httptunnel.', 'imap.',
                           'ipsweep.', 'land.', 'loadmodule.', 'mailbomb.', 'mscan.', 'multihop.', 'named.', 'neptune.',
                           'nmap.', 'normal.', 'perl.', 'phf.', 'pod.', 'portsweep.', 'processtable.', 'ps.', 'rootkit.',
                           'saint.', 'satan.', 'sendmail.', 'smurf.', 'snmpgetattack.', 'snmpguess.', 'sqlattack.',
                           'teardrop.', 'udpstorm.', 'warezmaster.', 'worm.', 'xlock.', 'xsnoop.', 'xterm.']
        label_type = [['normal.'],
                      ['ipsweep.', 'mscan.', 'nmap.', 'portsweep.', 'saint.', 'satan.'],
                      ['apache2.', 'back.', 'land.', 'mailbomb.', 'neptune.', 'pod.', 'processtable.', 'smurf.', 'teardrop.', 'udpstorm.'],
                      ['buffer_overflow.', 'httptunnel.', 'loadmodule.', 'perl.', 'ps.', 'rootkit.', 'sqlattack.', 'xterm.'],
                      ['ftp_write.', 'guess_passwd.', 'imap.', 'multihop.', 'named.', 'phf.', 'sendmail.', 'snmpgetattack.',
                       'snmpguess.', 'spy.', 'warezclient.', 'warezmaster.', 'worm.', 'xlock.', 'xsnoop.']]
        return protocol_type,service_type,flag_type,label_type

    特别注意的是,在label中,我们采用前面所提的博客中的分类方法,只分类为5个类,因为如果分类太多太细的话会导致某些类的训练数据太少而根本不能fit到它。当然,有兴趣的也可以试一下。

    接下来是真正的数据处理了:

    def handle_data():
        protocol_type,service_type,flag_type,label_type = get_col_types()
        source_file = 'kddcup.data_10_percent_corrected'
        handled_file = 'train_data.csv'  # write to csv file
        data_file = open(handled_file, 'w', newline='')
        csv_writer = csv.writer(data_file)
        with open(source_file, 'r') as data_source:
            csv_reader = csv.reader(data_source)
            for row in csv_reader:
                row[1] = protocol_type.index(row[1])
                row[2] = service_type.index(row[2])
                row[3] = flag_type.index(row[3])
                for labels in label_type:
                    if labels.count(row[-1])>0:
                        row[-1] = label_type.index(labels)
                csv_writer.writerow(row)
            data_file.close()
        test_source_file = 'corrected'
        test_handled_file = 'test_data.csv'  # write to csv file
        test_data_file = open(test_handled_file, 'w', newline='')
        test_csv_writer = csv.writer(test_data_file)
        with open(test_source_file, 'r') as data_source:
            csv_reader = csv.reader(data_source)
            for row in csv_reader:
                row[1] = protocol_type.index(row[1])
                row[2] = service_type.index(row[2])
                row[3] = flag_type.index(row[3])
                for labels in label_type:
                    if labels.count(row[-1]) > 0:
                        row[-1] = label_type.index(labels)
                test_csv_writer.writerow(row)
            test_data_file.close()
        print('pre process completed!')

    handle_data后,数据将会由下面这样:

    变成下面这样:

    好了,这是第一步预处理。但是数据有的范围很大有的很小的问题仍然容易导致训练失败。所以,我们对数据进行一次归一化。

        def normalization(self,minibatch):
            data = np.delete(minibatch, -1, axis=1)
            labels = np.array(minibatch,dtype=np.int32)[:, -1]
            mmax = np.max(data, axis=0)
            mmin = np.min(data, axis=0)
            for i in range(len(mmax)):
                if mmax[i] == mmin[i]:
                    mmax[i] += 0.000001     # avoid getting devided by 0
            res = (data - mmin) / (mmax - mmin)
            res = np.c_[res,labels]
            return res

    归一化中需要避免max和min相同的情况,实际上数据中真的出现了这种情况,所以我们在遇到这种情况时将max加上了0.000001,这是为了避免除以0的情况,但是其实加几都是全0因为data和min是一样的所以不是很重要。

    这样,我们的预处理基本就完成了。现在开始第二个问题,训练。

    2.2 模型训练和预测

    在训练中,我们建立一个3层的全连接,并且经过relu和dropout,这是其中比较简单的一部分了。所以将直接给出代码。

    # train the network and use the model to predict the test set
    import tensorflow as tf
    import numpy as np
    import csv,os,random
    
    # Hyper Parameters
    LEARNING_RATE = 0.0001
    BATCH_SIZE = 32
    DATA_DIM = 41
    NUM_HIDDEN1_NODES = 32
    NUM_HIDDEN2_NODES = 64
    NUM_HIDDEN3_NODES = 64
    OUTPUT_DIM = 5
    MODEL_SAVE_PATH = './model/'
    MODEL_NAME = 'kdd_model'
    KEEP_PROB = 0.5
    
    class DNN():
        def __init__(self):
            self.learning_rate = LEARNING_RATE
            self.batch_size = BATCH_SIZE
            self.x_input = tf.placeholder(dtype=tf.float32,shape=[None,DATA_DIM])
            self.target = tf.placeholder(dtype=tf.int32,shape=[None])
            self.train_step = tf.Variable(0,trainable=False)
    
            self.init_data()
            self.create_DNN()
            self.build_loss()
    
            self.sess = tf.Session()
            self.sess.run(tf.global_variables_initializer())
    
            self.ckpt = tf.train.get_checkpoint_state(MODEL_SAVE_PATH)
            self.saver = tf.train.Saver()
            self.train_start = 0
            if self.ckpt and self.ckpt.model_checkpoint_path:
                self.saver.restore(self.sess,self.ckpt.model_checkpoint_path)
                self.train_start = self.sess.run(self.train_step)
    
        def create_DNN(self):
            w1 = tf.Variable(tf.truncated_normal(dtype=tf.float32,shape=[DATA_DIM,NUM_HIDDEN1_NODES],stddev=0.1))
            b1 = tf.Variable(tf.constant(0.1,dtype=tf.float32,shape=[NUM_HIDDEN1_NODES]))
            w2 = tf.Variable(tf.truncated_normal(dtype=tf.float32,shape=[NUM_HIDDEN1_NODES,NUM_HIDDEN2_NODES],stddev=0.1))
            b2 = tf.Variable(tf.constant(0.1,dtype=tf.float32,shape=[NUM_HIDDEN2_NODES]))
            w3 = tf.Variable(tf.truncated_normal(dtype=tf.float32,shape=[NUM_HIDDEN2_NODES,NUM_HIDDEN3_NODES],stddev=0.1))
            b3 = tf.Variable(tf.constant(0.1, dtype=tf.float32, shape=[NUM_HIDDEN3_NODES]))
            w4 = tf.Variable(tf.truncated_normal(dtype=tf.float32, shape=[NUM_HIDDEN3_NODES, OUTPUT_DIM], stddev=0.1))
            b4 = tf.Variable(tf.constant(0.1, dtype=tf.float32, shape=[OUTPUT_DIM]))
            h_layer = tf.nn.relu(tf.nn.dropout(tf.matmul(self.x_input,w1)+b1,KEEP_PROB))
            h_layer2 = tf.nn.relu(tf.nn.dropout(tf.matmul(h_layer,w2)+b2,KEEP_PROB))
            h_layer3 = tf.nn.relu(tf.matmul(h_layer2,w3)+b3)
            self.y = tf.nn.softmax(tf.matmul(h_layer3,w4)+b4)
    
        def build_loss(self):
            ce = tf.nn.sparse_softmax_cross_entropy_with_logits(logits=self.y, labels=self.target)
            self.loss = tf.reduce_sum(ce)       # tf.reduce_mean()
            self.train_op = tf.train.AdamOptimizer(self.learning_rate).minimize(self.loss,global_step=self.train_step)
    
    
        def train(self):
            step = self.sess.run(self.train_step)
            batch = self.get_a_train_batch(step)
            data,label = self.get_data_label(batch)
            _,y = self.sess.run([self.train_op,self.y], feed_dict={self.x_input: data, self.target: label})
            if (step+1) % 1000 == 0:
                # print(label)
                curr_loss,y = self.sess.run([self.loss,self.y], feed_dict={self.x_input: data, self.target: label})
                # print(y[0])
                print('trained {} rounds, current loss: {}'.format(step+1, curr_loss))
                self.saver.save(self.sess, os.path.join(MODEL_SAVE_PATH, MODEL_NAME), global_step=step+1)
    
    
        def get_a_train_batch(self,step):
            step = step%int(self.train_length/BATCH_SIZE)
            min = step*BATCH_SIZE
            max = min+BATCH_SIZE-1
            return self.train_data[int(min):int(max+1)]
    
    
        def get_data_label(self,batch):
            data = np.delete(batch, -1, axis=1)
            label = np.array(batch,dtype=np.int32)[:, -1]
            return data,label
    
    
        def init_data(self):
            self.train_data = []
            self.test_data = []        # init train and test data
            self.label_status = {}
            filename = 'train_data.csv'
            csv_reader = csv.reader(open(filename))
            label0_data = []
            label1_data = []
            label2_data = []
            label3_data = []
            label4_data = []
            for row in csv_reader:
                data = []
                for char in row:
                    if char=='None':
                        data.append(0)
                    else:
                        data.append(np.float32(char))       # transform data from format of string to float32
                if data[-1] == 0:
                    label0_data.append(data)
                if data[-1] == 1:
                    label1_data.append(data)
                if data[-1] == 2:
                    label2_data.append(data)
                if data[-1] == 3:
                    label3_data.append(data)
                if data[-1] == 4:
                    label4_data.append(data)
                if self.label_status.get(str(int(data[-1])),0)>0:
                    self.label_status[str(int(data[-1]))] += 1
                else:
                    self.label_status[str(int(data[-1]))] = 1
            while len(label0_data) < 10000:
                label0_data = label0_data + label0_data
            label0_data = random.sample(label0_data, 10000)
            while len(label1_data) < 10000:
                label1_data = label1_data + label1_data
            label1_data = random.sample(label1_data, 10000)
            while len(label2_data) < 10000:
                label2_data = label2_data + label2_data
            label2_data = random.sample(label2_data, 10000)
            while len(label3_data) < 10000:
                label3_data = label3_data + label3_data
            label3_data = random.sample(label3_data, 10000)
            while len(label4_data) < 10000:
                label4_data = label4_data + label4_data
            label4_data = random.sample(label4_data, 10000)
            self.train_data = label0_data+label1_data+label2_data+label3_data+label4_data
            filename = 'test_data.csv'
            csv_reader = csv.reader(open(filename))
            for row in csv_reader:
                data = []
                for char in row:
                    if char=='None':
                        data.append(0)
                    else:
                        data.append(np.float32(char))       # transform data from format of string to float32
                self.test_data.append(data)
            self.train_length = len(self.train_data)
            self.test_length = len(self.test_data)
            self.train_data = self.normalization(self.train_data)
            self.test_data = self.normalization(self.test_data)
            np.random.shuffle(self.train_data)
            print('init data completed!')
    
    
        def normalization(self,minibatch):
            data = np.delete(minibatch, -1, axis=1)
            labels = np.array(minibatch,dtype=np.int32)[:, -1]
            mmax = np.max(data, axis=0)
            mmin = np.min(data, axis=0)
            for i in range(len(mmax)):
                if mmax[i] == mmin[i]:
                    mmax[i] += 0.000001     # avoid getting devided by 0
            res = (data - mmin) / (mmax - mmin)
            res = np.c_[res,labels]
            return res
    
    
        def predict(self,x_feature):
            predict = self.sess.run(self.y,feed_dict={self.x_input:[x_feature]})[0]
            classLabel = np.argmax(predict)
            return classLabel
    
    
        def test(self):
            length = len(self.test_data)
            rightNum = 0
            np.random.shuffle(self.test_data)
            for row in self.test_data:
                feature = row[0:-1]
                label = row[-1]
                x_feature = np.array(feature)
                classLabel = self.predict(x_feature)
                if label == classLabel:
                    rightNum += 1
            accuracy = rightNum/length
            return accuracy
    
    
    if __name__ == '__main__':
        dnn = DNN()
        print('the number of training data: ',dnn.train_length)
        print('the number of test data: ',dnn.test_length)
        print('the training data status : ',dnn.label_status)
        print('start training...')
        for i in range(dnn.train_start, 20000):
            dnn.train()
        print('start testing...')
        accuracy = dnn.test()
        per = accuracy*100
        print('the accuracy on test data:  ','%.4f'%(per),'%')

    整体代码中比较关键的几点:

    init_data中对数据做了一个均衡,使每一个标签的数据都有10000条,这是很简单的暴力增广和采样,虽然丢失了很多数据,但是使训练数据相对均衡,不至于模型直接坍塌到0和2两个分类。标签为3的数据只有52个,即使增广,意义也不大,因为特征很难提取出来,可以直接舍弃这部分数据。测试中发现有没有这些数据其实差别不是很大。

    采用类的构造方式,这是比较常用的代码风格。

    build_loss中使用reduce_sum和reduce_mean差别不是很大,可以调节不同的学习率去测试体会其中的差距。reduce_mean是比较标准的交叉熵。

    整体代码的流程就是:

    从csv中读取数据;

    对各个标签的数据进行增广、采样,各取10000条放入训练集;

    打乱训练集;

    每次取一个batch进行训练;

    测试。

     

    展开全文
    qq_35733521 2019-02-25 09:25:17
  • 入侵检测KDD99数据集预处理onehot编码(分为5类)归一化(matlab代码) KDD99数据集预处理 使用onehot编码方式进行编码(python实现),并归一化(matlab),matlab可以实现并行处理,速度快。 onehot编码(分为5类...

    KDD99数据集预处理

    使用onehot编码方式进行编码(python实现),并归一化(matlab),matlab可以实现并行处理,速度快。

    onehot编码(分为5类)

    # kdd99数据集预处理
    # 将kdd99符号型数据转化为数值型数据
    
    # coding:utf-8
    
    import numpy as np
    import pandas as pd
    import csv
    import time
    
    global labe
    展开全文
    weixin_37870244 2021-03-30 18:03:40
  • 2.66MB smileyan9 2021-08-07 16:38:14
  • 30.62MB fujianfafu 2018-05-21 10:40:49
  • KDD是数据挖掘与知识发现(Data Mining and Knowledge Discovery)的简称,KDD CUP是由ACM(Association for Computing Machiner)的 SIGKDD(Special Interest Group on Knowledge Discovery and ...

    背景知识

    KDD是数据挖掘与知识发现(Data Mining and Knowledge Discovery)的简称,KDD CUP是由ACM(Association for Computing Machiner)的 SIGKDD(Special Interest Group on Knowledge Discovery and Data Mining)组织的年度竞赛。竞赛主页在这里

    下面是历届KDDCUP的题目:

    KDD-Cup 2008, Breast cancer
    KDD-Cup 2007, Consumer recommendations
    KDD-Cup 2006, Pulmonary embolisms detection from image data
    KDD-Cup 2005, Internet user search query categorization
    KDD-Cup 2004, Particle physics; plus Protein homology prediction
    KDD-Cup 2003, Network mining and usage log analysis
    KDD-Cup 2002, BioMed document; plus Gene role classification
    KDD-Cup 2001, Molecular bioactivity; plus Protein locale prediction.
    KDD-Cup 2000, Online retailer website clickstream analysis
    KDD-Cup 1999, Computer network intrusion detection
    KDD-Cup 1998, Direct marketing for profit optimization
    KDD-Cup 1997, Direct marketing for lift curve optimization

    ”KDD CUP 99 dataset ”就是KDD竞赛在1999年举行时采用的数据集。从这里下载KDD99数据集。

    1998年美国国防部高级规划署(DARPA)在MIT林肯实验室进行了一项入侵检测评估项目。林肯实验室建立了模拟美国空军局域网的一个网络环境,收集了9周时间的 TCPdump(*) 网络连接和系统审计数据,仿真各种用户类型、各种不同的网络流量和攻击手段,使它就像一个真实的网络环境。这些TCPdump采集的原始数据被分为两个部分:7周时间的训练数据 (**) 大概包含5,000,000多个网络连接记录,剩下的2周时间的测试数据大概包含2,000,000个网络连接记录。

    一个网络连接定义为在某个时间内从开始到结束的TCP数据包序列,并且在这段时间内,数据在预定义的协议下(如TCP、UDP)从源IP地址到目的IP地址的传递。每个网络连接被标记为正常(normal)或异常(attack),异常类型被细分为4大类共39种攻击类型,其中22种攻击类型出现在训练集中,另有17种未知攻击类型出现在测试集中。

    4种异常类型分别是:

    1. DOS, denial-of-service. 拒绝服务攻击,例如ping-of-death, syn flood, smurf等;
    2. R2L, unauthorized access from a remote machine to a local machine. 来自远程主机的未授权访问,例如guessing password;
    3. U2R, unauthorized access to local superuser privileges by a local unpivileged user. 未授权的本地超级用户特权访问,例如buffer overflow attacks;
    4. PROBING, surveillance and probing, 端口监视或扫描,例如port-scan, ping-sweep等。

    随后来自哥伦比亚大学的Sal Stolfo 教授和来自北卡罗莱纳州立大学的 Wenke Lee 教授采用数据挖掘等技术对以上的数据集进行特征分析和数据预处理,形成了一个新的数据集。该数据集用于1999年举行的KDD CUP竞赛中,成为著名的KDD99数据集。虽然年代有些久远,但KDD99数据集仍然是网络入侵检测领域的事实Benckmark,为基于计算智能的网络入侵检测研究奠定基础。


    数据特征描述


    KDD99数据集中每个连接(*)用41个特征来描述:

    2, tcp, smtp, SF, 1684, 363, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0.00, 0.00, 0.00, 0.00, 1.00, 0.00, 0.00, 104, 66, 0.63, 0.03, 0.01, 0.00, 0.00, 0.00, 0.00, 0.00, normal.


    0, tcp, private, REJ, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 38, 1, 0.00, 0.00, 1.00, 1.00, 0.03, 0.55, 0.00, 208, 1, 0.00, 0.11, 0.18, 0.00, 0.01, 0.00, 0.42, 1.00, portsweep.


    0, tcp, smtp, SF, 787, 329, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0.00, 0.00, 0.00, 0.00, 1.00, 0.00, 0.00, 76, 117, 0.49, 0.08, 0.01, 0.02, 0.00, 0.00, 0.00, 0.00, normal.


    上面是数据集中的3条记录,以CSV格式写成,加上最后的标记(label),一共有42项,其中前41项特征分为4大类,下面按顺序解释各个特征的含义:

    1. TCP连接基本特征(共9种)

    基本连接特征包含了一些连接的基本属性,如连续时间,协议类型,传送的字节数等。

    (1)duration. 连接持续时间,以秒为单位,连续类型。范围是 [0, 58329] 。它的定义是从TCP连接以3次握手建立算起,到FIN/ACK连接结束为止的时间;若为UDP协议类型,则将每个UDP数据包作为一条连接。数据集中出现大量的duration = 0 的情况,是因为该条连接的持续时间不足1秒。

    (2)protocol_type. 协议类型,离散类型,共有3种:TCP, UDP, ICMP。

    (3)service. 目标主机的网络服务类型,离散类型,共有70种。’aol’, ‘auth’, ‘bgp’, ‘courier’, ‘csnet_ns’, ‘ctf’, ‘daytime’, ‘discard’, ‘domain’, ‘domain_u’, ‘echo’, ‘eco_i’, ‘ecr_i’, ‘efs’, ‘exec’, ‘finger’, ‘ftp’, ‘ftp_data’, ‘gopher’, ‘harvest’, ‘hostnames’, ‘http’, ‘http_2784′, ‘http_443′, ‘http_8001′, ‘imap4′, ‘IRC’, ‘iso_tsap’, ‘klogin’, ‘kshell’, ‘ldap’, ‘link’, ‘login’, ‘mtp’, ‘name’, ‘netbios_dgm’, ‘netbios_ns’, ‘netbios_ssn’, ‘netstat’, ‘nnsp’, ‘nntp’, ‘ntp_u’, ‘other’, ‘pm_dump’, ‘pop_2′, ‘pop_3′, ‘printer’, ‘private’, ‘red_i’, ‘remote_job’, ‘rje’, ‘shell’, ‘smtp’, ‘sql_net’, ‘ssh’, ‘sunrpc’, ‘supdup’, ‘systat’, ‘telnet’, ‘tftp_u’, ‘tim_i’, ‘time’, ‘urh_i’, ‘urp_i’, ‘uucp’, ‘uucp_path’, ‘vmnet’, ‘whois’, ‘X11′, ‘Z39_50′。

    (4)flag. 连接正常或错误的状态,离散类型,共11种。’OTH’, ‘REJ’, ‘RSTO’, ‘RSTOS0′, ‘RSTR’, ‘S0′, ‘S1′, ‘S2′, ‘S3′, ‘SF’, ‘SH’。它表示该连接是否按照协议要求开始或完成。例如SF表示连接正常建立并终止;S0表示只接到了SYN请求数据包,而没有后面的SYN/ACK。其中SF表示正常,其他10种都是error。

    (5)src_bytes. 从源主机到目标主机的数据的字节数,连续类型,范围是 [0, 1379963888]。

    (6)dst_bytes. 从目标主机到源主机的数据的字节数,连续类型,范围是 [0. 1309937401]。

    (7)land. 若连接来自/送达同一个主机/端口则为1,否则为0,离散类型,0或1。

    (8)wrong_fragment. 错误分段的数量,连续类型,范围是 [0, 3]。

    (9)urgent. 加急包的个数,连续类型,范围是[0, 14]。

    2. TCP连接的内容特征(共13种)

    对于U2R和R2L之类的攻击,由于它们不像DoS攻击那样在数据记录中具有频繁序列模式,而一般都是嵌入在数据包的数据负载里面,单一的数据包和正常连接没有什么区别。为了检测这类攻击,Wenke Lee等从数据内容里面抽取了部分可能反映入侵行为的内容特征,如登录失败的次数等。

    (10)hot. 访问系统敏感文件和目录的次数,连续,范围是 [0, 101]。例如访问系统目录,建立或执行程序等。

    (11)num_failed_logins. 登录尝试失败的次数。连续,[0, 5]。

    (12)logged_in. 成功登录则为1,否则为0,离散,0或1。

    (13)num_compromised. compromised条件(**)出现的次数,连续,[0, 7479]。

    (14)root_shell. 若获得root shell 则为1,否则为0,离散,0或1。root_shell是指获得超级用户权限。

    (15)su_attempted. 若出现”su root” 命令则为1,否则为0,离散,0或1。

    (16)num_root. root用户访问次数,连续,[0, 7468]。

    (17)num_file_creations. 文件创建操作的次数,连续,[0, 100]。

    (18)num_shells. 使用shell命令的次数,连续,[0, 5]。

    (19)num_access_files. 访问控制文件的次数,连续,[0, 9]。例如对 /etc/passwd 或 .rhosts 文件的访问。

    (20)num_outbound_cmds. 一个FTP会话中出站连接的次数,连续,0。数据集中这一特征出现次数为0。

    (21)is_hot_login.登录是否属于“hot”列表(***),是为1,否则为0,离散,0或1。例如超级用户或管理员登录。

    (22)is_guest_login. 若是guest 登录则为1,否则为0,离散,0或1。

    3. 基于时间的网络流量统计特征 (共9种,23~31)

    由于网络攻击事件在时间上有很强的关联性,因此统计出当前连接记录与之前一段时间内的连接记录之间存在的某些联系,可以更好的反映连接之间的关系。这类特征又分为两种集合:一个是 “same host”特征,只观察在过去两秒内与当前连接有相同目标主机的连接,例如相同的连接数,在这些相同连接与当前连接有相同的服务的连接等等;另一个是 “same service”特征,只观察过去两秒内与当前连接有相同服务的连接,例如这样的连接有多少个,其中有多少出现SYN错误或者REJ错误。

    (23)count. 过去两秒内,与当前连接具有相同的目标主机的连接数,连续,[0, 511]。

    (24)srv_count. 过去两秒内,与当前连接具有相同服务的连接数,连续,[0, 511]。

    (25)serror_rate. 过去两秒内,在与当前连接具有相同目标主机的连接中,出现“SYN” 错误的连接的百分比,连续,[0.00, 1.00]。

    (26)srv_serror_rate. 过去两秒内,在与当前连接具有相同服务的连接中,出现“SYN” 错误的连接的百分比,连续,[0.00, 1.00]。

    (27)rerror_rate. 过去两秒内,在与当前连接具有相同目标主机的连接中,出现“REJ” 错误的连接的百分比,连续,[0.00, 1.00]。

    (28)srv_rerror_rate. 过去两秒内,在与当前连接具有相同服务的连接中,出现“REJ” 错误的连接的百分比,连续,[0.00, 1.00]。

    (29)same_srv_rate. 过去两秒内,在与当前连接具有相同目标主机的连接中,与当前连接具有相同服务的连接的百分比,连续,[0.00, 1.00]。

    (30)diff_srv_rate. 过去两秒内,在与当前连接具有相同目标主机的连接中,与当前连接具有不同服务的连接的百分比,连续,[0.00, 1.00]。

    (31)srv_diff_host_rate. 过去两秒内,在与当前连接具有相同服务的连接中,与当前连接具有不同目标主机的连接的百分比,连续,[0.00, 1.00]。

    注:这一大类特征中,23、25、27、29、30这5个特征是 “same host” 特征,前提都是与当前连接具有相同目标主机的连接;24、26、28、31这4个特征是 “same service” 特征,前提都是与当前连接具有相同服务的连接。

    4. 基于主机的网络流量统计特征 (共10种,32~41)

    基于时间的流量统计只是在过去两秒的范围内统计与当前连接之间的关系,而在实际入侵中,有些 Probing攻击使用慢速攻击模式来扫描主机或端口,当它们扫描的频率大于2秒的时候,基于时间的统计方法就无法从数据中找到关联。所以Wenke Lee等按照目标主机进行分类,使用一个具有100个连接的时间窗,统计当前连接之前100个连接记录中与当前连接具有相同目标主机的统计信息。

    (32)dst_host_count. 前100个连接中,与当前连接具有相同目标主机的连接数,连续,[0, 255]。

    (33)dst_host_srv_count. 前100个连接中,与当前连接具有相同目标主机相同服务的连接数,连续,[0, 255]。

    (34)dst_host_same_srv_rate. 前100个连接中,与当前连接具有相同目标主机相同服务的连接所占的百分比,连续,[0.00, 1.00]。

    (35)dst_host_diff_srv_rate. 前100个连接中,与当前连接具有相同目标主机不同服务的连接所占的百分比,连续,[0.00, 1.00]。

    (36)dst_host_same_src_port_rate.前100个连接中,与当前连接具有相同目标主机相同源端口的连接所占的百分比,连续,[0.00, 1.00]。

    (37)dst_host_srv_diff_host_rate.前100个连接中,与当前连接具有相同目标主机相同服务的连接中,与当前连接具有不同源主机的连接所占的百分比,连续,[0.00, 1.00]。

    (38)dst_host_serror_rate. 前100个连接中,与当前连接具有相同目标主机的连接中,出现SYN错误的连接所占的百分比,连续,[0.00, 1.00]。

    (39)dst_host_srv_serror_rate.前100个连接中,与当前连接具有相同目标主机相同服务的连接中,出现SYN错误的连接所占的百分比,连续,[0.00, 1.00]。

    (40)dst_host_rerror_rate.前100个连接中,与当前连接具有相同目标主机的连接中,出现REJ错误的连接所占的百分比,连续,[0.00, 1.00]。

    (41)dst_host_srv_rerror_rate. 前100个连接中,与当前连接具有相同目标主机相同服务的连接中,出现REJ错误的连接所占的百分比,连续,[0.00, 1.00]。


    样本分析

    前面提到KDD99数据集是由DARPA98数据集经过数据挖掘和预处理后得到的。但KDD99与DARPA98并不是一一对应的,Wende Lee等人在处理原始连接数据时将部分重复数据去除,例如进行DoS攻击时产生大量相同的连接记录,就只取攻击过程中5分钟内的连接记录作为该攻击类型的数据集。同时,也会随机抽取正常(normal)数据连接作为正常数据集。

    KDD99数据集总共由500万条记录构成,它还提供一个10%的训练子集和测试子集,它的样本类别分布表如下:

    标签类别训练集(10%)测试集(Corrected)
     39种攻击
    0NORMAL9727860593
    1PROBE41074166
     ipsweep1247306
     mscan/1053
     nmap23184
     portsweep1040354
     saint/736
     satan15891633
    2DOS391458229853
     apache2/794
     back22031098
     land219
     mailbomb/5000
     neptune10720158001
     pod26487
     processtable/759
     smurf280790164091
     teardrop97912
     udpstorm/2
    3U2R52228
     buffer_overflow3022
     httptunnel/158
     loadmodule92
     perl32
     ps/16
     rootkit1013
     sqlattack/2
     xterm/13
    4R2L112616189
     ftp_write83
     guess_passwd534367
     imap121
     multihop718
     named/17
     phf42
     sendmail/17
     snmpgetattack/7741
     snmpguess/2406
     spy2/
     warezclient1020/
     warezmaster201602
     worm/2
     xlock/9
     xsnoop/4
    1. 训练集和测试集分别为KDD99数据集中的10%训练样本和corrected 的测试样本;
    2. “/”表示该种攻击类型只在测试集(或训练集)中出现,而未在训练集(或测试集)中出现;

    如上表,同DARPA98一样,KDD99将攻击类型分为4类,然后又细分为39小类,每一类代表一种攻击类型,类型名被标记在训练数据集每一行记录的最后一项。

    从表中可以看出,训练集中共出现了22个攻击类型,而剩下的17种只在测试集中出现,这样设计的目的是检验分类器模型的泛化能力,对未知攻击类型的检测能力是评价入侵检测系统好坏的重要指标。


    应用和评价


    KDD 99数据集的应用

    建立KDD99数据集的目的就是为入侵检测系统提供统一的性能评价基准,它的应用一般局限在学术范围内,用来检验入侵检测算法的好坏。

    入侵检测的方法从根本上讲就是设计一个分类器,能将数据流中的正常与异常数据区分出来,从而实现对攻击行为的报警。通常的,我们将数据集中的的10%训练集来训练分类器,然后用corrected测试集测试分类器性能,这个分类器可以是基于贝叶斯的、决策树的、神经网络的或者是支持向量机的。有关分类器的设计,请自行google相关文献。

    特征选择是KDD99数据集的另一个主要应用。KDD99数据集中,每个连接有41个特征,对于一个分类器来说,要从这么多特征中提取规则是费时且不精确的,这体现在一些无关或冗余的特征往往会降低分类器模型的检测精度和速度。而且对于从原始的tcpdump数据中提取特征这一过程,也将是困难和费时的,这对于在线入侵检测系统是致命的。因此去除冗余特征或不重要特征,对于提高分类器训练速度和检测精度来说,是必要的。要说明的是对于不同的分类器来说,最优的特征子集可以是不同的。关于特征选择,以后写一篇文章详细介绍下。

    KDD 99数据集的评价

    前面说过,KDD 99数据集是入侵检测领域的事实Benchmark,为基于计算智能的网络入侵检测研究奠定了基础,从那以后很多学者开始研究入侵检测算法,当然不能不提到众所周知、臭名昭著的“功夫网”。实际上“功夫网”就是一个大规模的入侵检测系统,科技这把双刃剑在让我们远离恶意攻击的同时,也让我们离真相越来越远。

    不评论某墙,话说KDD99从1999年创建到2010年现在也有11个年头了,因为是98年做的实验,所以还得加1年,12年。12年过去,当年的实验条件和攻击手段放到今天早已过时,而且从原来的网络层攻击进化为针对应用层的攻击,例如跨站脚本、数据库注入等等(当然,针对应用层攻击自有新的解决方案)。你可以说,要解决这个问题,重新做一遍98年那个实验,用新的设备新的攻击手段,产生新的数据集不就行了吗?事实是据我所知还没有学术组织公开新的数据集,安全软件公司里肯定有足够的数据库,当然,人家是不会共享出来的,就靠这个赚钱了呗。另一个解决办法是你自己搭建网络环境,自己做实验,就是累点,当然可行。

    暂且不管数据新旧,KDD99数据集存在的一些原生的缺陷却不能被忽略。这里给出几篇介绍KDD99缺陷的文献,供大家参考:

    [1] The 1998 Lincoln Laboratory IDS Evaluation A Critique. by John McHugh

    [2] Testing Intrusion Detection Systems: A Critique of the 1998 and 1999 DARPA Intrusion Detection System Evaluations as Performed by Lincoln Laboratory. by John McHugh

    [3] The Comparison of IP Networks. by ST Brugger

    [4] KDD Cup ’99 dataset (Network Intrusion) considered harmful. by ST Brugger

    展开全文
    zhangtian6691844 2016-12-05 09:50:28
  • win_in_action 2019-08-20 21:50:20
  • qq_14998713 2018-04-12 14:04:48
  • 25.42MB turn_sole 2020-03-02 21:54:42
  • realmardrid 2020-11-28 23:45:00

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,769
精华内容 707
关键字:

kdd99

友情链接: CalendarDlg.rar