이전 포스트에 이어 작성하였습니다.
[시스템 보안 및 실무/시스템 운영·구축 실무] - HTTP 로그분석(현황분석/이상징후)
HTTP 이상징후 분석
1. 비정상 메소드 사용
2. 외부행 데이터 전송
3. Mime-type과 파일 확장자 불일치
4. 사이트 이동 후 실행파일 다운로드
5. 프록시 서버 접속
1. 비정상 메소드 사용
● Head, Delete, Trace, Option과 같은 메소드가 네트워크에서 지속적으로 보인다는 것은 정상적인 사용자의 활동이라 보기 어려움
(1)
index=httplog sourcetype=httplog
| stats count(eval(method="OPTIONS")) AS option_count by src
| where option_count > 10
| sort option_count desc
=> httlog 저장소에서 httplog 필드와 일치하는 로그들만 검색
=> 메소드가 OPTION인 것들의 개수를 세어 src별 option_count를 표시(OPTIONS 메소드를 사용한 횟수를 src별로 집계)
=> option_count가 10보다 크다면 아래줄 실행
=> option_count를 기준으로 내림차순
(2)
index=httplog sourcetype=httplog
| where NOT match(method, "(GET|POST|-)")
| stats count(src) as src_count by method
| sort - src_count
=> 메소드가 GET,POST,-(값이 없음)이 아니라면 아래줄 실행(GET,POST, -를 제외한 메소드 검색)
=> 각 메소드별 src의 개수를 세어 src_count로 표시
=> src_count를 기준으로 내림차순 정렬
2. 외부행 데이터 전송
index=httplog sourcetype=httplog (request_body_len!=0 OR response_body_len!="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)
| search oMB!=0 AND iMB!=0
| iplocation dst
| eval isUp=if((oMB/iMB)>1, "Yes","No")
| where isUp="Yes"
| table src,dst, iMB, oMB, Country, City
=> 요청길이 또는 응답길이가 0이 아니고, domain(접속하려는 사이트)이 비어있지 않은 경우를 검색
일반적으로 요청라인이 GET, HEAD, DELETE, OPTION일 경우 요청본문X, POST, PUT일 경우 요청본문O
=> src(송신지 IP), dst(목적지 IP)별 요청길이의 총합을 outTotal, 응답길이의 총합을 inTotal로 표시
=> oMB, iMb 변수에 각 outTotal, inTotal을 MB단위로 변환하여 소수점 아래 2자리까지 표시하여 저장
=> oMB와 iMb가 0이 아닌 경우만 선택(oMb는 reqeust에 대한 값, iMb는 response에 대한 값)
=> dst(목적지 IP)를 기반으로 IP위치 정보 추가(국가)
=> isUp 변수에 iMB 대비 oMB 비율이 1보다 크면 Yes, 아니면 No 저장
response보다 request가 많으면 비정상이므로 관제대상(Yes 출력)
=> isUp이 Yes일 경우 아래줄 실행
=> 결과를 테이블 형태로 추출
[참고]
ex) http://www.test.com/search/new/hello
domain : www.test.com
uri : search/new/hello
=> 웹취약점 : file upload 공격(request에 파일 첨부해서 보냄), request file 용량 > response 전송량
=> 파일 업로드 공격 점검 목적
3. Mime-type과 파일 확장자 불일치
index=httplog sourcetype=httplog resp_mime_types="application/x-dosexec" uri!="-"
| eval filename1=mvindex(split(uri,"/"),-1)
| eval filename=if(like(filename1,"%?%"), mvindex(split(filename1,"?"),0),filename1)
| eval filetype=if(match(filename,"(.exe|.bat|.ps1|.dll|.ocx)$"), "PE", "Not_PE")
| table domain, uri, filename, filetype, resp_mime_types
| where filetype=="Not_PE"
| dedup filename
=> resp_mime_types(MIME 타입)= application/x-dosexec : DOS 및 Windows 실행파일 즉, .exe 확장자 파일에 해당하는 데이터를 의미.
=> httlog에서 httplog 필드와 일치하며, uri가 비어있는 것은 제외하고, DOS 및 Windows 실행 파일에 해당하는 데이터를 검색
=> uri를 "/" 기준으로 나눈 후 -1번째(마지막 부분)에 위치한 값을 filename1 변수에 저장
=> filename1에 "?"가 포함되어 있다면 "?"를 기준으로 나눈 후 0번째(첫번째 부분)에 위치한 값을 filename에 저장하고, "?"가 포함되어 있지 않다면 filename1을 그대로 filename에 저장
=> 위의 두 줄은 확장자를 검출하는 코드
=> filename이 ".exe", ".bat", ".ps1", ".dll", ".ocx" 중 하나로 끝나는 경우 "PE"를, 그렇지 않은 경우 "Not PE"를 filetype에 저장
=> 테이블로 출력
= filetype이 "Not PE"인 경우 중복된 filename 제거
=> mime type은 브라우저가 인지한 type(body를 보고 인지한 것, content-type), filetype은 클라이언트가 파일을 첨부시 지정한 파일명
=> 분명 1번째 줄에서 exe파일만 검출을 했는데, 6번째 줄에서 DOS 및 Windows 실행 파일 아닌 것들을 발견!!
분명 필터링을 했는데 왜 6번째에서 또 할까?
클라이언트가 첨부된 파일의 확장자명과 브라우저 인지한 파일명이 다른 경우가 있음!!!
**MIME-Type**
● MIME(Multipurpose Internet Msail Extensions) Type은 미디어 타입(Media Type)라고 부름
● 인터넷에서 데이터 형식을 식별하기 위해 사용되는 Type
● 인터넷의 모든 MIME Type은 국제인터넷주소관리기구(ICANN)에서 관리
● MIME Type을 저의 하기 위해서는 슬래시(/)를 사용하며 공백이나 탭이 존재할 수 없음
● 형식(Type/SubType)
폰트 | font/woff, font/ttf, font/otf |
영상 및 이미지 | image/jpeg, image, png, image/svg_xml |
텍스트 | text/plain, text/csv, text/html |
멀티파트 | HTML Form을 POST 전송하는 경우 : multipart/form-data |
pdf 및 json | application/pdf, application/json |
=> text/html : 내가 text를 전송하려고 하는데 text의 구체적인 타입은 html이야~
=> text/csv : text인데 csv 타입을 전송할거야~
**Content-Type**
● HTTP 헤더에 존재하는 매개변수로 어떤 유형의 데이터가 전송되는지 웹 클라이언트 또는 웹 서버에 알리는 역할
● 웹 클라이언트가 text/html을 요청하는 경우 웹 서버는 요청에 대한 응답에 Content-Type:text/html을 포함
● 형식(Type/SubType)
Content-Type : Multipart/related Content-Type : Application/X-FixedRecord Content-Type : text/html |
Request
- accept: text/html => 난 html 데이터 수용할 수 있어~
Response
- Content-type : text/html => 내가 지금 body에 가져가는 데이터타입이 html이야~
=> accept, content-type에 MIME 타입(미디어타입)이 들어간다!!
★Content-type은 request, response에 모두 나올 수 있음
언제 content-type이 나오나? body가 있다면 나옴!! 왜냐면 body에 대한 타입을 쓰는 공간이기 때문에
**MIME-Type & Content-Type**
● MIME-Type과 Content-Type은 인터넷에서 데이터(텍스트,이미지 파일 등) 형식을 식별하기 위해 사용
● MIME-Type은 Content-Type 보다 상위개념
● Content-Type은 웹에서 사용
4. 사이트 이동 후 실행파일 다운로드
index=httplog sourcetype=httplog referrer!="-" status_code=200
| eval filename1=mvindex(split(uri,"/"),-1)
| eval filename=if(like(filename1,"%?%"), mvindex(split(filename1,"?"),0),filename1)
| where cidrmatch("0.0.0.0/0",domain)
| where match(resp_mime_types,"application/x-dosexec") OR match(filename,"(exe|dll|com|src)$")
| eval URL=domain+" :: " + filename
| stats count by src, URL
| stats list(URL) as Target list(count) as Source by src
=> referrer : 이전 페이지 URL을 의미함.
=> 어디를 경유하지 않고, 웹브라우저에 다이렉트로 들어온 것들을 검색하겠어!
=> httlog에서 httplog 필드와 일치하고, 상태코드는 200(응답 정상적)이며 referrer가 비어있지 않은 경우를 검색
=> uri를 "/" 구분자로 분리하여 -1번째(마지막부분)에 위치한 값을 filename1에 저장
=> filename1에 "?"가 포함되어 있다면 "?"를 기준으로 나눈 후 0번째(첫번째 부분)에 위치한 값을 filename에 저장하고, "?"가 포함되어 있지 않다면 filename1을 그대로 filename에 저장
=> 0.0.0.0/0 대역대에 포함하는 경우 아래줄 실행(IP 주소 체계인 것들만 작업을 하겠어)
=> exe 확장자 파일에 해당하는 데이터이거나 filename이 ".exe", ".dll", ".com", ".src" 중 하나로 끝나는 경우 아래줄 실행(응답헤더의 content_type이 실행파일이거나 filename이 실행파일인 경우를 찾기)
=> domain과 filename을 결합하여 URL에 저장(domain :: filename 형식)
=> src(송신지 IP), URL 별 카운팅
=> src를 기준으로 URL을 리스트로 수집하여 Target으로, count를 리스트로 수집하여 Source로 표시
=> 어떤 사이트로 이동하여 실행파일을 받았는지 확인
=> 보통 uri에는 텍스트 주소가 나와야 하는데 IP 주소로 특정 파일을 다운로드하였다면 관제 대상이 될 수 있음
=> 172.16.154.10 사이트에 들어가서 27.101.131.41에 접속했는데 이곳에서 PelicanC.dll이라는 파일을 다운받음( 27.101.131.41 사이트에 유입하게 한 경로는 172.16.154.10임)
=> 송신지 : 172.16.154.10
=> 수신지 : 27.101.137.41
=> 유입경로(referrer) : http://www.sisafocus.co.kr/news/articleView.html?idxno=213804
**DBD(Drive By Download)공격**
[보안 취약점 진단 및 대응/취약점] - DBD(Drive By Download) 공격
● 웹서핑 중 특정 실행파일 다운로드가 진행되는 것
● 어떤 사이트를 방문했는데 방문한 사이트에서 자신도 모르게 악성파일을 다운로드하게 되는 것
=> 우리는 파일을 어느 사이트에서 다운받았는지(유포지)와 유포지에 들어오게 된 경유페이지(중계지)를 찾고자 합니다.
=> 이때 referer를 사용
=> 빨간 네모 uri는 유포지의 uri일까? 경유지의 uri일까? 유포지의 uri이다!!
=> 파란 네모 referrer는 중계지
5. 프록시 서버 접속
● Method:CONNECT => 웹서버에 Proxy 기능을 요청 시 사용
● URI에 접속 대상의 전체 주소가 기록된 경우
● 클라이언트가 자체적으로 프록시를 설정하고 운영하는 경우
● 프록시를 사용하는 이유 :
- 보안 : 서버, 클라이언트 IP 숨김 => 차단된 사이트를 접속하기 위한 용도
- 캐싱기능
- 트래픽 분산
● web client - proxy - web server 형태의 경우, 보통 method는 connect
web client(proxy) - web server 형태(client 자기 자신에게 proxy를 설치)의 경우, 다이렉트로 서버로 갈건데 내 컴퓨터에 프록시를 설치하는 경우는 웹서버의 취약점을 찾거나 서버의 웹구조를 파악하기 위함임
index=httplog sourcetype=httplog (uri="http://*" OR method="connect")
| table src, domain, uri
=> * : 와일드카드로, 부분 문자열 매칭을 나타냄. 어떠한 문자열이든 해당 위치에 올 수 있음을 의미
=> uri= "http://*" : WC가 프록시로 운영될 때를 의미. 즉, full 주소가 나타난다는 것은 프록시 사용했다는 것!!
http://www.test.com/aaa/bbb/ccc에서 보통 uri는 /aaa/bbb/ccc이 부분이다.
=> 프록시를 사용했다는 것을 확인하는 방법은 2가지!!
1) method가 CONNECT 인 경우
2) uri가 full 주소인 경우
=> uri가 http://으로 시작하거나 method가 connect인 것을 검색
=> 테이블 형식으로 추출