[HTTP_NETWORK] 웹 공격 기술

업데이트:

HTTP 자체는 보안 상의 문제가 일어날 정도로 복잡한 프로토콜이 아니기 떄문에 프로토콜 자신이 공격대상이 되는 경우는 거의 없다. 공격 대상은 HTTP를 사용하는 서버와 클라이언트 그리고 서버 상에서 동작하는 웹 애플리케이션 등의 리소스이다. 현재 인터넷에서 벌어지는 대부분의 공격이 웹 사이트를 노린 것이다. 그 중에서도 특히 웹 애플리케이션을 대상으로 많은 공격이 발생하고 있다. 이번 시간에는 주로 웹 애플리케이션에 대한 공격에 대해 알아보자.


현재 웹 사이트 대부분은 인증이나 세션관리, 암호화 등의 보안 기능이 필요하지만 이들은 HTTP에는 존재하지 않았다. HTTP는 구조가 단순한 프로토콜로 장점도 많이 있지만 보안에 관해서는 나쁜 면이 많이 있다. 원격 접속으로 사용하는 SSH라는 프로토콜에는 프로토콜 레벨에서 인증이나 세션관리 등의 기능이 준비되어 있지만 HTTP에는 없다. 또한 SSH 서비스 셋업은 누구나 쉽게 구축할 수 있지만 HTTP는 웹 서버가 설치되었다고 해도 웹 애플리케이션의 대부분은 처음부터 개발하게 된다.

때문에 웹 애플리케이션에서 인증이나 세션 관리 기능을 개발자가 설계하고 구현할 필요가 있다. 개발자마다 제각각으로 설계하기 때문에 각기 다르게 구현되고 이로 인해 공격자가 악용할 수 있는 취약성을 지닌 상태로 가동되고 있는 웹 애플리케이션들이 있다.

1. 웹 애플리케이션 공격 패턴

웹 애플리케이션 공격 패턴은 크게 두 가지로 나눌 수 있다.

1) 서버를 노리는 능동적 공격

  • 능동적 공격은 공격자가 직접 웹 애플리케이션에 액세스해서 공격 코드를 보내는 타입의 공격. 서버 상의 리소스에서 직접 실행되기 때문에 공격자가 리소스에 액세스 할 필요가 있음. 대표적으로 SQL 인젝션과 OS 커맨드 인젝션 등이 있다.

2) 유저를 노리는 수동적 공격

  • 수동적 공격은 함정을 이용해 유저에게 공격 코드를 실행시키는 공격. 사용자가 함정에 걸리면 HTTP 리퀘스트를 공격 대상인 웹 애플리케이션에 송신하고 공격코드를 실행. 취약성이 있는 웹 애플리케이션을 경유한 결과로 유저가 가지고 있는 쿠키 등의 기밀 정보 또는 로그인중인 유저의 권한을 악용. 대표적으로 크로스 사이트 스크립팅, 크로스 사이트 리퀘스트 포저리 등이 있음

  • 수동적 공격을 이용하면 인트라넷 같은 인터넷에서 직접 액세스 불가능한 네트워크를 공격할 수도 있다. 공격자가 설치한 함정에 빠진 유저가 액세스 할 수 있는 네트워크라면 어디든 공격이 가능하다.

2. 출력 값의 취약성

웹 애플리케이션의 보안 대책을 실시하는 장소는 크게 클라이언트와 웹 애플리케이션(서버)로 분류할 수 있다.

클라이언트에서의 체크는 대부분 JavaScript를 사용한다. 그러나 변조되었거나 무효화 가능성이 있어 근본적인 보안 대책으로는 적합하지 않다. 클라이언트 측의 체크는 입력 실수를 지적해주는 정도, 즉 UI 향상을 위한 정도로 사용한다.

1) 크로스 사이트 스크립팅

취약성이 있는 웹 사이트를 방문한 사용자의 브라우저에서 부정한 HTML 태그나 JavaScript 등을 동작시키는 공격.

동적으로 HTML을 생성하는 부분에서 취약성이 발생할 수 있다. 이는 공격자가 작성한 스크립트가 함정이 되고 유저의 브라우저 상에서 움직이는 수동적 공격이다.

  • 가짜 입력 폼 등에 의해 유저의 개인정보 유출
  • 스크립트에 의해 유저의 쿠키를 유출하거나 피해자가 의도치 않은 리퀘스트 송신
  • 가짜 웹 페이지 표시

발생하는 장소는 동적으로 HTML을 생성하는 곳이다. ID와 패스워드를 입력하는 화면을 보여주면 유저는 기존과 동일한 화면이라 생각할 수 있지만 데이터 전송시 스크립트를 통해 공격자의 사이트로 이를 보낼 수 있다. 그 후에 원래 사이트에 ID와 패스워드를 전송하여 로그인을 하면 유저는 정보가 유출되었다는것도 눈치채기 어렵다.

2) SQL 인젝션

웹 애플리케이션이 이용하는 데이터베이스에 SQL을 부정하게 실행하는 공격. 개인 정보나 기밀 정보 누설로 이어질 수 있다.

대부분의 웹 애플리케이션은 데이터베이스를 이용하고 있고 테이블 내의 데이터 검색 및 추가, 삭제가 발생하는 경우 SQL을 사용해 데이터베이스에 액세스 한다. SQL 호출 방법이 잘못된 경우 의도치 않은 SQL문이 삽입(인젝션)되어 실행되어버리는 경우가 있다.

  • 데이터베이스 내의 데이터 부정 열람이나 변조
  • 인증 회피
  • 데이터베이스 서버를 경유한 프로그램 실행 등

예를 들어 도서검색 사이트에서 ‘bonobono’를 검색하면 내부적으로 아래의 쿼리가 실행된다고 생각해보자.

SELECT * FROM BookTable WHERE author='bonobono' and useFlag = 'Y';

위 쿼리는 저자가 bonobono 이면서 현재 판매중인 도서만 검색하도록 지시한다.

‘bonobono’라고 검색했던것을 ‘bonobono’–‘로 변경 후 검색하면 쿼리는 아래와 같다.

SELECT * FROM BookTable WHERE author='bonobono'--' and useFlag = 'Y';

SQL에서 – 이후의 문자는 주석으로 처리된다. 따라서 판매중이 아닌 도서도 검색되게 된다.

3) OS 커맨드 인젝션

웹 애플리케이션을 경유하여 OS 명령을 부정하게 실행하는 공격이다. 웹 애플리케이션은 OS에서 사용되는 커맨드를 쉘을 경유해서 실행할 수 있다. 쉘을 호출하는 부분에 취약한 부분이 있다면 잘못된 OS 커맨드가 실행되어 버리는 경우가 있다.

4) HTTP 헤더 인젝션

HTTP 헤더 인젝션은 공격자가 리스폰스 헤더 필드에 개행 문자 등을 삽입해서 임의의 리스폰스 헤더 필드나 바디를 추가하는 수동적 공격이다.

  • 임의의 쿠키 Set
  • 임의의 URL에 리다이렉트
  • 임의의 바디 표시

HTTP 바디를 추가하는 공격을 HTTP 리스폰스 분할 공격이라 부르는데 가짜 웹 페이지를 표시해 개인정보를 입력받거나 크로스 사이트 스크립팅과 같은 효과를 얻을 수 있다. 또한 HTTP/1.1의 복수 리스폰스를 모아 돌려보내는 기능을 아용해서 캐시 서버 등에 임의의 콘텐츠를 캐시하는것도 가능하다. 이 캐시서버를 이용하는 유저는 공격을 받은 사이트를 열람하면 바뀐 웹 페이지를 계속해서 참조하게 된다.

5) 메일 헤더 인젝션

웹 애플리케이션의 메일 송신 기능에 공격자가 임의의 To 및 Subject 등의 메일 헤더를 부정하게 추가하는 공격이다. 취약성이 있는 웹 사이트를 이용해 스팸 메일이나 바이러스 메일 등을 임의의 주소에 송신할 수 있다.

공격자는 메일 주소로 아래의 데이터를 리퀘스트로 보낸다.

bonobono@1q1w.io%0D%0ABcc:user@sample.com

%0D%0A는 개행 문자를 의미하며 문의 양식 폼이 개행문자를 수신하면 본래 지정할 수 없는 Bcc에 수신처를 추가할 수 있다. 또 아래와 같이 개행 문자를 두 개 연속해 ㅁ일의 본문을 변조해서 보낼 수도 있다.

bonobono@1q1w.io%0D%0A%0D%0ATestAddMessage
6) 디렉토리 접근 공격

비공개 디렉토리 파일에 부정하게 디렉토리 패스를 가로질러 액세스하는 공격. 패스 트래버설(Path Traversal)이라 부르기도 한다.

웹 애플리케이션 파일을 조작하는 처리에서 파일 이름을 외부에서 지정하는 부분이 취약한 경우 유저는 ‘…/’ 등으로 상대 경로를 지정하거나 ‘/etc/pswd’ 등의 절대 경로를 지정해 임의의 파일이나 디렉토리에 액세스 할 수 있다. 이로 인해 웹 서버 상의 파일이 잘못 열람되어버리거나 변조 또는 삭제될 수도 있다.

7) 리모트 파일 인클루션

스크립트의 일부를 다른 파일에서 읽어올 때 공격자가 지정한 외부 서버의 URL을 파일에서 읽게 함으로써 임의의 스크립트를 동작시키는 공격. 주로 PHP에서 발생하는 취약성으로 PHP의 include와 require 설정에 따라 외부 서버의 URL을 파일명으로 지정할 수 있는 기능이다. 위험한 기능이기 때문에 PHP 5.2.0 이후에서는 초기에 무효로 설정되어 있다.

3. 웹 서버의 취약성

1) 강제 브라우징

웹 서버의 공개 디렉토리에 있는 파일 중 공개 의도가 없는 파일이 열람되는 것을 강제 브라우징이라 한다.

  • 고객 정보 등 중요 정보 누설
  • 액세스 권한이 없는 사용자에게 정보 누설
  • 링크되지 않은 파일 누설

공개하고싶지 않은 파일의 URL을 숨기는 보안 대책에 의존하는 경우 해당 URL을 알게 되면 파일을 열람할 수 있게 된다.

인증이 필요한 웹 페이지에서 이용되는 파일의 URL을 직접 지정해서 액세스할 수도 있다.

2) 부적절한 에러메시지

공격자에게 유익한 정보가 에러메시지에 담기는 경우, 공격자는 이를 가지고 힌트를 얻어 공격을 할 수 있다.

예를 들어 ID, 패스워드로 로그인하는 경우 ID가 존재하면 패스워드가 잘못되었다고 보여주고 ID가 존재하지 않으면 ID가 없다고 표시한다면 이는 ID의 유무를 확인할 수 있는 힌트가 된다.

또한 데이터베이스 등의 시스템에 대한 에러메시지를 그대로 보여주게 되면 어떤 데이터베이스를 사용하는지도 알 수 있고 쿼리의 일부를 공격자가 취득할 수 있게 된다. 이를 통해 SQL 인젝션 등의 추가 공격이 가능할 수도 있다. 따라서 에러 메시지가 공격 힌트로 이용되지 않게 하려면 각 시스템 설정에 의한 상세 에러 메시지를 제한하거나 커스텀 에러메시지를 제공해야 한다.

3) 오픈 리다이렉트

오픈 리다이렉트는 지정한 임의의 URL로 리다이렉트 하는 기능이다. 리다이렉트되는 곳의 URL에 악의가 있는 웹 사이트가 지정된 경우 유저가 그 웹 사이트로 접속하게 된다. 유저가 신뢰하는 사이트에 오픈 리다이렉트 기능이 있다면 피싱 사이트로 연결되는 등 가짜 웹 페이지로 연결 할 수 있게 된다.

4. 세션 관리 미비로 인한 취약성

세션은 유저의 상태를 관리하기 위한 기능이지만 만약 관리가 취약하다면 유저 인증 상태를 빼앗겨버리게 된다.

1) 세션 하이잭

공격자가 어떠한 방법으로 유저의 세션ID를 입수해 유저로 위장하는 공격. 인증 기능이 있는 웹 애플리케이션에서는 세션 ID를 사용해 인증 상태를 관리하는 방법이 대부분이다. 클라이언트에서는 쿠키 등에 세션 ID를 기록하고 서버에서는 세션ID와 인증 상태를 연동해서 관리한다. 공격자가 세션ID를 입수하는 방법은 다음과 같다.

  • 부적절한 생성 방법에 의한 세션 ID 추측
  • 도청이나 XSS 등에 의한 세션 ID 도용
  • 세션 고정 공격에 의한 세션 ID 강제

인증된 유저는 세션ID를 브라우저의 쿠키에 가지고 있게 된다. 공격자는 크로스 사이트 스크립팅을 통해 document.cookie를 공격자에게 송신하는 스크립트 함정을 설치하고, 유저가 함정에 걸리면 세션ID를 포함한 쿠키 정보를 공격자에게 빼앗기게 된다. 공격자는 브라우저의 쿠키에 세션ID를 세팅하고 웹 사이트에 액세스하여 유저로 위장할 수 있다.

2) 세션 픽세이션

세션 하이잭이 세션ID를 빼앗는 공격이라면 세션 픽세이션은 공격자가 지정한 세션ID를 유저에게 강제적으로 사용하게 하는 공격으로 수동적 공격이다. 세션 고정 공격이라고도 불린다.

공격자는 함정 준비를 위해 웹 사이트에 액세스해서 세션ID를 입수한다. 이 때 세션ID는 서버 상에서 인증 전 상태로 기록된 상태이다. 그 다음으로 이 세션ID를 유저가 강제적으로 이용하도록 함정을 준비하고 유저가 해당 세션ID로 인증하도록 기다린다. 유저가 인증을 마치면 공격자는 해당 세션ID로 유저가 접속한 것처럼 웹 사이트에 액세스 할 수 있다.

3) 크로스 사이트 리퀘스트 포저리

인증된 유저가 의도하지 않은 개인정보나 설정 정보 등을 공격자가 설치해둔 함정에 의해 임의의 액션을 취하는 공격으로 수동적 공격에 해당한다.

  • 인증된 유저 권한으로 설정 정보 갱신
  • 인증된 유저 권한으로 상품 구입
  • 인증된 유저 권한으로 게시글 작성 등

5. 그 외 취약성

1) 패스워드 크래킹

패스워드를 논리적으로 이끌어내 인증을 하는 공격이다. 패스워드 크래킹에는 다음과 같은 방법이 있다.

  • 네트워크 경유로 패스워드 시행
  • 암호화된 패스워드를 해독 (공격자가 암호화나 해시화된 패스워드 데이터를 취득한 상황)

이 외에도 SQL 인젝션으로 인증을 회피하거나 크로스 사이트 스크립팅 등으로 유저를 속여 패스워드를 훔치는 방법이 있다.

네트워크 경유로 패스워드 후보를 시험해보는 공격은 무차별 대입 공격과 사전 공격이 있다. 무차별 대입 공격은 모든 패스워드 후보를 시험해서 인증을 돌파하는 공격이다. 예를 들어 은행의 비밀번호같은 4자리 비밀번호는 0000~9999 까지의 모든 후보를 시험한다. 그러면 후보 중 올바른 패스워드가 존재하므로 인증을 통과할 수 있다. 무차별 대입 공격은 모든 후보를 시험하므로 반드시 패스워드를 해독할 수 있는 공격이지만 범위가 큰 경우 해독하는데 몇천년이 걸릴 수도 있어 현실적으로 공격이 어려운 방법이다.

사전 공격은 사전에 패스워드 후보를 준비해두고 이를 가지고 인증을 돌파하는 공격이다. 패스워드가 4자리라면 생일일 가능성이 크다. 이 경우 0101~1231 사이의 숫자를 사전적으로 테스트한다. 시험할 후보의 수가 적어 공격에 시간이 단축될 수 있다. 공격의 성공 여부는 패스워드 후보에 따라 좌우된다.

누설된 다른 곳의 ID/패스워드를 이용해 공격하는 경우 높은 확률로 성공하게 된다.

암호화된 패스워드 해독

웹 애플리케이션으로 이용하는 패스워드를 보존하는 경우, 패스워드를 평문 그대로 보존하지 않고 해시 함수를 통해 해시화나 salt 등의 방법으로 암호화를 한다. 결국 공격자가 패스워드 데이터를 훔치더라도 이를 해독하거나 평문을 손에 넣어야 한다. 암호화된 데이터로붜 평문을 도출하는 방법은 다음과 같다.

  • 무차별 대입 공격/사전 공격에 의한 유추 : 해시 함수를 입수한 경우 패스워드 후보에 같은 해시 함수를 적용해 시험해보면서 해시 값을 만들어내서 패스워드를 유추할 수 있다.
  • 레인보우 테이블 : 평문과 그에 대응하는 해시값으로 구성된 데이터베이스 테이블. 사전에 거대한 테이블을 만들어 무차별 대입공격/사전 공격에 걸리는 시간을 단축하는 테크닉. 거대한 테이블이 필요하며 FreeRainbowTable 에서 배포하고 있는 레인보우 테이블은 대소 영문자와 숫자1~8 문자로 조합할 수 있는 모든 MD5에 해당하며 약 1050GB 파일 사이즈이다.
  • 열쇠 입수 : 패스워드의 데이터가 공통키 암호 등으로 암호화된 경우 해당 키를 입수하면 복호화가 가능
  • 암호 알고리즘의 취약성을 파고들어 직접 해독 : 가능성이 낮은 방법이지만 독자적 암호 알고리즘의 경우 검증되지 않은 취약성이 존재할 수 있음
2) 클릭 재킹

투명한 버튼이나 링크를 함정으로 사용할 엡 페이지에 심어두고 유저에게 클릭하게 함으로써 의도치 않은 콘텐츠에 액세스시키는 공격. UI Rendressing 이라 부르기도 한다.

예를 들어 웹 페이지의 어떤 버튼에 투명한 레이어를 씌워 실제로 클릭하면 다른 액션을 취하도록 하는 방식이다.

3) DoS 공격

서비스 제공을 정지 상태로 만드는 공격. 웹 사이트 뿐 아니라 네트워크 기기나 서버 등을 대상으로 공격하는 경우도 있다.

  • 액세스를 집중시켜 부하를 걸어 리소스를 다 소비하게 만들어 서비스를 정지 상태로 만든다
  • 취약성을 공격해 서비스를 정지시킨다

DoS공격은 대량의 액세스를 보낸다는 점에서 단순해 보이지만 공격 이외의 정상적인 액세스와 구별이 힘들어 방지하는 것이 쉽지는 않다. 여러 대의 컴퓨터에서 실행하는 DoS 공격은 DDos 공격이라 불리며, 바이러스 등에 감염된 컴퓨터가 공격자에 의해서 공격에 이용되곤 한다.

4) 백도어

제한된 기능을 정규 절차를 밟지 않고 이용하기 위해 설치된 뒷문으로 생각하면 된다. 백도어시 정해진 기능 이외의 기능을 이용하는 것이 가능하다.

  • 개발 단계에 디버그용으로 추가한 백도어
  • 개발자가 자기 자신의 이익을 위해 추가한 백도어
  • 공격자가 설치한 백도어

백도어용 프로그램이 설치된 경우 프로세스나 통신을 감시해서 발견하는 것도 가능하지만, 웹 애플리케이션을 수정해서 설치한 백도어는 정상적으로 이용하는 것과 구별이 어려워 발견하기 쉽지 않다.