ML

보안log기반 SIEM내 중요 이벤트 가중치 계산(with stats 모델)

치타뱅뱅 2024. 11. 4. 12:27
728x90

재직시절 그룹사에 웹취약점 진단을 수행한 적이 있습니다.

한쪽은 공격, 한쪽은 방어(IP 차단 or 확인) 방식으로 진행되었었습니다.

이번엔 방어자 입장에서 해킹 시도 ip들을 안다고 가정하고 점수화 하는 방법을 했습니다.

 

<가설>

 - 해킹 or 의심 ip를 알고 해당 활동들을 역으로 SIEM의 애러로그별로 가중치를 계산한다.

 - 장점 : 유사한 방식의 해킹을 막을 수 있다.

 - 단점 : 다른 방식의 해킹시도시 SIEM 보안  log의 가중치가 바뀔 수 있다.

 

1. 서버 애러 로그 다운로드

 

server_error_logs.xlsx
0.05MB

 

2. 결과값

Optimization terminated successfully.
         Current function value: 0.018712
         Iterations 11
                           Logit Regression Results                           
==============================================================================
Dep. Variable:          is_suspicious   No. Observations:                 1000
Model:                          Logit   Df Residuals:                      997
Method:                           MLE   Df Model:                            2
Date:                Mon, 04 Nov 2024   Pseudo R-squ.:                 0.08376
Time:                        12:09:09   Log-Likelihood:                -18.712
converged:                       True   LL-Null:                       -20.423
Covariance Type:            nonrobust   LLR p-value:                    0.1808
=========================================================================================
                            coef    std err          z      P>|z|      [0.025      0.975]
-----------------------------------------------------------------------------------------
const                    -9.1237      2.489     -3.666      0.000     -14.002      -4.246
error_type_encoded        0.1900      0.241      0.787      0.431      -0.283       0.663
error_message_encoded     0.4642      0.322      1.444      0.149      -0.166       1.094
=========================================================================================
Error Type Scores: {'400 Bad Request': 1.9000513078756325, '401 Unauthorized': 1.9000513078756325, '403 Forbidden': 1.9000513078756325, '404 Not Found': 1.9000513078756325, '408 Request Timeout': 1.9000513078756325, '500 Internal Server Error': 1.9000513078756325, '502 Bad Gateway': 1.9000513078756325, '503 Service Unavailable': 1.9000513078756325, '504 Gateway Timeout': 1.9000513078756325}
Error Message Scores: {'Authentication failed': 4.6419486278281195, 'Database connection failed': 4.6419486278281195, 'Invalid request format': 4.6419486278281195, 'Permission denied': 4.6419486278281195, 'Remote server not responding': 4.6419486278281195, 'Resource not found': 4.6419486278281195, 'Service overloaded': 4.6419486278281195, 'Syntax error': 4.6419486278281195, 'Timeout reached': 4.6419486278281195}

  - 애러 타입과 애러 메세지 별 Score화 : ex) 400 Bad Request : 1.9점

  - 모두 p-value가 높게 나와 유의미하지는 않습니다. 만약 실제 보안 SIEM로그를 업로드하여 계산시 p-value가 0.05 미만으로 나올경우 유의미하며, 해킹 시도시에는 이벤트를 기반으로 일정한 선형 패턴을 보인다고 할 수 있습니다.

 

 

3. 방법

 

 #3.1 로그파일 및 의심 ip 설정

import pandas as pd
import statsmodels.api as sm
from sklearn.preprocessing import LabelEncoder

# 엑셀 파일 로드
file_path = r"본인의 파일위치 기재\server_error_logs.xlsx"
excel_data = pd.ExcelFile(file_path)

# 시트 로드
incident_df = pd.read_excel(excel_data, sheet_name='장애발생일지')
error_log_df = pd.read_excel(excel_data, sheet_name='error log')

# 의심스러운 IP 리스트
suspicious_ips = ["241.206.184.49", "26.189.99.59", "120.175.229.185"]

 

 #3.2 데이터 전처리 및 통계분석을 위한 인코딩
# 데이터 전처리: timestamp 및 레이블 생성
incident_df['timestamp'] = pd.to_datetime(incident_df['timestamp'])
error_log_df['timestamp'] = pd.to_datetime(error_log_df['timestamp'])
error_log_df['is_suspicious'] = error_log_df['ip_address'].apply(lambda x: 1 if x in suspicious_ips else 0)

# 에러 타입과 에러 메시지 인코딩
label_encoder_type = LabelEncoder()
label_encoder_message = LabelEncoder()
error_log_df['error_type_encoded'] = label_encoder_type.fit_transform(error_log_df['error_type'])
error_log_df['error_message_encoded'] = label_encoder_message.fit_transform(error_log_df['error_message'])

 

#3.3 가중치 기반 점수 계산(stats model 사용
# 독립 변수와 종속 변수 설정
X = error_log_df[['error_type_encoded', 'error_message_encoded']]
y = error_log_df['is_suspicious']

# 상수항 추가 및 모델 적합
X = sm.add_constant(X)
model = sm.Logit(y, X).fit()

# 결과 확인
print(model.summary())

# 각 에러 타입과 에러 메시지에 대해 점수를 계산
error_type_scores = {}
error_message_scores = {}

# error_type_encoded의 가중치
for i, error_type in enumerate(label_encoder_type.classes_):
    error_type_scores[error_type] = model.params[f'error_type_encoded'] * 10  # 가중치를 10배로 조정

# error_message_encoded의 가중치
for i, error_message in enumerate(label_encoder_message.classes_):
    error_message_scores[error_message] = model.params[f'error_message_encoded'] * 10  # 가중치를 10배로 조정

# 가중치 기반 점수 출력
print("Error Type Scores:", error_type_scores)
print("Error Message Scores:", error_message_scores)

 

 

감사합니다.