Parcourir la source

수정한 코드.

master
Hwanu il y a 4 ans
Parent
révision
e09924e592
1 fichiers modifiés avec 311 ajouts et 0 suppressions
  1. 311
    0
      HwanWooCode/prefix_1025.py

+ 311
- 0
HwanWooCode/prefix_1025.py Voir le fichier

@@ -0,0 +1,311 @@
1
+#!/usr/bin/env python
2
+# coding: utf-8
3
+
4
+# In[1]:
5
+
6
+
7
+import pandas as pd
8
+import numpy as np
9
+from mlxtend.preprocessing import TransactionEncoder
10
+from mlxtend.frequent_patterns import association_rules, fpgrowth
11
+from prefixspan import PrefixSpan
12
+
13
+
14
+
15
+df = pd.read_csv("ts_data_accident-2020_sample.csv", low_memory=False, encoding='ISO-8859-1')
16
+pd.set_option('display.max_columns',None)
17
+df=df[['RISK_V2','INST_NM','DRULE_ATT_TYPE_CODE1','TW_ATT_IP','TW_ATT_PORT','TW_DMG_IP','TW_DMG_PORT','ACCD_DMG_PROTO_NM','TW_ATT_CT_NM','ACCD_FIND_MTD_CODE','DRULE_NM']].dropna()
18
+len(df)
19
+##################### NTM section #####################
20
+NTM_df=df[df['ACCD_FIND_MTD_CODE']==1]
21
+NTM_df
22
+
23
+# Pick out it in order to get the asset, risk, intent, black IP out
24
+RISK_V2=NTM_df['RISK_V2']
25
+RISK_V2_FILTERED=RISK_V2.dropna()
26
+## 결측값 제거.
27
+
28
+import json
29
+from pandas import json_normalize
30
+
31
+# modified
32
+def get_asset_desc(asset_field):
33
+    if asset_field == 'ASSETS_VAL_1':
34
+        return '공인-전체IP대역(유선)'
35
+    elif asset_field == 'ASSETS_VAL_2':
36
+        return '공인-전체IP대역(무선)'
37
+    elif asset_field == 'ASSETS_VAL_3':
38
+        return '공인-WEB서버'
39
+    elif asset_field == 'ASSETS_VAL_4':
40
+        return '공인-내부응용서버'
41
+    elif asset_field == 'ASSETS_VAL_5':
42
+        return '공인-DB서버'
43
+    elif asset_field == 'ASSETS_VAL_6':
44
+        return '공인-패치서버'
45
+    elif asset_field == 'ASSETS_VAL_7':
46
+        return '공인-네트워크'
47
+    elif asset_field == 'ASSETS_VAL_8':
48
+        return '공인-보안'
49
+    elif asset_field == 'ASSETS_VAL_9':
50
+        return '공인-업무용PC'
51
+    elif asset_field == 'ASSETS_VAL_10':
52
+        return '공인-비업무용PC'
53
+    elif asset_field == 'ASSETS_VAL_11':
54
+        return '공인-기타'
55
+    elif asset_field == 'ASSETS_VAL_12':
56
+        return '사설-전체IP대역(유선)'
57
+    elif asset_field == 'ASSETS_VAL_13':
58
+        return '사설-전체IP대역(무선)'
59
+    elif asset_field == 'ASSETS_VAL_14':
60
+        return '사설-WEB서버'
61
+    elif asset_field == 'ASSETS_VAL_15':
62
+        return '사설-내부응용서버'
63
+    elif asset_field == 'ASSETS_VAL_16':
64
+        return '사설-DB서버'
65
+    elif asset_field == 'ASSETS_VAL_17':
66
+        return '사설-패치서버'
67
+    elif asset_field == 'ASSETS_VAL_18':
68
+        return '사설-네트워크'
69
+    elif asset_field == 'ASSETS_VAL_19':
70
+        return '사설-보안'
71
+    elif asset_field == 'ASSETS_VAL_20':
72
+        return '사설-업무용PC'
73
+    elif asset_field == 'ASSETS_VAL_21':
74
+        return '사설-비업무용PC'
75
+    elif asset_field == 'ASSETS_VAL_22':
76
+        return '사설-기타'
77
+    else:
78
+        return ''
79
+
80
+def get_intent_desc(intent_field):
81
+    if intent_field == 'INTENT_VAL_1':
82
+        return '파괴'
83
+    elif intent_field == 'INTENT_VAL_2':
84
+        return '유출'
85
+    elif intent_field == 'INTENT_VAL_3':
86
+        return '지연'
87
+    elif intent_field == 'INTENT_VAL_4':
88
+        return '잠복'
89
+    elif intent_field == 'INTENT_VAL_5':
90
+        return '단순침입'
91
+    elif intent_field == 'INTENT_VAL_6':
92
+        return 'MD5'
93
+    elif intent_field == 'INTENT_VAL_0':
94
+        return 'Default'
95
+    else:
96
+        return ''
97
+
98
+def get_source_desc(source_field):
99
+    if source_field=='SOURCE_VAL_1':
100
+        return '북한IP'
101
+    if source_field=='SOURCE_VAL_3':
102
+        return 'ECSC Black IP'
103
+    else:
104
+        return ''    
105
+# New assets column
106
+
107
+## ASSETS_VAL을 아예 JSON항목으로 만들어서 새로운 데이터프레임으로 생성.
108
+risk_df = pd.DataFrame()
109
+for risk in RISK_V2_FILTERED:
110
+    risk = risk.replace("'", "\"") #json으로 만들려고.
111
+    json_string = json.loads(risk)
112
+    json_df = json_normalize(json_string)
113
+    risk_df = pd.concat([risk_df,json_df],ignore_index=True)    #DataFrame 합쳐주기. ignore_index = True를 해야 index가 재구성 된다.
114
+risk_df_column_names = risk_df.columns
115
+
116
+assets_df = []
117
+intents_df = []
118
+sources_df = []
119
+def filter_all(risk):
120
+    for i in range(0,len(risk)):
121
+        risks=[]
122
+        intents=[]
123
+        sources=[]
124
+        for column in risk_df_column_names:
125
+            # filter_asset
126
+            if 'ASSETS_VAL_' in column and risk.iloc[i][column]:
127
+                risk_key_desc = 'RISK_V2.' + column + '=' + get_asset_desc(column)
128
+                risks.append(risk_key_desc)
129
+            
130
+            # filter_intent
131
+            if 'INTENT_VAL_' in column and risk.iloc[i][column]:
132
+                intent_key_desc = 'RISK_V2.' + column + '=' + get_intent_desc(column)
133
+                intents.append(intent_key_desc)
134
+                
135
+            if 'SOURCE_VAL_' in column and risk.iloc[i][column]:
136
+                source_key_desc='RISK_V2.' + column + '=' + get_source_desc(column)
137
+                sources.append(source_key_desc)
138
+        
139
+        assets_df.append(risks)
140
+        intents_df.append(intents)
141
+        sources_df.append(sources)
142
+        
143
+filter_all(risk_df)
144
+## 여기까지 내가 만든 것.
145
+
146
+NTM_df['ASSETS_VAL'] = assets_df
147
+NTM_df['ASSETS_VAL'] = NTM_df['ASSETS_VAL'].astype(str)
148
+NTM_df['ASSETS_VAL'] = NTM_df['ASSETS_VAL'].str.replace('[','',regex=True)
149
+NTM_df['ASSETS_VAL'] = NTM_df['ASSETS_VAL'].str.replace(']','',regex=True)
150
+NTM_df['ASSETS_VAL']
151
+
152
+NTM_df['INTENT_VAL'] = intents_df
153
+NTM_df['INTENT_VAL'] = NTM_df['INTENT_VAL'].astype(str)
154
+NTM_df['INTENT_VAL'] = NTM_df['INTENT_VAL'].str.replace('[','',regex=True)
155
+NTM_df['INTENT_VAL'] = NTM_df['INTENT_VAL'].str.replace(']','',regex=True)
156
+NTM_df['INTENT_VAL']
157
+
158
+NTM_df['SOURCE_VAL'] = sources_df
159
+NTM_df['SOURCE_VAL'] = NTM_df['SOURCE_VAL'].astype(str)
160
+NTM_df['SOURCE_VAL'] = NTM_df['SOURCE_VAL'].str.replace('[','',regex=True)
161
+NTM_df['SOURCE_VAL'] = NTM_df['SOURCE_VAL'].str.replace(']','',regex=True)
162
+NTM_df['SOURCE_VAL']
163
+NTM_df.drop(columns=['RISK_V2'], inplace=True)
164
+
165
+
166
+##################### 여기서부터 진행하시면 됩니다. #####################
167
+##################### 아래 12개 아이템(12. 장비 ACCD_FIND_MTD_CODE 제외)에 대해서 모든 아이템 조합에 알고리즘 적용하기#####################
168
+
169
+# It should be 13 columns in total
170
+
171
+# 1. 기관 INST_NM
172
+# 2. 공격 DRULE_ATT_TYPE_CODE1
173
+# 3. 자산 ASSETS_VAL
174
+# 4. 위협공격ip TW_ATT_IP
175
+# 5. 위협공격port TW_ATT_PORT
176
+# 6. 위협피해ip TW_DMG_IP
177
+# 7. 위협피해port TW_DMG_PORT
178
+# 8. 위협피해프로토콜 ACCD_DMG_PROTO_NM
179
+# 9. 공격국가 TW_ATT_CT_NM
180
+# 10. 의도(7개) INTENT_VAL
181
+# 11. IP/URL 가중치 SOURCE_VAL
182
+# 12. 장비 ACCD_FIND_MTD_CODE
183
+# 13. 탐지규칙명 DRULE_NM
184
+
185
+NTM_df.isna().sum()
186
+
187
+# Change the Nan to zero
188
+NTM_df['ACCD_DMG_PROTO_NM']=NTM_df['ACCD_DMG_PROTO_NM'].replace(np.nan,'')
189
+NTM_df['INST_NM']=NTM_df['INST_NM'].replace(np.nan,'')
190
+NTM_df['DRULE_ATT_TYPE_CODE1']=NTM_df['DRULE_ATT_TYPE_CODE1'].replace(np.nan,'')
191
+NTM_df['TW_ATT_IP']=NTM_df['TW_ATT_IP'].replace(np.nan,0)
192
+NTM_df['TW_ATT_PORT']=NTM_df['TW_ATT_PORT'].replace(np.nan,0)
193
+NTM_df['TW_DMG_IP']=NTM_df['TW_DMG_IP'].replace(np.nan,0)
194
+NTM_df['TW_DMG_PORT']=NTM_df['TW_DMG_PORT'].replace(np.nan,0)
195
+NTM_df['TW_ATT_CT_NM']=NTM_df['TW_ATT_CT_NM'].replace(np.nan,'')
196
+NTM_df['ASSETS_VAL']=NTM_df['ASSETS_VAL'].replace(np.nan,0)
197
+NTM_df['INTENT_VAL']=NTM_df['INTENT_VAL'].replace(np.nan,0)
198
+NTM_df['SOURCE_VAL']=NTM_df['SOURCE_VAL'].replace(np.nan,0)
199
+NTM_df['DRULE_NM']=NTM_df['DRULE_NM'].replace(np.nan,'')
200
+NTM_df['TW_ATT_IP']=NTM_df['TW_ATT_IP']
201
+NTM_df['TW_ATT_PORT']=NTM_df['TW_ATT_PORT']
202
+NTM_df['TW_DMG_IP']=NTM_df['TW_DMG_IP']
203
+NTM_df['TW_DMG_PORT']=NTM_df['TW_DMG_PORT']
204
+# Check NaN out again
205
+NTM_df.isna().sum()
206
+
207
+copy_df = NTM_df.copy() #원본도 안건드리고, 실행시킬 때마다 오류 떠서 copy로 하는게 좋을 것 같다.
208
+copy_df.drop(columns=['ACCD_FIND_MTD_CODE'],inplace=True)
209
+data_len = len(NTM_df)
210
+    
211
+# Combination
212
+import itertools
213
+
214
+# Combination 조합들 생성하는 함수. row마다 mCn 생성.
215
+def get_comb_df(df, n):
216
+    nCr = list(itertools.combinations(df.columns.tolist(),n))
217
+    nCr = [column for column in nCr if 'DRULE_ATT_TYPE_CODE1' in column]
218
+    ret_list = []
219
+    for l in range(2):
220
+        for i in range(50):
221
+            temp = []
222
+            temp_df = df.loc[i]
223
+            for col in nCr[l]:
224
+                new_string = col
225
+                new_string = new_string + ":" + str(temp_df[col])
226
+                temp.append(new_string)
227
+            ret_list.append(temp)
228
+    return ret_list                  
229
+
230
+# item들은 이 순서다.
231
+#item1 = 'INST_NM'
232
+#item2 = 'DRULE_ATT_TYPE_CODE1'
233
+#item3 = 'TW_ATT_IP'
234
+#item4 = 'TW_ATT_PORT'
235
+#item5 = 'TW_DMG_IP'
236
+#item6 = 'TW_DMG_PORT'
237
+#item7 = 'ACCD_DMG_PROTO_NM'
238
+#item8 = 'TW_ATT_CT_NM'
239
+#item9 = 'DRULE_NM'
240
+#item10 = 'ASSETS_VAL'
241
+#item11 = 'INTENT_VAL'
242
+#item12 = 'SOURCE_VAL'
243
+
244
+nonnull_list = []
245
+for i in range(0,data_len):
246
+    item1 = 'INST_NM:' + NTM_df.loc[i]['INST_NM']
247
+    item2 = 'DRULE_ATT_TYPE_CODE1:' + NTM_df.loc[i]['DRULE_ATT_TYPE_CODE1']
248
+    item3 = 'TW_ATT_IP:' + NTM_df.loc[i]['TW_ATT_IP'].astype(str)
249
+    item4 = 'TW_ATT_PORT:' + NTM_df.loc[i]['TW_ATT_PORT'].astype(str)
250
+    item5 = 'TW_DMG_IP:' + NTM_df.loc[i]['TW_DMG_IP'].astype(str)
251
+    item6 = 'TW_DMG_PORT:' + NTM_df.loc[i]['TW_DMG_PORT'].astype(str)
252
+    item7 = 'ACCD_DMG_PROTO_NM:' + NTM_df.loc[i]['ACCD_DMG_PROTO_NM']
253
+    item8 = 'TW_ATT_CT_NM:' + NTM_df.loc[i]['TW_ATT_CT_NM']
254
+    item9 = 'DRULE_NM:' + NTM_df.loc[i]['DRULE_NM']
255
+    item10 = NTM_df.loc[i]['ASSETS_VAL']
256
+    item11 = NTM_df.loc[i]['INTENT_VAL']
257
+    item12 = NTM_df.loc[i]['SOURCE_VAL']
258
+    not_null_arr = []
259
+    ## 리스트안에 빈 값을 빼버리자.
260
+    null_check_list = [item1,item2,item3,item4,item5,item6,item7,item8,item9,item10,item11,item12]
261
+    for item in null_check_list:
262
+        if item and item != '[]':
263
+            not_null_arr.append(item)
264
+    nonnull_list.append(not_null_arr)
265
+    
266
+get_comb_df(copy_df,9)
267
+
268
+def get_prefix_span(df_list, n): #n이상 길이를 갖는 규칙들만. 거기다가 Frequency기준 정렬 까지.
269
+    prefix_span = PrefixSpan(df_list)
270
+    n_ps = prefix_span.frequent(1,filter = lambda patt, matches:len(patt)>n)
271
+    ps_df = pd.DataFrame(n_ps)
272
+    ps_df.rename(columns={0:'Frequency', 1:'Cause'}, inplace=True)
273
+    ps_df['Effect']= np.nan
274
+    ps_df = ps_df[['Cause','Effect','Frequency']]
275
+    ps_sort_df = ps_df.sort_values(by=['Frequency'],ascending=False,ignore_index=True)
276
+    return ps_sort_df
277
+  
278
+test = get_prefix_span(nonnull_list,8)
279
+test
280
+
281
+# Define the function that find the rule name 
282
+# 데이터 크기를 줄여서 실행해본 결과 정상 작동함.
283
+def get_Effect(df):
284
+    for i in range(0,10000):
285
+        drules=['Attack','DDOS','HACK','MAIL','Malwr','WEB']
286
+        for item in df.loc[i,'Cause']:
287
+            for drule in drules:
288
+                drule_str = 'DRULE_ATT_TYPE_CODE1:' + drule
289
+                if item == drule_str:
290
+                    df.loc[i,'Effect'] = drule
291
+                    break         
292
+    return df                
293
+
294
+tdf = get_Effect(test)
295
+tdf.head(10000)	# 10000개로 했을 때, DRULE_ATT_TYPE_CODE 가 있는 항목들은 Effect정상 추출.
296
+
297
+# 정규표현식 사용해서 매칭하기.
298
+# 정규표현식 사용하는 틀. words에 배열만 넣으면 된다.
299
+tdf['Cause'] = [','.join(map(str, word))for word in tdf['Cause']]
300
+
301
+def regbase(words):
302
+    base = r'^{}'
303
+    expr = '(?=.*{})'
304
+    ret = base.format(''.join(expr.format(w) for w in words))
305
+    return ret
306
+
307
+def result(n):
308
+    comlist = get_comb_df(copy_df,n)
309
+    for i in range(0,len(comlist)):
310
+        print(comlist[i])
311
+        print(tdf[tdf['Cause'].str.contains(regbase(comlist[i]),na=False,regex=True)].reset_index(drop=True,inplace=False))

Chargement…
Annuler
Enregistrer