웹은 본질적으로 점차 그 사회성이 높아지고 있지만, 반대로 보안은 취약해지는 경향이 있다. 실제로 WASC(Web Application Security Consortium)에서는 2009년 초기에 전체 웹 사이트의 87%가 공격에 취약한 것으로 추정했다(참고자료에서 자세한 정보에 대한 링크 참조). 일부 회사의 경우에는 외부 보안 분석가를 고용하여 위험성을 테스트할 수 있는 여력이 있지만 외부 보안 감사를 위해 2만 - 4만달러에 달하는 비용을 감당할 수 없는 회사도 많이 있다. 대신 이러한 회사에서는 위협을 파악하여 취약성 없는 코드를 만들기 위해 자사 개발자에게 의존하고 있다.
보안 코드를 작성하려면 먼저 현재 작업이 어떤 위협에 노출되어 있는지 파악해야 한다. 이 기사에서는 교차 사이트 스크립팅 및 SQL 삽입과 같이 잘 알려져 있는 일부 취약성을 살펴본 후 사이트뿐만 아니라 사이트와 관련된 데이터 및 네트워크까지도 보호할 수 있는 도구에 대해 설명한다. 이 기사는 보안 분석가를 대신하거나 핵심 보안 스킬을 알려주기 위한 것은 아니다. 대신 이 기사에서는 주로 코드에서 악용될 가능성이 있는 부분을 찾아내서 취약성을 해결하는 방법에 대해 설명한다.
우선, 앞으로 검색할 일부 취약성을 살펴볼 필요가 있다. 가장 먼저 살펴볼 내용은 현재까지 가장 널리 알려진 취약성인 XSS(cross-site scripting)이다. XSS는 웹 사이트에 삽입 중인 악성 스크립트로 인해 발생한다. 예를 들어, Mallory가 사용자를 신뢰할 수 있는 Alice의 웹 사이트로 보내는 스크립트를 작성한 후 유명한 포럼에 삽입해 놓았다고 가정해 보자. 이제 Bob이 포럼에서 이 링크를 보고 클릭하여 Alice의 웹 사이트에서 계정을 작성하게 되면 Alice의 웹 사이트에 있는 XSS 결점을 악용하고 있던 이 스크립트가 Bob의 쿠키를 Mallory에게 보낸다. 이제 Mallory는 자신이 Bob인 것처럼 가장하여 그의 정보를 빼낼 수 있다.
SQL 삽입은 두 번째로 유명한 취약성으로, 주로 데이터베이스에 대한 웹 사이트의
의존성이 높아지면서 많이 악용되고 있다. SQL 삽입은 실제로 매우 단순한 공격 방법으로, 악의를
지닌 해커가 데이터베이스에 연결하는 웹 사이트를 찾은 다음 인증을 빠져나가거나 데이터를 조작하기
위해 개발자가 의도하지 않았던 위치에서 SQL 쿼리를 실행하는 공격이다. 이 유형의 공격이 바로
Albert Gonzalez가 1억 3천만 개의 신용 카드 번호를 훔칠 때 사용한 방법이었다. SQL 삽입 공격을
위해 Mallory는 전자기기를 판매하는 Alice의 웹 사이트를 발견한 후 일반적으로 사용되는 사용자
이름과 암호 조합을 입력하는 대신 ') OR 1=1-을 사용자 이름으로
입력한다. 이렇게 하이픈(-)을 포함시키기만 하면 된다. 1=1은
항상 true이기 때문에 성공적으로 로그인할 수 있다. 이제 그녀는 데이터베이스를 조작하여 Bob의
고객 정보를 빼낼 수 있다. 이 예에서 보여 주는 SQL 삽입이 가장 단순한 형태이기는 하지만 이
공격이 매우 쉽다는 것을 충분히 알 수 있을 것이다.
전문적인 보안 분석가 팀 없이 일반적인 웹 개발자가 이러한 취약성에 대처한다는 것이 불가능해 보일 수도 있을 것이다. 다행스럽게도 항상 불가능한 것은 아니다. 사이트의 잠재적 취약성을 찾아내는 데 사용할 수 있는 도구가 많이 있으므로 이러한 도구에서 필요한 단계를 수행하여 취약성을 예방할 수 있다. WebScarab 및 Paros와 같은 도구를 사용하면 브라우저와 서버 사이의 통신을 파악할 수 있을 뿐만 아니라 웹 사이트를 검색하여 잠재적 위험을 식별할 수도 있다. 그런 다음 이 정보를 분석하여 취약성을 검사한 후 필요한 대응 조치를 취할 수 있다.
OWASP(Open Web Application Security Project)에서 개발한 WebScarab은 브라우저 요청과 서버 응답을 분석하는 데 사용되는 최초의 프록시이다. 패킷 분석 기능을 제공하는 이 도구는 위에서 언급한 악용 코드를 찾기 위해 사이트를 "퍼지"하는 데도 사용할 수 있다. WebScarab을 사용하려면 먼저 웹 브라우저의 프록시 설정을 구성해야 한다. Mozilla Firefox의 경우 다음 단계를 수행한다. (Firefox keyboard shortcuts에서 메뉴에 빠르게 액세스하는 방법을 찾아볼 수 있다.)
- 도구 > 옵션 > 고급 > 네트워크를 클릭한다.
- 설정을 클릭한다.
연결 설정 창이 열린다.
- 프록시 수동 설정 옵션을 선택한다.
- HTTP 프록시와 SSL 프록시에
localhost를 입력하고 포트를 8008로 설정한다. - 프록시 사용 안 함 상자가 비어 있는지 확인한 다음 확인을 클릭한다.
그림 1에서는 Firefox의 연결 설정을 보여 준다.
그림 1. Firefox 연결 설정
Windows® Internet Explorer®의 경우 다음 단계를 수행한다. (IE 도움말 메뉴의 Internet Explorer 키보드 바로 가기 항목에서 메뉴에 빠르게 액세스하는 방법을 찾아볼 수 있다.)
- 도구 > 인터넷 옵션 > 연결을 클릭한다.
- LAN 설정을 클릭하여 프록시 설정 창을 연다.
- 프록시 서버에서 사용자 LAN에 프록시 서버 사용 선택란을 선택한 다음 고급을 클릭한다.
- HTTP와 Secure에 대한 사용할 프록시 주소 항목에
localhost를 입력한 다음 포트 항목에8008을 입력한다. - 예외 상자가 비어 있는지 확인한 다음 확인을 클릭한다.
그림 2에서는 Internet Explorer의 프록시 설정을 보여 준다.
그림 2. 프록시 설정하기
이제 웹 사이트를 검색할 준비가 완료되었다.
다음 예제에서는 Hacme Casino 사이트를 사용한다. Foundstone에서 교육용으로 사용하기 위해 작성한 이 사이트에는 특정 취약성이 포함되어 있다(참고자료 참조). 이 사이트는 Apache Tomcat에 패키지로 포함되어 있으므로 원하는 경우 로컬에서도 실행할 수 있다.
그런 다음 WebScarab을 연다. WebScarab이 실행되면 Summary와 Intercept라는 두 탭이 표시된다. WebScarab을 사용하여 퍼지 작업을 수행할 것이므로 Tools > Use full-featured interface > OK를 클릭하여 보기를 변경한다. 그러면 WebScarab을 다시 시작할지 묻는 메시지가 표시된다. WebScarab이 다시 시작되면 그림 3과 같은 인터페이스가 표시된다. (WebScarab에서도 단축키를 사용할 수 있다. 하지만 아쉽게도 두 개뿐이다.)
그림 3. WebScarab 인터페이스
새 세션을 시작하려면 File > New를 클릭한다. 세션을 저장할 위치를
묻는 상자가 표시된다. 저장소 디렉토리를 선택하거나 작성한 다음 OK를 클릭한다. WebScarab을
Hacme Casino와 함께 사용할 경우에는 서버를 시작한 후 브라우저를 연다. 그런 다음 브라우저의
주소 표시줄에 http://localhost:3000을 입력한다.
WebScarab은 브라우저와 서버 사이의 요청과 응답을 모두 캡처하므로 브라우저를
연 후 WebScarab의 일부 활동이 표시되어야 한다. 퍼지 기능을 사용하여 취약성을 테스트할 것이므로
다양한 취약성이 존재할 수 있는 위치를 먼저 검색한다. 먼저 악용될 가능성이 있는 로그인부터
살펴본다. 로그인을 테스트하려면 브라우저와 서버 사이에서 발생한 상호 작용을 기록해야 한다. 여기에서는
원하는 사용자 이름과 암호를 입력할 수 있으므로 유효한 로그인이 필요하지 않다. 이 예제의 경우에는
casino를 사용자 이름과 암호로 입력한 다음 Login을 클릭한다.
물론 로그인이 실패할 것이다. 하지만 여기에서는 로그인의 성공 여부에 관심을 두지 않아도 된다. 대신 WebScarab으로 돌아간다. 그런 다음 Path 열에서 account\login을 마우스 오른쪽 단추로 클릭하고 Use as fuzz template를 클릭한다(그림 4 참조).
그림 4. 퍼지 템플리트
다음 단계를 수행한다.
- WebScarab 인터페이스의 맨 위에 있는 Fuzzer 탭을 클릭한다.
- Source를 클릭한다.
- 사용자 사전이 있는 위치로 이동한다. (이 예제에서는 all_attack.txt를 사용한다. 참고자료에서 링크를 볼 수 있다.)
- 소스에 대한 설명을 입력하고 Add를 클릭한다.
- Close를 클릭하여 Fuzzer 창으로 돌아간다.
이제 user_login 매개변수로 이동한 후 Fuzz Source
열 아래에 있는 영역을 클릭한다. All attack이라는 하나의 소스만 로드했으므로 드롭 다운 메뉴에서
All attack을 선택한다. user_password 매개변수에 대해서도 같은 작업을
수행한다(그림 5 참조).
그림 5. 공격 파일 선택하기
이제 소스를 정의했으므로 Start를 클릭하여 프로세스를 시작한다. 퍼저가 파일의 매개변수를 사용자 이름 및 암호 입력에 삽입한다. 도구가 각 시도를 완료할 때마다 화면에 일부 활동이 표시되어야 한다. 일반적으로 결과에 있는 각 ID를 조사하여 각 시도에서 발생한 작업을 분석해야 한다. 하지만 추가된 문자열이 결과를 생성할 것을 알고 있으므로 퍼저가 성공할 때 발생할 수 있는 결과를 확인할 수 있다.
예제의 첫 번째 문자열을 더블 클릭한다(그림 6 참조).
그림 6. 취약성 찾기
위쪽 원을 보면 user_login 및 user_password의
값이 ') OR 1=1--이라는 것을 알 수 있다. 그리고 위치가 홈 페이지를
나타내는 http://localhost:3000에서 성공적으로 로그인한 사용자에게
표시되는 http://localhost:3000/lobby/games로 변경되었다. 이렇게
위치가 변경되었다는 것은 사이트에 취약성이 있다는 것을 의미한다. ') OR 1=1--은
SQL 문자열이므로 이 사이트는 SQL 삽입에 취약하다. Next 단추로 결과를 스크롤하면서
해당 값을 찾아보자. 여기에는 위치가 http://localhost:3000으로
그대로 남아 있다. 이 결과를 보면 이 유형의 문자열을 삽입했을 때 로그인이 성공하지 못했음을
알 수 있으며, 이는 사이트가 이 유형의 공격에 취약하지 않다는 의미이다.
Paros Proxy는 보안 테스트에 유용한 또 다른 도구이다. WebScarab과 마찬가지로 Paros는 분석을 위해 브라우저와 서버 사이의 통신을 캡처한다. 또한 Paros를 사용하여 사이트의 취약성을 테스트할 수 있다. Paros를 실행하려면 브라우저의 프록시 설정에 사용되는 포트 번호를 변경해야 한다. WebScarab에서는 8008을 사용했지만 Paros를 실행하기 전에 이 포트를 8080으로 변경해야 하며, 그렇지 않은 경우에는 도구가 작동되지 않는다. 이를 실습하기 위해 예제에서는 OWASP의 또 다른 도구인 WebGoat를 사용한다(참고자료 참조). Hacme Casino와 마찬가지로 WebGoat는 Tomcat 서버를 로컬 호스트로 사용하여 실행된다. 이 기사의 목적 상 WebGoat는 Hacme Casino보다 더 많은 취약성을 Paros 스캔에서 보여 준다.
포트를 변경한 후 Paros를 연다. 이제 다음 단계를 수행한다.
- WebGoat 폴더에서 WebGoat.ba를 더블 클릭하여 Tomcat을 시작한다.
- 브라우저를 열고
http://localhost/WebGoat/attack을 입력한다. guest를 사용자 이름과 암호로 입력한다.- Start WebGoat를 클릭한다.
이제 Paros로 돌아가서 WebGoat 사이트에 대한 스캔을 시작한다. 물론 WebGoat 사이트 주소 대신 사용자 사이트의 주소를 주소 표시줄에 입력할 수도 있다.
Paros에서 Sites 폴더를 펼친 후 트리에서 http://localhost를 찾는다. 이 폴더를 펼쳐서 WebGoat를 시작한다. WebGoat를 강조 표시한 후 Analyse Scan을 클릭한다. 이제 사이트에 대한 스캔이 즉시 시작된다. 큰 사이트의 경우에는 시간이 걸릴 수도 있지만 이 경우에는 몇 초만에 스캔이 완료된다. 스캔이 시작되면 아래쪽 분할창이 자동으로 Alerts 탭으로 변경된다(그림 7 참조). 스캔이 완료되면 보고서의 위치를 알려 주는 팝업 창에서 OK를 클릭한다.
그림 7. 경고 보기
경고를 펼쳐서 자세한 정보를 볼 수 있다. 또한 훨씬 더 자세한 정보를 제공하는 보고서를 볼 수도 있다. 하지만 먼저 File > Save As를 클릭하고 스캔할 위치와 파일 이름을 선택한 다음 Save를 클릭하여 스캔 결과를 저장한다.
보고서를 보려면 Report > Last Scan Report를 클릭한다. 팝업 창에서 OK를 클릭한다. 그러면 새 브라우저 탭이 열리면서 스캔 결과를 보여 주는 보고서가 표시된다(그림 8 참조). 이 보고서에는 특정 악용 방법에 대해 다루는 OWASP 페이에 대한 참조를 비롯하여 검색된 각 취약성과 관련된 자세한 정보가 들어 있다.
그림 8. Paros 보고서
스캐너를 통해 웹 사이트의 잠재적 취약성을 찾는 것도 좋은 방법이기는 하지만 유수한 보안 회사에서는 항상 거짓 긍정과 관련된 잠재적 취약성을 직접 테스트한다. 이러한 잠재적 취약성을 테스트한다는 것은 실제로 취약한 것으로 보고된 사이트의 영역으로 이동하여 SQL 코드나 스크립트를 해당 사이트에 삽입하여 그 응답을 확인한 후 사이트 자체로 이동하여 공격을 시도해 보는 것을 의미한다. 대규모 회사에서는 이 유형의 테스트(취약성 검증이라고 함)를 전문적으로 처리하는 프로그래머를 고용하기도 하지만 개발자가 이러한 테스트 중 일부를 직접 수행할 수 있다면 여러 모로 유용할 것이다. 이러한 테스트는 현재 사이트의 보안을 강화하는 데도 도움이 되지만 향후 여러 사이트를 개발할 때도 많은 도움이 될 것이다.
이제
Hacme Casino 사이트를 다시 한번 사용하여 WebScarab에서 검색되었던 취약성인 로그인에서의 SQL 삽입
공격을 살펴보자. Hacme Casino가 실행 중인 상태에서 WebScarab에서 성공적으로 사용했던 SQL 코드인
‘) OR 1=1--을 사이트의 Login 입력 영역에 입력한다. Login을
클릭하면 Andy_Aces 계정이 열린다. 이 경우에는 1=1이 true로 평가되므로
가장 기본적인 형태의 SQL 삽입이 작동한다. 이 예제에서는 Andy가 데이터베이스의 첫 번째 계정이라는
이유로 피해를 입게 된다.
그렇다면 이 SQL 코드가 어떻게 작동했던 것일까? 백엔드에서 데이터베이스는 다음과 같은 쿼리를 실행한다.
SELECT * FROM users WHERE (username=username AND password=password) |
Login 상자를 통해 삽입된 코드는 다음과 같은 유효한 쿼리로 변경된다.
SELECT * FROM users WHERE (username=’’) OR 1=1—AND password=’’) |
이 쿼리는 사이트의 첫 번째 사용자에 대한 로그인 성공을 리턴하며, 불행하게도 이 사용자가 Andy이다.
물론 이 예제에서 다루는 내용은 SQL 삽입의 일부에 불과하다. 웹 사이트 공격 스킬 수준이 높다면 실제로 이 취약성을 악용하여 사용자를 작성하고, 암호를 변경하고, 사이트의 중요 데이터를 추출할 수 있다. 이러한 공격으로부터 사이트를 보호하려면 다음과 같은 몇 가지 단계를 수행해야 한다.
- 문자열 연결을 사용하지 않고 매개변수화된 쿼리나 저장 프로시저를 사용하여 데이터베이스에 액세스한다. 매개변수화된 쿼리를 사용하려면 모든 SQL 코드를 정의한 후 나중에 각 매개변수를 쿼리에 전달해야 한다. 이렇게 하면 데이터베이스가 제공된 사용자 입력의 유형에 상관 없이 코드와 데이터를 구분할 수 있다. 저장 프로시저도 SQL 코드를 먼저 정의한 후 매개변수를 나중에 전달한다는 점에서 매개변수화된 쿼리와 비슷하다. 이러한 요소는 저장 프로시저에 대한 SQL 코드가 데이터베이스 자체에서 정의 및 저장된 다음 애플리케이션에서 호출된다는 점이 다르다.
- 허용 문자를 "화이트리스트"로 작성하여 악성 사용자 입력을 차단한다. 예를 들어, 이름을 요청할 경우 a-z와 A-Z만 허용하고, 전화번호의 경우 허용되는 문자를 0-9로 제한한다. 데이터베이스에서 지원되는 적합한 유효성 검증 기술을 사용하여 이를 수행한다.
- 데이터베이스에 설정된 문자 이스케이프 스키마를 사용하여 사용자가 제공하는 입력을 이스케이프한다. 특수 문자를 이스케이프하면 데이터베이스에서는 쿼리에 포함된 해당 문자를 코드가 아닌 데이터로 인식한다. 모든 사용자 제공 입력을 적합한 스키마에 따라 이스케이프하게 되면 해당 입력과 개발자가 작성한 SQL 코드가 데이터베이스에서 명확하게 구별된다.
- 공격자에게 일말의 여지도 남겨주면 안된다. 나중에 사이트에 대해 사용할 수 있는 정보가 오류 메시지에 포함되는 일이 없도록 해야 한다.
XSS
공격의 예를 살펴보기 위해 WebGoat로 돌아가자. Cross Site Scripting > LAB: Cross Site
Scripting > Stage 1: Stored XSS를 클릭하여 이 사이트를 시작한다. 사용자 이름
Larry Stooge와 암호 larry를 사용하여
데모 사이트인 Goat Hills Financial에 로그인한다. 이제 공격자라면 악성 스크립트를 입력할
수 있는 위치를 찾으려고 할 것이다. 아마도 Search Staff 기능에 이름을
입력할 수 있는 텍스트 상자가 있을 것이라는 생각이 들어서 Search Staff를 클릭하니
그림 9와 같이 이름을 입력할 수 있는 상자가 표시된다.
그림 9. XSS 진입점
Name 상자에 alert("You got me with XSS");를
입력한다. 이 스크립트는 그림 10과 같은 경고 상자만 표시하지만 만일
이 스크립트에서 주민등록번호, 집 주소, 은행 정보 등을 입력해야 하는 가짜 Humun Resources
사이트로 리디렉션하게 된다면 심각한 상황이 발생하게 될 것이다. OK 단추에 연결된
작업을 변경하여 이를 수행할 수 있다. 사용자가 악의적인 해커를 믿는 한 이러한 해커의 교묘한
술수는 그 끝을 헤아릴 수 없을 것이다.
그림 10. 성공적인 XSS 공격
XSS 공격을 차단하려면 모든 입력을 정리해야 한다. 나중에 입력이 운영 체제 명령, 스크립트 및 데이터베이스 쿼리에 대한 매개변수로 사용될 경우에는 사용자가 정리 작업을 직접 수행해야 한다. HTML 요소 컨텐츠 및 HTML 일반 속성에 삽입하기 전에 신뢰할 수 없는 데이터를 이스케이프하여 사용자 입력을 정리할 수 있다. OWASP에서는 256 미만의 모든 ASCII 값을 HTML 일반 속성으로 이스케이프하기를 권장한다. JavaScript™ 데이터 값, HTML 스타일의 특성 값 및 HTML 값 속성도 이스케이프할 수 있다. 물론 입력 데이터를 이스케이프하기 전에 웹 사이트에 대한 입력을 유효성 검증해야 한다. 특정 입력 값, 숫자, 문자, 이메일 주소 및 링크를 찾을 경우에는 이 유형의 데이터만 허용하고 다른 유형의 데이터를 거부한다.
웹 사이트에서 발생할 수 있는 일부 일반적인 공격을 찾으려면 이러한 공격의 작동 방식을 이해하고 있어야 한다. 공격자가 찾고 있는 허점을 알고서 이러한 취약성에 대비할 수 있다면 사이트의 빈틈을 노리고 들어오는 초보 공격자를 막을 수 있으며 조직화된 공격자라고 하더라도 심각한 문제를 일으키지는 못하게 할 수 있다. 이 기사에서 설명한 카운터 측정값과 수행된 스캔이 이러한 공격의 작동 방식과 공격을 예방하는 방법에 대한 단편만을 보여 주는 수준에 불과하지만 이 기사의 정보를 바탕으로 보다 나은 솔루션을 구축할 수 있을 것이다.
교육
-
Prevent
a cross-site scripting attack(Anand Sharma 저, developerWorks, 2004년 2월): 사이트에 대한 XSS 공격을 예방하는 방법에 대해 설명한다.
-
Secure
programmer: Validating input(David Wheeler 저, developerWorks, 2003년 10월): 보안 프로그램의 첫 번째 방어 단계 중
하나인 입력 유효성 검증에 대해 알아보자.
-
Web application security statistics: WASC에서는
"산업 전반에 걸쳐서 정리된 웹 사이트 취약성 데이터를 취합하여 웹 애플리케이션 취약성에 대한 분석 정보를 제공하기 위해
노력"하고 있다".
-
Website
Security Statistics: 웹 사이트 보안에 대한 WhiteHat Security의 6번째 보고서를 읽어보자.
-
developerWorks 웹 개발 영역: Web 2.0 개발과 관련된 도구와 정보를 볼 수 있다.
-
IBM
기술 행사 및 웹 캐스트: developerWorks 기술 행사 및 웹 캐스트를 통해 최신 정보를 얻을 수 있다.
- My developerWorks: 웹 개발을
비롯한 관심 분야에 대한 그룹, 블로그 및 활동을 찾아보거나 만들어보자.
제품 및 기술 얻기
-
Hacme Casino: Hacme Casino를 다운로드하여 이 기사에서 배운 스킬을 실습해 보자.
-
WebScarab and WebGoat: OWASP에서 테스트 사이트를 다운로드하자.
-
Paros Proxy: 이 도구를 다운로드하고 사이트를 스캔해 보자.
-
IBM 시험판 제품을
다운로드하여 DB2®, Lotus®, Rational®, Tivoli® 및 WebSphere®의 애플리케이션 개발 도구 및
미들웨어 제품을 사용하자.