윈도우 시스템 점검 시 각종 애플리케이션 로그와 함께 점검하는 중요한 로그가 이벤트 로그다. 시스템점검 시 초기에 파일로 수집하는 항목 중 하나이기도 하다.
일반적으로 이벤트 로그를 점검하는 방법은 점검 대상 시스템의 로그를 파일로 저장(확장자 evt)해 점검 PC에서 불러와 분석 한다. 점검 과정에서 발생할 변경 사항을 최소화 하고, 원본 파일 손상을 막기 위해 위와 같은 방식으로 점검 한다.

애플리케이션 로그와 마찬가지로 이벤트 로그에 대한 기본적인 형식과 각 항목에 대한 이해가 있으면 좀더 효율적으로 분석 작업이 가능하다. 특히 이벤트 로그의 경우 이벤트 ID별로 각각이 의미하는 내용이 틀리다. 기본적으로 Windows Server 제품군 운영 체제를 실행하는 컴퓨터는 다음과 같은 세 가지 종류의 로그에 이벤트를 기록한다. 사용자의 로그인 성공/실패를 기록하는 보안로그, 시스템 구동 중에 발생되는 응용프로그램의 오류 및 특이 사항을 기록하는 응용프로그램, 드라이버 충돌 및 오류관련 로그를 기록하는 시스템 로그 총 3개의 이벤트 로그를 기록 한다.
| 로그 종류 | 설명 |
| 응용프로그램 로그 | 응용 프로그램 로그에는 응용 프로그램이나 프로그램에서 기록한 이벤트가 포함됩니다. 예를 들어 데이터베이스 프로그램에서 응용 프로그램 로그에 파일 오류를 기록할 수 있습니다. 로그할 이벤트는 응용 프로그램 개발자가 결정합니다. |
| 보안 로그 | 보안 로그에는 파일이나 다른 개체 만들기, 열기 또는 삭제 등의 리소스 사용과 관련된 이벤트뿐만 아니라 올바른 로그온 시도 및 잘못된 로그온 시도와 같은 이벤트가 기록됩니다. 예를 들어 로그온 감사를 사용하는 경우 시스템에 로그온하려는 시도가 보안 로그에 기록됩니다. |
| 시스템 로그 | 시스템 로그에는 Windows 시스템 구성 요소에서 기록한 이벤트가 포함됩니다. 예를 들어 시스템을 시작하는 동안 드라이버나 다른 시스템 구성 요소의 로드에 실패하면 시스템 로그에 기록됩니다. 시스템 구성 요소가 기록하는 이벤트 유형은 서버에 의해 미리 정해져 있습니다. |
언급한 로그 외에도 사용 프로그램이나 환경에 따라 이벤트 로그에 추가적으로 다른 종류의 로그가 생길 수 있다. 예를 들어 윈도우 운영체제에 디렉터리 서비스를 운영하거나 파일 복제 서비스(파일서버)를 운영할 경우 해당 로그가 추가적으로 발생된다.
| 디렉터리 서비스 로그 | 디렉터리 서비스 로그에는 Windows Active Directory 서비스에서 기록한 이벤트가 포함됩니다. 예를 들어 서버와 글로벌 카탈로그 사이의 연결 문제는 디렉터리 서비스 로그에 기록됩니다. |
| 파일 복제 서비스 로그 | 파일 복제 서비스 로그에는 Windows 파일 복제 서비스에서 기록한 이벤트가 포함됩니다. 예를 들어 도메인 컨트롤러가 시스템 볼륨 변경 정보로 업데이트되고 있는 동안 발생하는 파일 복제 실패와 이벤트는 파일 복제 로그에 기록됩니다. |
| DNS 서버 로그 | DNS 서버 로그에는 Windows DNS 서비스에서 기록한 이벤트가 포함됩니다. |
윈도우 이벤트 로그는 Windows를 시작할 때 이벤트 로그 서비스가 자동으로 시작된다. 또한 이벤트 로그에 대해 접근 권한을 설정할 수 있어서 그룹정책 편집기(gpedit.msc)를 이용해 이벤트 로그에 대한 엑세스 사용 권한을 설정 할 수 있다. 로그 훼손을 막기 위해 사용하면 좋다.
윈도우와 마찬가지로 리눅스도 여러 종류의 로그가 존재한다. OS에 의해 발생되는 로그는 물론 애플리케이션에 의해 로그가 발생하는 것은 유사하다. 일반적인 로그 종류를 살펴보면 다음과 같다.
| 구분 | 경로 |
| 주요로그디렉터리 | /var/adm /var/log |
| 주요로그파일 | /var/log/wtmp, /var/run/utmp, /var/log/btmp, /var/log/pact, /var/log/messages, /var/log/lastlog, /var/adm/lastlog, /var/adm/sulog |

로그 종류는 운영환경과 사용중인 애플리케이션에 따라 일부 항목은 차이가 발생할 수 있다.
- 애플리케이션 로그
가장 대표적인 애플리케이션 로그가 웹 로그다. 윈도우의 대표적인 애플리케이션인 인터넷정보서비스(IIS) 웹 서버 로그를 살펴보자.
IIS 로그는 속성 설정을 통해 실제 기록하고자 하는 로그항목을 선택적으로 사용할 수 있다. 로깅 속성에서 제공하는 로깅 옵션을 살펴보면 다음 표와 같다. (옵션의 버전에 따라 차이가 있다)
| 옵션항목 | 설명 | 기본설정 |
| 날짜 | 작업이 발생한 날짜를 기록 | Yes |
| 시간 | 작업이 발생한 시간을 기록 | Yes |
| 클라이언트 IP 주소 | 서버에 액세스한 클라이언트의 IP 주소를 기록 | Yes |
| 사용자 이름 | 서버에 액세스한 인증된 사용자의 이름을 기록. 하이픈(-)으로 표시되는 익명 사용자는 포함되지 않는다. | Yes |
| 서비스 이름 | 클라이언트에서 액세스한 인터넷 서비스 및 인스턴스 번호를 기록 | No |
| 서버 이름 | 로그 항목이 생성된 서버의 이름을 기록 | No |
| 서버 IP | 로그 항목이 생성된 서버의 IP 주소를 기록 | Yes |
| 서버 포트 | 클라이언트가 연결된 포트 번호를 기록 | Yes |
| 메서드 | 클라이언트가 시도한 작업(예: GET 명령)을 기록 | Yes |
| URI 스템 | 액세스한 리소스(예: HTML 페이지, CGI 프로그램, 또는 스크립트)를 기록 | Yes |
| URI 쿼리 | 클라이언트가 시도한 쿼리(있는 경우), 즉 클라이언트에서 찾으려고 한 하나 이상의 검색 문자열을 기록 | Yes |
| 프로토콜 상태 | HTTP 또는 FTP 항목을 기준으로 작업 상태를 기록 | Yes |
| 프로토콜 하위 상태 | HTTP 항목을 기준으로 작업의 추가 상태를 기록. | Yes |
| Win32 상태 | Microsoft_ Windows (R) 운영 체제에서 사용하는 항목을 기준으로 작업 상태를 기록 | Yes |
| 보낸 바이트 수 | 서버에서 보낸 바이트 수를 기록 | No |
| 받은 바이트 수 | 서버에서 받은 바이트 수를 기록 | No |
| 걸린 시간 | 작업을 완료하는 데 걸린 시간을 기록. ODBC 로깅을 제외한 모든 로그 형식에서 걸린 시간은 다음과 같은 기술적인 문제에 따라 밀리초 단위로 기록된다. 클라이언트 요청 타임스탬프는 HTTP.sys(커널 모드 드라이버)가 요청을 분석하기 전에 첫 번째 바이트를 받을 때 초기화되고 IIS에서 보내기가 완료되면(마지막 보내기) 중지 된다. 걸린 시간은 네트워크를 통한 시간은 반영 되지않는다. | No |
| 프로토콜 버전 | 클라이언트에서 사용하는 프로토콜(HTTP, FTP) 버전을 기록 HTTP의 경우 HTTP 1.0 또는 HTTP 1.1 | No |
| 호스트 | 호스트 헤더의 내용을 기록 | No |
| 사용자 에이전트 | 클라이언트에 사용되는 브라우저를 기록 | Yes |
| 쿠키 | 보내거나 받은 쿠키의 내용(있는 경우)을 기록 | No |
| 참조 페이지 | 사용자가 방문한 이전 사이트를 기록 | No |
IIS에서 기록하는 웹 로그가 어떤 것들이고, 또 내용은 무엇인지 알아야 여러분이 로그를 점검하거나 분석할 때 정확하고 효과적으로 분석 할 수 있다. 예를 들어 웹 요청 중에 메소드 형식이 틀린 웹 로그를 검색한다고 가정해보자. 로그를 검색하기 위해서는 메소드가 무엇이고 메소드가 로그에 기록되는지 알아야 한다. 다음과 같은 로그를 찾는다고 가정하자.
| 2010-11-05 08:34:29 W3SVC1 192.168.0.100 PUT /test.txt – 80 – X9.XX.XXX.8X – – 201 0 0 |
물론 로그 파일을 열어 각행을 일일이 검색할 수 있다. 하지만 로그 사이즈에 따라서 일일이 검색하기 불가능할 수 있다.
효과적으로 로그를 분석하기 위해 대부분 로그 분석 툴을 이용하게 된다. 이때 웹 로그 형식을 이해하고 검색을 통해 원하는 결과를 빠른 시간에 찾는 것이 로그 분석의 핵심이다.
다음은 아파치 웹 로그 형식을 표로 설명한 자료다. IIS로깅 옵션과 마찬가지로 클라이언트 IP에서부터 시간, 메소드, 쿠키정보, 헤더정보 등 로그에 기록되는 정보는 다양하다.
다음은 아파치에 기록된 로그 예제다.
127.0.0.1 - frank [10/Oct/2000:13:55:36 -0700] "GET /apache_pb.gif HTTP/1.0" 200 2326 |
예제 로그의 각각의 정보들이 의미하는 내용은 다음과 같다.
| 127.0.0.1 (%h) | 서버에 요청을 한 클라이언트(원격 호스트)의 IP 주소이다. HostnameLookups가 On이라면 호스트명을 찾아서 IP 주소 자리에 대신 쓴다. 그러나 이 설정은 서버를 매우 느리게 할 수 있으므로 추천하지 않는다. 호스트명을 알려면 대신 나중에 logresolve와 같은 로그를 처리하는 프로그램을 사용하는 것이 좋다. 여기에 나온 IP 주소는 사용자가 사용하는 컴퓨터 주소가 아닐 수 있다. 프록시 서버가 사용자와 서버사이에 존재한다면, 원래 컴퓨터 주소가 아니라 프록시의 주소가 기록될 것이다. |
| – (%l) | 출력에서 “빼기기호”는 요청한 정보가 없음을 나타낸다. 이 경우 여기에 나올 정보는 클라이언트 컴퓨터의 identd가 제공할 클라이언트의 RFC 1413 신원이다. 이 정보는 매우 믿을 수 없기때문에, 긴밀히 관리되는 내부 네트웍이 아니라면 절대로 이 정보를 사용하면 안된다. IdentityCheck가 On이 아니라면 아파치 웹서버는 이 정보를 알아보려고 시도하지도 않는다. |
| frank (%u) | 이는 HTTP 인증으로 알아낸 문서를 요청한 사용자의 userid이다. 보통 이 값은 CGI 스크립트에게 REMOTE_USER 환경변수로 넘겨진다. 요청의 상태코드가 401이라면 (아래 참고) 사용자가 아직 인증을 거치지 않았으므로 이 값을 믿으면 안된다. 문서를 암호로 보호하지 않는다면 이 항목은 이전 항목과 같이 “-“이다. |
| [10/Oct/2000:13:55:36 -0700] (%t) | 서버가 요청처리를 마친 시간. 형식은: [day/month/year:hour:minute:second zone] day = 숫자 2개 month = 숫자 3개 year = 숫자 4개 hour = 숫자 2개 minute = 숫자 2개 second = 숫자 2개 zone = (`+’ | `-‘) 숫자 4개 로그 형식문자열에 %{format}t를 사용하여 다른 형식으로 시간을 출력할 수 있다. format은 C 표준 라이브러리의 strftime(3)과 같다. |
| “GET /apache_pb.gif HTTP/1.0″ (\”%r\”) | 클라이언트의 요청줄이 쌍따옴표로 묶여있다. 요청줄은 매우 유용한 정보를 담고 있다. 첫째, 클라이언트가 사용한 메써드는 GET이다. 둘째, 클라이언트는 자원 /apache_pb.gif를 요청한다. 세번째, 클라이언트는 HTTP/1.0 프로토콜을 사용한다. 요청줄의 여러 부분을 따로 로그할 수도 있다. 예를 들어, 형식문자열 “%m %U%q %H”은 “%r”과 똑같이 메써드, 경로, 질의문자열, 프로토콜을 로그한다. |
| 200 (%>s) | 이는 서버가 클라이언트에게 보내는 상태코드이다. 이 정보는 (2로 시작하는 코드) 요청이 성공하였는지, (4로 시작하는 코드) 클라이언트에 오류가 있는지, (5로 시작하는 코드) 서버에 오류가 있는지 알려주므로 매우 중요하다. 상태코드의 전체 목록은 HTTP 규약 (RFC2616 section 10)에서 찾을 수 있다. |
| 2326 (%b) | 마지막 항목은 응답 헤더를 제외하고 클라이언트에게 보내는 내용의 크기를 나타낸다. 클라이언트에게 보내는 내용이 없다면 이 값은 “-“이다. 내용이 없는 경우 “0”을 로그하려면 대신 %B를 사용한다. |
예제에서 살펴본 항목 외 아파치 웹 서버에서 기록 가능한 항목이다.
| 형식 문자열 | 설명 |
| %% | 퍼센트 기호 (아파치 2.0.44 이후) |
| %a | 원격 IP-주소 |
| %A | (서버) IP-주소 |
| %B | HTTP 헤더를 제외한 전송 바이트수. |
| %b | HTTP 헤더를 제외한 전송 바이트수. CLF 형식과 같이 전송한 내용이 없는 경우 0 대신 ‘-‘가 나온다. |
| %{Foobar}C | 서버가 수신한 요청에서 Foobar 쿠키의 내용. |
| %D | 요청을 처리하는데 걸린 시간 (마이크로초 단위). |
| %{FOOBAR}e | 환경변수 FOOBAR의 내용 |
| %f | 파일명 |
| %h | 원격 호스트 |
| %H | 요청 프로토콜 |
| %{Foobar}i | 서버가 수신한 요청에서 Foobar 헤더의 내용. |
| %l | (있다면 identd가 제공한) 원격 로그인명. IdentityCheck가 On이 아니면 빼기기호를 기록한다. |
| %m | 요청 메써드 |
| %{Foobar}n | 다른 모듈이 기록한 Foobar 노트(note) 내용. |
| %{Foobar}o | 응답의 Foobar 헤더 내용. |
| %p | 요청을 서비스하는 서버의 정규 포트 |
| %P | 요청을 서비스하는 자식의 프로세스 ID. |
| %{format}P | 요청을 서비스하는 자식의 프로세스 ID 혹은 쓰레드 ID. format에는 pid와 tid가 가능하다. (아파치 2.0.46 이후) |
| %q | 질의문자열 (질의문자열이 있다면 앞에 ?를 붙이고, 없다면 빈 문자열) |
| %r | 요청의 첫번째 줄 |
| %s | 상태(status). 내부 리다이렉션된 요청의 경우 *원래* 요청의 상태이다. 최종 요청의 상태는 %…>s. |
| %t | common log format 시간 형식(표준 영어 형식)의 시간 |
| %{format}t | strftime(3) 형식 format의 시간. (지역시간일 수 있음) |
| %T | 요청을 처리하는데 걸린 시간 (초 단위). |
| %u | 원격 사용자 (auth가 제공하며, 상태(%s)가 401인 경우 이상한 값을 나올 수 있음) |
| %U | 질의문자열을 제외한 요청 URL 경로. |
| %v | 요청을 서비스한 서버의 정규 ServerName. |
| %V | UseCanonicalName 설정에 따른 서버명. |
| %X | 응답을 마쳤을때 연결 상태. X = 응답을 마치기 전에 연결이 끊어졌다. + = 응답을 보낸후에도 연결이 살아있다(keep alive). – = 응답을 보낸후 연결이 끊어졌다. (아파치 1.3 후반 버전에서 이 지시어는 %…c였지만, 전통적인 ssl %…{var}c 문법과 겹쳐서 변경했다.) |
| %I | 요청과 헤더를 포함한 수신 바이트수로 0일 수 없다. 이를 사용하려면 mod_logio가 필요하다. |
| %O | 헤더를 포함한 송신 바이트수로 0일 수 없다. 이를 사용하려면 mod_logio가 필요하다. |
아파치 로그 형식을 파악했으니 앞서 소개했던 로그 검색 예제를 참고해 여러분이 분석 시 상황에 맞게 원하는 결과를 검색하기 바란다.
- 운영체제 로그
SSH를 통한 로그인 시도에서부터 시스템에 마지막으로 로그인 했던 내역까지 시스템에 남아 있는 로그를 통해 확인이 가능하다. 대부분의 사전식 대입 시도는 “secure” 로그를 통해 확인이 가능하다. 시스템 로그 분석 시 점검하는 항목을 확인해 보자.
시스템에 로그인한 계정 정보를 점검해보자. wtmp로그는 시스템에 로그인, 로그아웃 내역을 누적해서 기록한다. 해당 항목을 통해 시스템에 로그인한 사용자, IP, 로그인 시간에 대해 확인이 가능하다. 침해사고 발생 시 공격자에 발생한 로그인 내역 분석 시 활용한다.
다음은 샘플로 wtmp로그를 실행 시킨 내역이다.
| # last -100 -f /var/log/wtmp root pts/0 192.168.9.15 Wed Apr 28 00:58 still logged in root pts/1 192.168.9.15 Sun Apr 25 21:32 – 20:41 (1+23:08) root pts/0 192.168.9.15 Thu Apr 22 18:09 – 23:26 (3+05:17) root pts/0 192.168.9.15 Sun Apr 18 17:52 – 18:28 (00:35) root pts/0 192.168.9.15 Sun Apr 18 17:46 – 17:50 (00:03) root pts/1 song.local Thu Apr 8 20:52 – 22:17 (01:24) root pts/0 song.local Thu Apr 8 18:18 – 22:17 (03:58) wtmp begins Thu Apr 8 18:17:43 2010 |
네트워크와 로그를 통해 분석에 필요한 정보를 충분히 확보한 후에는 이벤트 분석 작업을 수행 한다. 수집된 정보의 양이 많은 경우는 효율적인 분석을 위해 먼저 데이터를 가공하는 작업이 선행되기도 한다.
선별된 정보를 분석해 위협 징후를 확인 하고, 침해사고완 연관된 일련의 정보들을 조합 한다. 분석 과정에서는 공격과 관련된 특징으로 정보를 선별하거나 통계학적인 관점에서 임계치를 기준으로 정보를 분석 한다. 만약 침해사고와 관련된 근거 정보를 충분히 확보 할 수 없다면 정보 수집 과정을 반복할 필요가 있다. 처음 수집할 정보를 선별하는 과정에서 정보 수집 범위가 잘못됐을 수도 있고, 혹은 수집된 정보를 가공하는 과정에서 정보가 누락 됐을 수 도 있다. 이런 경우 처음 정보 수집 대상을 다시 한번 검토하고 제외된 대상에 대한 정보 재가공을 통해 분석 작업을 반복 한다.
[1] http://httpd.apache.org/docs/2.0/ko/mod/mod_log_config.html#logformat