SK shieldus Rookies 9기/클라우드 기반 시스템 운영,구축 실무

시스템 운영/구축 실무 7일차 (22/11/01)

ksh_5 2022. 11. 1. 17:33
  • fields

 

- 검색 결과에서 특정 필드를 포함시키거나 제거 시 사용

- +는 기본값이므로 반드시 명시할 필요 없음

- 필드 추출하기 전에 동작하므로 검색 결과에서 원하는 필드만 선택 시 전체 검색 성능 높일 수 있음

 

 

  • split (X, "Y")

 

- 구분자 Y를 이용해서 X를 분할해 다중 값 형식으로 변환

- 구분자로 분리한 문자열은 여러 개의 토큰이 발생하므로 주로 mvindex()에서 사용

- 이벤트에서 특정 값 추출할 때 사용

 

 

  • mvindex (X, Y, Z)

 

- 필드 X에 있는 Y 번째 값 반환 (Z 생략가능)

- Y는 인덱스 번호 ( 0 : 첫 번째 값, -1 : 인덱스를 뒤에서 시작, -2 : 끝에서 두 번째)

- 세 번째 인자인 Z는 선택적으로 사용

   → Z값을 지정하면 함수는 Y부터 Z까지의 값 반환

 

 

  • substr (X, Y, Z)

 

- 세 번째 인자인 Z가 없다면 필드 X의 Y부터 시작해서 문자열 끝까지 반환

- Z가 주어지면 Y부터 Z개의 문자열 반환

 

 

 

 

 

  • round (X, Y)

- X를 Y 자리 수 기준으로 반올림

- 나누기 계산을 할 경우 소수점 자리가 급격히 늘어나는 것 방지

 

 

  • urldecode (X)

 

- URL 인코딩이 있는 X를 디코딩해 반환

- 웹 주소에 한글이 사용되는 경우 대부분 URL인코딩이 되어 바로 확인 힘듦

- 인코딩 문자열을 디코딩해서 한글이 있는 경우라도 바로 확인할 수 있음

 

 

  • strftime (X, Y)

 

- 유닉스 타임 X를 지정한 Y형식으로 출력

- 주로 사용자가 읽기 편한 형식으로 변환할 때 사용

- 유닉스 타임(에포크 타임) 계산법은 1970년 1월 1일 0시를 기준으로 초를 계산

 

 

  • striptime (X, Y)

 

- strftime과 반대로 Y형식으로 된 X 시간 문자열을 입력받아서 유닉스 타임을 반환

 

더보기

index=main sourcetype="access_combined_wcookie"
| eval unixtime=strptime(req_time,"%d/%B/%Y:%H:%M:%S") 
| eval humantime=strftime(unixtime,"%Y-/%m-/%d %H:%M:%S")
| table req_time, unixtime, humantime

 

 

index=main sourcetype="access_combined_wcookie" 
| eval unixtime=strptime(req_time,"%d/%B/%Y:%H:%M:%S") 
| eval date_diff=round((now()-unixtime)/86400,0)
| table req_time, date_diff

 

 

  • HTTP Log 실습환경 구성

 

❶ Index 만들기

더보기
인덱스 클릭

 

새 인덱스 이름 (HTTPLog) 적고 저장 클릭

 

httplog가 생성된 걸 확인

 

❷ SourceType 지정

더보기
Source Type 클릭

 

쉼표로 구분된 필드 이름에 [siem-http] 붙여 넣기

 

새 이름 (HTTPLog) , 인덱스 추출 tsv , 필드 이름 붙여넣고 저장 클릭

 

httplog가 생성된 걸 확인

 

❸ 데이터 추가

더보기
데이터 추가 클릭

 

업로드 내 컴퓨터의 파일 클릭

 

다운로드 받은 http.zip 파일 선택

 

Source type : 선택 > 사용자 지정 > HTTPLog 클릭

호스트 : ZeekIDS

인덱스 : httplog 선택

 

파일 업로드가 완료된다면 검색 시작 클릭

 

source="http.zip:*" host="ZeekIDS" index="httplog" sourcetype="HTTPLog"

 

 

  • URL Toolbox 설치

 

URL Toolbox | Splunkbase 

 

https://splunkbase.splunk.com/app/2734#/overview

 

splunkbase.splunk.com

 

더보기
앱 - 앱 관리 - 파일에서 앱 설치 클릭

 

파일 url-toolbox_192.tgz 선택 후 업로드

 

업로드한 url toolbox 확인 가능

 

개체 보기 클릭하면 나오는 설정들

 

 

  • HTTP 로그 필드

 

 

 

  • HTTP 네트워크 현황 분석

 

- 내부 인트라넷 서비스/ 인터넷 기반 서비스도 대부분 HTTP로 동작

- HTTP를 분석 시 목적지가 인터넷인지 인트라넷 서비스인지 구분 필요

- 공격자가 내부망에 침투했다면 중요 데이터의 외부 유출 시도

→ 따라서 목적지가 인터넷으로 향하는 HTTP인지 아니면 기업 내부망으로 향하는지가 중요한 기준이 될 수 있음

 

 

  • HTTP 네트워크 현황 분석 항목

 

❶ Top 10 접속 도메인, 국가별 접속

- 사용자들이 가장 많이 접속하는 도메인을 추출해서 접속 현황 분석

- 특정 도메인과 국가로 많은 데이터가 전송되거나 낯선 국가명 등을 모니터링

- 접속 국가 정보를 이상 징후의 주요 항목으로 사용

 

 

더보기

index=httplog sourcetype=httplog domain!="(empty)"

→ domain이라는 필드는 있지만 값이 없다
| iplocation dst

→ 목적지 IP인 dst 지역정보를 iplocation 명령어로 찾는다
| where NOT cidrmatch("0.0.0.0/0", domain)

→ 도메인이 IP주소가 아닌 것을 찾는다
| stats sum(request_body_len) as "Outbound", sum(response_body_len) as "Inbound" 
by domain, Country

→ 도메인, 국가명 기준으로 외부행, 내부행 전송량 모두 더해 Outbound, Inbound 필드명으로 저장
| eval Outbound=round(Outbound/(1024*1024),2)

→ Round 함수 이용해 소수점 2자리까지만 보여준다
| eval Inbound=round(Inbound/(1024*1024),2)
| sort Outbound desc

→ Outbound 필드 역순으로 정렬
| head 10

→ 총 10개 보여준다

 

 

❷ HTTP 메서드

- 클라이언트가 서버에 자원을 요청하는 방식

- 클라이언트는 서버에서 Get 또는 Post를 이용해서 자원 요청

- HTTP 표준에서는 많은 메서드를 지원하지만 사용자가 많이 사용하지 않는 메서드는 공격자의 정보 수집 행위 등 정상적인 사용 범위가 아닐 수 있음

 

uri!="-" Uri 필드 값이 “-”이 아닌 이벤트 검색
top method limit=10 showperc=f 상위 10개의 메서드 검색 각 값이 차지하는 비율 검색하지 않음

 

더보기
각 값이 차지하는 비율 검색

index=httplog sourcetype=httplog uri!="-"

→ uri 필드 값이 "-"이 아닌 이벤트 찾는다
| top method limit=10 showperc=f

→ 상위 10개의 메서드 찾고, 각 값이 차지하는 비율은 구하지 않는다

 

시각화

 

 

❸ Top 10 클라이언트 오류

- HTTP의 상태 코드는 클라이언트가 요청한 내용을 서버에서 처리한 결과

status_code >=400 AND status_code < 500 Status_Code가 400이상이거나 500미만인 이벤트 검색

 

더보기

index=httplog sourcetype=httplog uri!="-" uri!="/" 
(status_code >=400 AND status_code < 500)
| top domain, status_code limit=10 showperc=f

 

* status_code → 400 : 클라이언트 오류 , 403 : 접속 권한이 없는 사용자 접속 요청 , 404 : 요청한 자료 없음

 

 

❹ Top 10 서버 오류

- 클라이언트의 요청에 서버가 정상적으로 응답 못함

- 웹 응용프로그램이 비정상적으로 종료

 

더보기

index=httplog sourcetype=httplog uri!="-" status_code >= 500
| top domain, status_code limit=10 showperc=f

 

* status_code → 500 : 서버가 클라이언트 요청 처리 방법 모를 때 또는 서버 프로그램이 비정상적으로 동작할 때

503 : 서버가 요청을 처리할 준비가 되지 않음 (서버 과부하 등으로 서비스 이용)

 

 

❺ HTTP 상태 코드

- 전체 상태 코드의 현황

더보기

index=httplog sourcetype=httplog domain!="(empty)" status_code!="-" 
| top limit=10 showperc=f status_code

 

 

  • HTTP 이상징후

 

❶ 비정상 메서드 사용

- HTTP에서 메서드는 클라이언트가 서버에 데이터를 요청하는 방식

- Head, Delete, Trace, Option과 같은 메서드가 네트워크에서 지속적으로 보인다는 것은 정상적인 사용자의 활동이라 보기 어려움

 

더보기

index=httplog sourcetype=httplog
| stats count(method) by src

→ 송신지를 기준으로 접속에 사용한 메서드의 종류별 개수 검색

 

 

index=httplog sourcetype=httplog 
| stats count(eval(method="OPTIONS")) AS option_count by src 
| where option_count > 10 
| sort option_count desc

→ AS 키워드 사용해 count() 함수 필드명 option_count로 변경, 10번 이상 사용한 것을 역순으로 정렬

 

 

index=httplog sourcetype=httplog 
| where NOT match(method, "(GET|POST|-)")

→ GET, POST, 값이 설정되지 않은 것 결과
| stats count(src) as src_count by method

→ 메서드 별로 출발지 숫자 세서 결과 반환
| sort - src_count

→ 반환 결과 역순으로 추출

 

 

❷ 외부행 데이터 전송

- 업로드가 많은 사용자는 외부 데이터를 전송하는 것으로 판단

- 최소한 내부자료 유출을 파악할 수 있는 단서가 됨

- 대부분 사용자의 통신 유형은 다운로드 데이터 총량이 더 많음

- 업로드 데이터 총량이 크면 분모가 분자보다 크므로 계산 결과는 1보다 큰 값을 결과로 가짐 

- 결과 값이 1보다 큰 값이 나오는 출발지 주소와 목적지 주소 조사

 

더보기

→ 송신지와 수신지 별로 업로드 전송량(request_body_len)과 다운로드 전송량(response_body_len)의 총합 구함

 

index=httplog sourcetype=httplog
(request_body_len!=0 OR response_body_len!="0") domain!="-"

→ 전송량이 0인 이벤트와 domain이 명확하지 않은 이벤트 제거
| stats sum(request_body_len) as outTotal sum(response_body_len) as inTotal by src, dst

→ 출발지 목적지 별로 업로드 전송향과 다운로드 전송량의 총합 구함
| eval oMB=round(outTotal/(1024*1024),2) | eval iMB=round(inTotal/(1024*1024),2)

→ 총합 단위를 메가바이트로 변환, round 함수 이용해 소수점 두 자리로 변환
| search oMB!=0 AND iMB!=0 | iplocation dst

→ iplocation은 splunk가 지원하는 내부 명령어로 IP를 인자로 받아 지리 정보 반환
| eval isUp=if((oMB/iMB)>1, "Yes", "No") | where isUp="Yes"

→ isUP 필드가 Yes인 이벤트만 추출
| table src, dst, iMB, oMB, Country, City

→ 출발지, 목적지, 업로드 전송량, 다운로드 전송량, 국가, 도시 정보 보여줌

 

 

❸ Mime-type과 파일 확장자 불일치

- 전송하는 파일이 가진 속성

- Mime-type을 확인하면 전송 파일이 그림 파일인지, 문서 파일지 바로 파악 가능

- 확장자가 실행파일이 아닌 것을 찾아낸다면 공격자가 위장하는 정보라고 판별 가능

 

더보기

index=httplog sourcetype=httplog resp_mime_types="application/x-dosexec" uri!="-"
| eval filename1=mvindex(split(uri,"/"),-1)

→ split() 함수 이용해 uri필드를 '/'로 분할, -1 : 마지막 토큰
| eval filename=if(like(filename1,"%?%"), mvindex(split(filename1,"?"),0),filename1)

→ 추출한 uri에 '?'가 있는지 like 함수 이용해 검색, 있다면 '?'를 없다면 filename1을 추출
| eval filetype=if(match(filename,"(.exe|.bat|.ps1|.dll|.ocx)$"), "PE", "Not_PE")

→ filename의 문자열이 .exe, .bat, .psl, .dll, .ocx 중 하나로 끝나면 PE를 반환하고 아니면 Not_PE를 반환
| table domain, uri, filename, filetype, resp_mime_types

→ domain, uri, filename, filetype, resp_mime_types를 테이블 형태로 보여줌
| where filetype=="Not_PE"

→ 조건이 "Not_PE"만 추출
| dedup filename

→ filename 필드 중복 제거

 

 

❹ 사이트 이동 후 실행파일 다운로드

 

 

- 유포지로 유도하는 코드를 가진 웹 사이트를 악성코드 경유지라고 함

- 악성코드가 해당 웹 서버에 있는 경우도 있고, 다른 웹 페이지로 사용자의 접속을 유도하는 코드가 있을 수도 있음

 

* referrer

- 사용자가 브라우저에 직접 주소 입력하고 접속하면 이 필드 값은 존재하지 않음

- 다른 사이트의 유도에 의해 접속되었다는 것을 의미

 

 

더보기

index=httplog sourcetype=httplog referrer!="-" status_code=200

→ referrer 필드 값이 "-"이 아니고, 특정 값이 존재한단 의미, status_code가 200이란 것은 해당 접속이 성공적으로 동작했다는 의미

| eval filename1=mvindex(split(uri,"/"),-1)
| eval filename=if(like(filename1,"%?%"), mvindex(split(filename1,"?"),0),filename1)

→ uri에서 파일명을 추출하는 결과 처리 명령어

| where cidrmatch("0.0.0.0/0",domain)

→ 도메인이 IP 주소라는 것 의미
| where match(resp_mime_types,"application/x-dosexec") OR match(filename,"(exe|dll|com|src)$")

파일의 mime-types가 x-dosexce 형식이면서 파일의 확장자가 exe, dll, com, src인 경우를 찾는다
| eval URL=domain+" :: " + filename

→ 도메인 필드와 filename 필드를 연결해 URL이라는 필드에 할당
| stats count by src, URL

→ 출발지와 URL 기준으로 숫자 센다
| stats list(URL) as Target list(count) as Source by src

→ 출발지별로 접속한 URL의 개별적인 접속 수 보여줌

 

 

❺ 프록시 서버 접속

 

- 인터넷의 웹 서버를 접속할 때 사용하는 프락시는 불특정 다수에게 웹 사이트 접속을 빠르게 하는 캐시의 목적으로 사용하는 경우

- 기업 업무망에서 인터넷으로 향하는 네트워크에서 사용하는 프록시는 사용자 인증, 사용자 접속 제어 용도로도 사용

- 로그에서 메서드가 connect를 사용하면 목적지 서버는 프록시 서버라는 의미

 

더보기

index=httplog sourcetype=httplog (uri="http://*" OR method="connect") 
| table src, domain, uri

→ uri 필드 값이 http://로 시작하거나 method가 connect인 로그 찾으면 프록시 서버 접속 검색 가능

 

 

  • DNS

 

 

<<내부망 DNS 서버 로그 분석>>

- 내부용 DNS 서버는 내부 사용자가 인터넷 또는 내부 업무망을 접속 사용

- 공격자의 악성코드에 감염된 내부망 PC가 내부 데이터 획득을 목표로 활동하는 상황을 파악할 수 있음

→ 내부망 도메인의 집중 질의는 공격자가 내부는 탐색하는 내부망 이동 공격일 수 있음

→ 감염된 PC가 인터넷에 위치한 C2(Command&Control) 서버에 접속할 수 있음

 

 

  • DNS 실습 환경

 

더보기
인덱스 클릭

 

새로만들기인덱스 클릭

 

인덱스 이름 DNSLog 작성 후 저장

 

DNSLog가 생성된 걸 확인

 

Source Type 클릭

 

새 이름 (DNSLog) , 범주 구조적, 인덱스 추출 tsv , 필드 이름 붙여넣고 저장 클릭

 

DNSLog 가 생성된 걸 확인

 

데이터 추가 클릭

 

업로드 내 컴퓨터의 파일 클릭

 

다운로드 받은 dns.zip 파일 선택

 

Source type : 선택 > 사용자 지정 > DNSLog 클릭

호스트 : ZeekIDS

인덱스 : dnslog 선택

 

파일 업로드가 완료된다면 검색 시작 클릭

 

source="dns.zip:*" host="ZeekIDS" index="dnslog" sourcetype="DNSLog"

 

 

* ut_parse 매크로

더보기
ut_parse 매크로 사용 결과

index=dnslog sourcetype=dnslog domain!="-"
| eval list="mozilla"
| `ut_parse(domain,list)`
| table ut_netloc, ut_domain, ut_subdomain, ut_domain, ut_domain_without_tld, ut_tld
| dedup ut_netloc

 

* ut_netloc : 전체 도메인 보여줌

* ut_domain : 서브 도메인 제외한 도메인 보여줌

* ut_subdomain : 서브 도메인만 보여줌

* ut_domain_without_tld : 도메인에서 tld를 제외하고 보여줌

* ut_tld : 도메인에서 tld 값만 보여줌