[IT Trend]/Security

[웹 파이어월 강좌] 웹 애플리케이션 보안 방법론

하늘을닮은호수M 2006. 5. 23. 16:07
반응형

출처 : http://www.ionthenet.co.kr/newspaper/view.php?idx=10982

[웹 파이어월 강좌] 웹 애플리케이션 보안 방법론

지난 2회에 걸친 연재에서 웹 애플리케이션 공격에 대한 몇 가지 시나리오와 다양한 공격 기법들에 대해서 살펴봤다. 이제 마지막으로 이 연재의 종착역이라고 할 수 있는 웹 애플리케이션 보안 방법에 대해 알아보자.

이종일 | 파이오링크 연구소 아테나팀 과장

웹 애플리케이션 보안을 실현하기 위해 ‘안전하게 웹 애플리케이션을 개발하기 위한 지침서’에 따라 안전하게 프로그래밍을 한다던가, 이미 개발돼 있는 프로그램의 소스 코드를 검사하는 등의 근본적인 해결책이 있지만, 실제로 적용하기가 쉽지 않고 보안 담당 부서에서 채택할 수 있는 방법도 아니다. 그래서 이번 연재에서는 최근 손쉽게 웹 애플리케이션 보안을 구축할 수 있어서 주목받고 있는 웹 애플리케이션 파이어월(Web Application Firewall)의 주요 기술에 대해 집중적으로 알아 보자.

애플리케이션 접근 제어
웹 파이어월에서 제공하는 대표적인 포지티브 보안 방식은 애플리케이션 접근 제어 기능이다. 웹 서버에는 서비스 제공자가 서비스를 제공하고자 의도한 대상 외에도 웹 서버가 설치될 때 자동으로 설치되는 테스트 애플리케이션이나 관리용 애플리케이션에서부터 개발 시에 남겨진 임시 파일까지 다양한 자원이 존재한다.
다양한 주체에 의해 개발되고 관리되는 웹 애플리케이션의 경우, 실제로 웹 서버에 존재하는 소스를 모두 파악해서 제어한다는 것은 거의 불가능하다. 문제는 서비스에 관계없이 서버에 남겨진 파일에 보안 취약점이 존재하며, 결국 웹 애플리케이션의 해킹으로 이어진다는 것이다.
전통적인 네거티브 보안 모델에서는 이같이 취약점이 존재하는 파일의 시그니처 목록을 유지하면서 취약한 파일에 대한 접근을 차단하는 방식을 사용한다. 이런 방식은, 취약점이 알려진 파일 중에서 시그니처가 제공되는 유명한 파일에 대해서만 제한적으로 적용할 수 있으며, 공격당하기 전에 이런 시그니처 목록을 업데이트 하는 것도 쉽지 않은 일이다.

웹 파이어월에서 제공하는 애플리케이션 접근 제어 기능은 이런 네거티브 방식과 완전히 반대되는 개념이다. 직접적으로 서비스를 제공하는 파일만 명시적으로 공개하고 그 외의 모든 접근을 차단하는 방식이다. 가장 간단한 접근 제어는 허용 URL을 설정하는 것으로, (그림 1)에서와 같이 웹 서버의 모든 자원 중 허용 URL 리스트(Permitted URL List)로 설정된 URL에 대해서만 접근을 허용하는 것이다. 이 허용 URL을 설정하는 것만으로도 의도되지 않은 중요 파일의 노출이나 서비스에 관계없는 취약한 프로그램의 노출 등을 모두 차단할 수 있다.
여기에 한 세션은 반드시 지정된 URL부터 브라우징을 해야 한다는 시작 URL(Start URL)의 개념을 추가하기도 하는데, 시작 URL 기능을 설정한 경우 관리자에 의해 지정된 시작 URL(보통 /나 /index.html)에 접근한 적이 없는 클라이언트는 서버의 어떤 URL에도 접근할 수 없게 된다. 이 기능은 보다 강력한 접근제어를 구현할 수 있으며, 이를 통해 웜에 의한 취약점 전파 시도, 취약점 스캐너에 의한 스캐닝 등과 같이 취약한 URL에 직접 접근해 오는 강제 브라우징을 차단할 수 있다.
그리고 로그인한 사용자와 그렇지 않은 사용자에게 다른 서비스를 제공하는 애플리케이션과 같이 자원이 구분돼 있는 경우는 별도의 보호 URL 리스트(Protected URL List)와 진입 URL 리스트(Entry URL List)을 설정해 자원에 대한 접근을 제한할 수 있다.
예를 들어, (그림 2)와 같은 구조의 사이트가 있다고 가정하자. 이 사이트에 접속하면 /index.html 페이지가 제공되고, 로그인 버튼을 누르면 /login.html이 제공된다. 그리고 사용자명과 비밀번호를 입력하면 /cgi-bin/login.py를 통해 로그인하고, 이후에 /lecture 아래에 있는 동영상(avi) 파일에 대한 접근 권한을 부여하는 구조다. 그런데, 이 사이트에는 개발자가 실수로 남겨 놓은 /cgi-bin/login.py.bak 파일이 존재하고, 잘못된 설정으로 외부에서 접근할 수 있는 /_private/ 디렉토리가 있다.

이 사이트와 같은 경우 애플리케이션 접근제어를 (표 1)과 같이 설정할 수 있다. /index.html을 거치지 않은 클라이언트는 어떤 파일에도 접근할 수 없으며, 명시적으로 접근이 허용되지 않은 /cgi-bin/login.py.bak와 /_private/ 디렉토리 등에 대한 접근은 원천적으로 차단된다. 그리고 로그인하지 않은 사용자는 /lecture/ 아래에 있는 동영상에 접근할 수 없도록 함으로써 추가적인 보안 계층을 확보할 수 있게 됐다.


이같은 예제에서 알 수 있듯이 애플리케이션 접근 제어 기능을 통해 서비스를 제공하기 위해 필요한 파일만을 접근을 허용하는 것으로도 사이트에 존재하는 잠재 보안 위협을 상당히 경감시킬 수 있다.
그런데, 이와 같은 애플리케이션 접근 제어 기능을 사용하기 위해서는 애플리케이션의 구조에 대한 지식이 필요하다. 일반적으로 애플리케이션 관리자의 경우 애플리케이션 개발자와 다르기 때문에 애플리케이션의 구조에 대한 지식이 부족한 경우가 많다. 그래서 웹 파이어월은 애플리케이션의 구조를 자동으로 분석해주는 크롤러(Crawler)나 학습(Learning) 기능이 같이 제공되는 경우가 많다.

폼 필드 검사 기능
웹 애플리케이션에 대한 공격의 대부분은 폼 필드를 처리하는 action URL에 해당하는 프로그램에 대한 공격이다. 이런 action URL의 프로그램은 CGI나 스크립트로 구현돼 있는데, 폼 필드를 통해 입력을 받아들인다. 웹 애플리케이션에 대한 입력은 대부분 폼 필드를 통해 이뤄지므로 웹 애플리케이션 공격이 이 폼 필드에 집중되고, 그래서 웹 파이어월의 핵심기능도 폼 필드 입력에 대한 검사 기능이다. 폼 필드 검사 기능은 폼의 형식이나 입력값의 조건 등을 입력하는 방식의 포지티브 방식과 입력돼서는 안 되는 패턴을 정의하는 네거티브 방식을 함께 사용한다.
(화면 1)과 같이 로그인에 사용되는 폼 페이지가 있다고 가정하자.

(화면 1) 폼필드 예제


이 폼의 HTML은 다음과 같다.


사용자명 :

비밀번호 :




이 폼에 사용자명을 shocker로 비밀번호를 hello라고 입력하고, login 버튼을 클릭하면 다음과 같은 요청이 서버로 보내진다.

http://www.###.com/login.py?user=shocker&passwd=hello&userid=1004

일반적인 웹 애플리케이션 공격은 login.py라는 프로그램의 입력 매개변수인 user, passwd, userid에 대한 입력을 조작함으로써 이뤄진다. 만약 개발자가 user의 입력 값에 대한 길이 검사를 하지 않고 strcpy와 같은 문자열 복사 함수를 사용했다면, 악의적인 공격자는 user에 아주 긴 입력을 제공해 버퍼 오버플로우 공격을 시도할 것이다. 또 다른 예로 개발자가 passwd에 대해 SQL 입력 제한을 수행하지 않았다면, 악의적인 공격자는 passwd에 SQL 삽입 공격을 시도할 수 있다.
웹 파이어월의 폼 필드 검사는 기능은 이런 매개변수를 통한 공격 차단을 위해 일반적으로 (표 2)와 같은 검사를 수행한다.


(화면 1)의 폼과 같은 경우에는 (표 3)과 같은 웹 파이어월의 폼 필드 검사 기능을 설정할 수 있다.


폼을 사용해서 다음과 같은 정상적인 입력을 하는 경우는 필드의 길이, 형식, 차단 패턴 등에 위배되지 않기 때문에 허용된다.

http://www.###.com/login.py?user=shocker&passwd=hello&userid=1004

반면에 다음과 같이 필드에 쉘 명령을 넣거나, 아주 긴 입력을 넣거나 상수를 변경하면 웹 파이어월에 의해 차단된다.

http://www.###.com/login.py?user=shocker%3B%2F%2E%2E%2Fsh&passwd=hello&userid=1004
http://www.###.com/login.py?user=shocker&passwd=helloaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&userid=1004
http://www.###.com/login.py?user=shocker&passwd=helloaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&userid=0001

동적 폼 필드 무결성 검사
일반적으로 정적인 폼 HTML의 경우는 앞에서와 같이 사전에 설정해 상수 목록을 정의해 놓을 수 있다. 하지만 웹 애플리케이션에 의해 동적으로 생성되는 HTML 폼의 경우는 클라이언트에서 변경되지 않아야 함에도 불구하고 특정 상수로 정의할 수 없는 경우가 있다. 예를 들어, (그림 3)와 같이 웹 애플리케이션에서 숨겨진 필드(hidden field)로 사용자 ID를 구분하는 경우 각 클라이언트에게 다른 폼 HTML을 제공하게 된다.

이런 경우는 폼 필드 검사 기능을 정적으로 설정할 수 없고, 동적으로 클라이언트에게 제공되는 HTML을 분석해, 이후에 폼 입력이 이뤄질 때 분석된 HTML에 부합하는 지 검사한다.
웹 파이어월은 클라이언트가 폼 HTML을 요청하는 순간에 폼 HTML을 분석해, 폼 필드의 action URL, 필드 이름, 개수, 숨겨진 필드, 상수 리스트 등을 인식해 세션 정보에 기록해두고, 해당하는 action URL에 대한 요청이 이뤄질 때, 세션 정보에 기록된 데이터에 기반해 검사를 수행한다.

쿠키 보호 기능
웹 애플리케이션의 세션 기반 동작을 위한 핵심은 쿠키(cookie)다. 따라서 세션에 대한 공격을 위한 주 공격 대상이 되는 것도 쿠키이며, 거의 모든 웹 파이어월에서도 쿠키 보호 기능을 제공한다.
쿠키 보호 기능은 폼 필드 검사와 유사하게 쿠키의 형식을 검사하는 쿠키 형식 검사, 쿠키의 내용을 볼 수 없도록 내용을 암호화하는 쿠키 암호화, 그리고 쿠키의 내용 변조를 막는 쿠키 전자 서명으로 나눌 수 있다.
쿠키 형식 검사는 서버에서 전송되는 쿠키의 내용을 변경하지 않고 적용할 수 있기 때문에, 쿠키 변경에 대한 부담없이 수행할 수 있다. 웹 파이어월은 사용자 설정이나 학습을 통해 쿠키의 크기, 형식과 같은 정보를 갖고 클라이언트에서 서버로 제공되는 쿠키의 형식을 검사하며 형식에 맞지 않는 쿠키 값이 존재할 경우 조작된 쿠키로 간주해 이를 웹 서버로 전달하지 않는다.
쿠키 암호화는 (그림 4)와 같이 서버에서 클라이언트로 보내는 Set-cookie 헤더의 내용을 웹 파이어월이 암호화해 클라이언트로 전달한다. 클라이언트는 암호화된 쿠키 값만을 볼 수 있기 때문에 원래 쿠키 값의 의미를 추측할 수 없다. 만약 악의적인 공격자가 의미를 제대로 해석하지 못하고 임의로 이 쿠키 값을 변조하면, 웹 파이어월에 의해 복호화돼 웹 서버에 전달됐을 때, 아무런 의미없는 값이 전달되므로 공격을 무위로 돌릴 수 있다.

그런데, 쿠키의 단순한 암호화는 쿠키 값의 의미를 클라이언트가 추측할 수 없도록 해주지만, 쿠키의 조작 여부를 판단할 수는 없다. 그래서 조작 여부를 판단할 수 있도록 메시지 인증 코드(Message Authentication Code, MAC)를 삽입하거나 쿠키 전자 서명을 사용해 이를 보완한다.
쿠키 전자서명은 (그림 5)과 같이 서버에서 클라이언트로 보내는 Set-cookie 헤더에 암호화한 전자 서명을 첨부한다. 웹 파이어월은 클라이언트가 서버로 요청을 할 때 포함되어 들어오는 Cookie 헤더의 전자 서명 값을 이용해 쿠키 값의 변조 여부를 검사한다.

이같은 쿠키 보호 기능을 사용하면 쿠키의 변조는 막을 수 있다. 그러나 (그림 6)과 같이 쿠키의 내용을 변조하지 않고 그대로 가져가 다른 사용자의 세션을 가로채는 세션 하이재킹(session hijacking) 공격에는 적절히 대응할 수 없다.

세션 하이재킹을 막기 위해서는 세션 쿠키의 타임아웃을 지정하는 방법을 사용하기도 하지만, 쿠키가 타임아웃되기 전에 이뤄지는 세션 하이재킹에는 속수무책이다. 그래서 일부 웹 파이어월에서는 세션 쿠키에 대한 IP 주소 제한 기능을 제공하기도 한다. 서버가 쿠키를 전송해준 IP 주소 이외의 곳에서 쿠키가 입력될 경우 세션 하이재킹으로 간주해 요청을 차단하는 것이다.
이같은 IP 주소 기반 쿠키 보호 기능은 보안성을 높여주기는 하지만, 동적 IP나 프록시 팜을 사용하는 사용자와 같은 특정 상황에서는 제한적으로 사용될 필요가 있다.

리퀘스트 플러딩 제어 기능
리퀘스트 플러딩(Request Flooding Control)은 웹 서버에 반복적인 요청(request)을 보내 부하를 주는 공격 방법으로 HTTP/1.1을 사용할 경우 단순한 접속 속도 제한으로는 차단할 수 없다.
웹 파이어월은 리퀘스트 플러딩을 제한하기 위해 세션 기반 요청 속도 제한, IP 기반 요청 속도 제한, 그리고 URL 기반 요청 속도 제한 등과 같은 다양한 방식을 제공한다.
세션 기반 요청 속도 제한은 하나의 세션에서 웹 애플리케이션에 대한 요청 속도를 검사해 정해진 한도를 넘을 경우 차단하거나 속도를 제한하는 방식이다. 자동화된 프로그램이 아닌 정상적인 사용자에 의한 브라우징의 경우, 일정 속도 이상을 넘는 경우가 없기 때문에, 이 기능을 통해 효과적으로 비정상적인 요청을 제한할 수 있다. 이 기능으로 웹 취약점 스캐너나 웹 크롤러(web crawler)에 의한 브라우징을 제한할 수 있다.
IP 기반 요청 속도 제한은 사용자를 세션 단위로 구분하지 않는 웹 애플리케이션의 경우 IP 단위로 사용자를 구분해 특정 IP나 IP 범위에서 발생하는 과도한 요청을 제한하는 기능이다.
URL 기반 요청 속도 제한은 요청을 보내는 클라이언트를 기준으로 속도를 제한하는 것이 아니고 요청 대상이 되는 서버의 특정 URL에 대해 과도한 요청이 들어오는 것을 탐지하고 제한하는 기능이다. 특정 URL이 취약해 스캐닝 대상이 되거나, 웜에 의한 공격 대상이 되는 경우 해당 URL에 대한 요청이 과도하게 들어오게 된다. 이 기능은 이를 탐지하고 순간적인 요청 범람을 제한하는 기능이다.

위장 기능
위장(Cloaking) 기능은 웹 파이어월 뒤에 있는 웹 서버의 정보를 최대한 숨겨, 악의적인 공격자가 공격 대상을 지정하거나 공격의 성공에 도움이 되는 정보를 획득할 수 없도록 해주는 기능이다.
상용 웹 파이어월에서 제공하는 위장 기능은 웹 서버의 IP 주소를 숨기는 NAT(Network Address Translation)기능에서부터 내부 URL을 숨기는 URL 변환(URL rewriting), 웹 서버의 응답 헤더에 포함된 서버 정보를 변조하는 등의 기능까지 다양하게 제공되고 있다. 여기서는 HTTP와 직접 관련이 있는 URL 변환 기능과 서버 정보 변조 기능을 알아보겠다.
URL 변환 기능은 내부 웹 서버의 구성에 따라 다양하게 존재하는 물리적인 URL 주소를 외부에 노출되는 단일한 URL 주소로 변환해 외부에서 내부 웹 서버의 구성을 알 수 없도록 해주는 기능이다.
예를 들어 (그림 7)과 같이 2개의 웹 서버가 있고 각각의 주소가 ‘a.###.com’이고, ‘b.###.com’일 경우, 이를 각각 ‘www.###.com/cgi-bin/’과 ‘www.###.com/image’로 자동 변환한다면 외부에서는 실제로 2개의 웹 서버에 컨텐츠가 분리된 상태로 존재한다는 사실을 알 수 없고, 하나의 웹 서버로 인식하게 될 것이다. 이런 추상적인 계층화는 웹 서버의 구성 변경을 자유롭게 할 수 있도록 해주는 보안성 이외의 효과도 있다.

서버 정보 변조 기능은 서버에서 응답(response)를 클라이언트에게 제공할 때, 응답 헤더에 포함되는 서버 정보 관련 헤더들을 삭제하거나 사용자가 설정한 값으로 변조하는 기능이다.
일반적으로 공격자들은 성공적인 공격을 위해서 스캐닝을 통해서 웹 서버의 종류와 버전을 미리 알아낸 후에 그에 해당하는 공격을 수행한다. IIS 서버에는 IIS 서버의 해당 버전에 맞는 공격 코드를 실행하고, 아파치 서버라면 아파치 서버의 해당 버전에 맞는 공격 코드를 실행하는 것이다. 이런 경우 웹 파이어월에 의해 조작된 서버 정보를 이용해 공격자를 방해할 수 있다. 특히 자동화된 취약점 공격 툴을 사용하는 공격자라면 변조된 서버 정보에 의해 공격을 성공시키는 것이 더욱 어려울 것이다.

컨텐츠 보호 기능
초기 웹 파이어월은 웹 애플리케이션에 대한 해킹을 통해 웹 서버로의 침입을 막는데 중점을 두고 개발됐다. 지금도 이 사실에는 변함이 없지만, 개인 정보 보호의 중요성이 높아지면서 점점 웹 애플리케이션 내부에 저장된 컨텐츠의 보호에 대한 요구도 높아지고 있다. 그래서 현재 상용 웹 파이어월에는 대부분 컨텐츠의 불법적인 유출을 막는 컨텐츠 보호 기능이 탑재돼 있다.
컨텐츠 보호 기능은 다양하지만 가장 인기 있는 것은 주민등록번호나 신용카드 정보의 유출 차단 기능이다. 이것은 SQL 삽입과 같은 웹 애플리케이션에 대한 공격의 결과로 데이터베이스에 저장돼 있는 고객들의 개인 정보의 유출을 차단하는 기능이다.
이 기능은 일반적으로 정규식과 같은 형식의 룰을 사용해 서버의 응답을 검사한다. 예를 들면 주민등록번호는 다음과 같은 정규식을 사용해 응답을 검사한다.

[[:digit:]]{6} [[:digit:]]{7}
[[:digit:]]{6}-[[:digit:]]{7}

정규식을 이용한 매칭 이외에도 주민등록번호와 같이 규칙이 있는 패턴의 경우에는 별도의 검사 루틴이 포함돼 오탐지율을 줄이기도 한다.

반응형