- 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 만들기



❷ SourceType 지정




❸ 데이터 추가




Source type : 선택 > 사용자 지정 > HTTPLog 클릭
호스트 : ZeekIDS
인덱스 : httplog 선택


source="http.zip:*" host="ZeekIDS" index="httplog" sourcetype="HTTPLog"
- URL Toolbox 설치
https://splunkbase.splunk.com/app/2734#/overview
splunkbase.splunk.com




- 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 실습 환경











Source type : 선택 > 사용자 지정 > DNSLog 클릭
호스트 : ZeekIDS
인덱스 : dnslog 선택


source="dns.zip:*" host="ZeekIDS" index="dnslog" sourcetype="DNSLog"
* 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 값만 보여줌
'SK shieldus Rookies 9기 > 클라우드 기반 시스템 운영,구축 실무' 카테고리의 다른 글
시스템 운영/구축 실무 8일차 (22/11/02) (1) | 2022.11.02 |
---|---|
시스템 운영/구축 실무 6일차 (22/10/31) (0) | 2022.10.31 |
시스템 운영/구축 실무 5일차 (22/10/28) (0) | 2022.10.28 |
시스템 운영/구축 실무 4일차 (22/10/27) (0) | 2022.10.27 |
시스템 운영/구축 실무 3일차 (22/10/26) (0) | 2022.10.26 |