이번 장에서는 웹 애플리케이션을 공격하는 기술들에 대해 알아본다.
1. 공격 패턴의 종류
공격의 종류는 크게 두 가지로 나눌 수 있다.
1-1. 능동적 공격
능동적 공격은 공격자가 직접 웹 애플리케이션에 공격을 시도하여 서버의 리소스를 탈취하려는 방식이다.
대표적인 예로 SQL 인젝션, OS 커맨드 인젝션, 디도스 등이 있다.
1-2. 수동적 공격
수동적 공격은 일반 사용자에게 공격 코드를 실행하도록 유도하는 공격 방식이다.
대표적인 예로 XSS(Cross-Site Scripting), CSRF(Cross Site Request Forgery) 등이 있다.
2. 여러 공격 패턴 이해하기
2-1. SQL 인젝션
SQL 인젝션이란 비정상적인 요청을 보냄으로써 웹 애플리케이션이 의도하지 않은 SQL을 요청하도록 의도하는 능동적 공격이다.
데이터베이스에 직접 접근하기 떄문에 개인 정보 유출이나 테이블 삭제 등 서비스 운영에 크리티컬한 문제가 발생할 수 있는 공격 중 하나다.
예를 들어, 사용자의 아이디와 비밀번호를 요청으로부터 입력받아 DB에 존재하는지 판별하는 SQL문을 작성했다고 가정해보자.
SELECT * FROM users WHERE id=${id} AND password=${password};
이때, password에 대한 입력값으로 ' OR '1'='1;
이 들어오면 쿼리는 아래와 같이 완성될 것이다.
SELECT * FROM users WHERE id='kdkdhoho' AND password='' OR '1'='1';
OR '1'='1'
이라는 조건문 때문에 해당 쿼리는 비밀번호를 입력하지 않아도 kdkdhoho 계정에 대한 로그인이 성공하게 된다.
SQL 인젝션을 방지하기 위해 입력값이 의도한 데이터 형식인지 체크하거나 입력값을 DB에 해싱하여 암호화한 다음 저장하는 노력 등을 수행할 수 있다.
2-2. HTTP 헤더 인젝션
HTTP 헤더 인젝션은 공격자가 HTTP 응답 헤더 필드에 개행 문자 등을 삽입함으로써 임의의 응답 헤더나 바디를 추가하는 수동적 공격이다.
만약 아래와 같은 HTTP Response가 있다고 가정해보자.
Location: http://www.example.com/a.cgi?q=12345
Set-Cookie: JSESSIONID=12345
위 응답을 이용해 공격자는 다음 요청에 아래와 같이 Location
헤더를 고쳐 요청을 보내면
Location: http://www.example.com/a.cgi?q=12345%0D%0ASet-Cookie:+SID=123456789
요청에 대한 응답으로 아래와 같은 HTTP 메시지가 응답된다.
Location: http://www.example.com/a.cgi?q=12345%0D%0ASet-Cookie:+SID=123456789
Set-Cookie: SID=123456789
왜냐하면 %0D%0A
는 HTTP 메시지의 개행 문자를 의미한다.
따라서 %0D%0A
뒤에 있는 Set-Cookie:+SID=123456789
가 서버가 만들어 낸 Set-Cookie
헤더를 덮어 씌워 응답으 보내게 된다.
이런 방식을 세션 픽세이션 이라고 한다.
위 방식처럼 HTTP 헤더 또는 바디에 공격자가 부적절한 값을 추가하여 웹 애플리케이션으로의 요청과 응답을 의도하는 대로 동작할 수 있다.
2-3. DoS 공격
DoS (Denial of Service attack)은 대량의 액세스를 특정 호스트에 집중하여 보내어 서비스 제공을 정지 상태로 만드는 공격이다.
DoS 공격은 웹 서버 뿐만 아니라, 네트워크 기기나 서버 등을 대상으로 공격하는 경우도 있다.
특히, DDoS 공격은 여러 대의 컴퓨터에서 요청을 보내는 방식을 의미한다.
2-4. XSS(Cross-Site Scripting)
XSS는 동적으로 HTML을 생성하는 부분에서 발생하는 취약점을 이용하는 공격 방식이다.
종류로는 Stored XSS 와 Reflection XSS 가 있다.
두 XSS 모두 공격자가 심어놓은 스크립트를 사용자가 의도하지 않아도 실행되도록 유도하는 방식이다.
2-4-1. Stored XSS
댓글이나 게시글에 글을 작성할 떄, HTML 태그를 본문에 넣어 요청을 보내면 서버는 본문 자체를 저장한다.
이때, 해당 게시글을 조회하는 모든 사용자는 공격자가 심어놓은 스크립트를 읽거나 수행하게 된다.
실제로 2011년 네이버 웹툰 댓글에 <img>
태그를 삽입함으로써 이미지 테러가 발생한 사례가 있다. [1]
1: 네이버 웹툰 댓글에서 이미지 첨부가 안되는 이유
2-4-2. Reflection XSS
공격자가 악의적인 스크립트를 URL에 담아 공유한다.
해당 URL을 누르게 되면, 브라우저는 스크립트를 수행하게 된다.
URL은 정상적인 사이트처럼 보이는 피싱 사이트이거나 사용자의 정보를 공격자에게 전송하는 URL 일 수 있다.
XSS가 어떤 식으로 수행되는지 직접 보고 싶다면 10분 테코톡 - 알트의 XSS 영상을 참고해보자.
2-4-3. XSS 방어하기
- innerHTML을 사용하지 못하도록 한다.
- 입력값으로 특수문자를 입력하지 못하도록 한다. (또는 정해진 형식으로만 입력하도록 강제한다.)
- 입력값의 특수문자를 문자열로 치환한다.
- Cookie의 httpOnly, Secure 속성을 사용하여 JS로 Cookie에 접근하지 못하도록 막는다.
2-5. CSRF(Cross Site Request Forgery)
CSRF는 특정 웹사이트에 인증된 상태의 유저가 의도하지 않은 요청을 보내도록 하는 수동적 공격이다.
실제 사례로, 2008년 옥션에서 CSRF 공격으로 1,800만 명의 개인정보가 유출된 사례가 있다.
공격 시나리오는 다음과 같다.
- 해커는
<img src="http://action.com/changeUserAccount?id=admin%password=admin width="0" height="0">
태그가 들어간 이메일을 보낸다. - 옥션 내부 관리자는 관리자 권한으로 로그인을 한 상태에서 해당 이메일을 클릭한다.
- 이때, 이미지를 받아오기 위해 URL이 열리게 되는데
src
에 담긴 요청으로 관리자 계정의 아이디와 비밀번호가 모두 해커가 의도한 값으로 변경된다.
2-5-1. CSRF 방어하기
사용자는 이상한 URL을 함부로 클릭하지 않는다.
서버는 HTTP Request에 담긴 Host
와 Referer
헤더 값을 비교한다.
만약 정상적인 요청이라면 두 헤더의 값은 일치할 것이다.
하지만 CSRF에 의한 요청이라면 두 값은 달라지므로 이를 비교하여 검증하는 것만으로도 대부분의 CSRF 공격을 방어할 수 있다고 한다.
2-6. 부적절한 에러 메시지 처리로 인한 공격
웹 애플리케이션이 처리한 에러 메시지로 인해 현재 접근이 어떤 문제를 가지고 있는지 힌트를 주는 경우가 있다.
가령, 로그인을 했는데 존재하지 않는 이메일이라거나
이럴 일은 없겠지만 입력한 비밀번호가 몇 글자 틀렸는지 알려주는 식의 에러 메시지는 공격자에게 너무 많은 힌트를 주게 되는 셈이다.
또한 데이터베이스 등의 시스템에 의한 에러 메시지가 그대로 노출되는 경우에도 공격자에게 취약성을 알려주는 셈과 같다.