ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [WEBHACKING] CSRF에 대해서
    # 웹해킹 공부중 2020. 12. 3. 15:35

    1. CSRF란?

    CSRF는 Cross-Site Request Forgery의 약자로 다른 사이트에서의 변조된 요청을 의미한다. 해당 공격은 공격자가 피해자의 권한으로 특정 행위를 하도록 인자값들을 구성해서 피해자가 본인도 모르게 본인의 권한으로 해당 사이트에 요청을 보내 하도록 하는 공격이다. 예를들어 패스워드를 변경한다던지 포인트를 다른 사람에게 선물하는 등 해당 사용자의 권한으로 할 수 있는 것들을 사용자 몰래 하게된다.

    <form id="machine" action="target.com/test" method="post">
    <input type="hidden" name="val" value="HACKED" />
    </form>
    <script>
    document.getElementById("machine").submit();
    </script>

     

    위와같은 코드를 피해자가 읽을만한 그리고 HTML 코드가 동작하는 곳에 입력해두고 사용자들이 해당 글을 읽으면 "target.com"으로 사용자 모르게 요청이 전송된다. 이런 공격이 가능한 이유는 해당 도메인으로 요청을 보낼 때 브라우저는 그 도메인에 대한 세션을 request에 포함시켜서 전송하게된다. 이 요청을 받은 서버는 요청을 보낸 사람의 세션을 받고 그 사람의 권한으로 동작을 수행하게 된다.

    따라서 CSRF가 발생하기위해선 사용자의 권한으로 할 수 있는 기능들이 존재해야하며 그 외 아래와 같은 조건이 필요하다. 

    1. 쿠키를 기반으로한 세션 인증을 해야한다.

    2. 예측불가능한 요청인자가 존재해서는 안된다.

    특정 사이트에 요청을 보낼 때 브라우저는 해당 사이트에 대한 쿠키를 같이 보내게된다. 즉 공격자가 사용자의 쿠키값을 몰라도 브라우저에서 알아서 인증값을 요청메시지에 포함해서 전송하기 때문에 CSRF가 가능해진다. 또한 특정 요청을 할 때 필요한 인자를 정확히 전송해야 원하는 행위를 하게 할 수 있으므로 필요한 요청값들을 알 수 있어야한다. 

    XSS가 있으면 CSRF 또한 가능할 수 있다. 자바스크립트로도 form을 구성해서 사이트에 요청을 보낼 수 있으며 스크립트 사용이 가능하면 것은 위와같은 HTML 코드 역시 가능한 경우가 있기 때문이다. 

    XSS와 CSRF의 차이점
    XSS는 사용자의 브라우저에서 자바스크립트 코드를 실행시키는 공격이고 CSRF는 사용자의 권한으로 사이트에서 원치않은 행위를 하도록 하는 공격이다. 즉 사용자의 브라우저 내에서 어떤 행위를 하게 하느냐 아니면 서버로 요청을 보내 특정 행위를 하게 하느냐의 차이다. 일반적으로 XSS가 CSRF보다 더 심각한 취약점으로 생각된다. CSRF는 할 수 있는 행위가 사이트의 기능 내 일부분에서 가능한 경우가 많은 반면 XSS는 사용자가 수행할 수 있는 모든 작업을 할 수 있기 때문이다. (이 말이 CSRF가 별로 위험하지 않다는말이 결코 아니다) 그리고 CSRF는 피해자로 하여금 요청만 보낼 수 있는 취약점인 반면 XSS는 요청을 보낼 수 있을뿐만아니라 해당 요청에 대한 응답까지 읽어서 공격자가 필요한 정보를 추출해낼 수 있다는 점에서 또 차이가 있다. 

    2. CSRF 보안방안

    1. CSRF Token

    CSRF를 보안하기 위해 보편적으로 사용되는 방법중 하나로 사용자가 요청한 페이지에 사용자의 세션과 연결된 랜덤값을 생성해서 넣어두고 나중에 오는 요청에 해당 랜덤값이 원본과 일치하는지 검사해서 일치할 경우에만 동작을 수행한다. 일치하지 않으면 에러를 출력하고 동작하지 않도록 한다. Token에 대한 검증이 잘 되어있고 예측불가능한 값을 이용한다면 강력한 보안수단이 된다. 

    <input type="hidden" name="csrf-token" value="C14DrSsr4!-421sfeer42">

    보통 이런식으로 요청한 페이지의 form 태그내에 token이 숨겨져있으며 사용자가 요청을 보낼 때 함께 전송된다. 

    이 token은 예측불가능한 랜덤값이기 때문에 공격자가 미리 값을 넣어둘 수 없어  공격자 입장에서 예측불가능한 요청인자가 존재하게 되어 CSRF 공격으로부터 안전해진다. (물론 검증을 명확히 했을때만) 하지만 주의해야할 점은 CSRF Token을 사용한다고 해서 무조건 안전한건 아니다. 만약 CSRF 공격코드를 작성하려는 곳에서 스크립트를 실행시킬 수 있다면(XSS 취약점이 있다면) 타겟 서비스에 요청을 보내 token값을 받아와 공격 코드에 포함시킬 수 있다. 

    2. Referer Header 검증

    Referer 헤더는 웹 요청시 현재 요청이 발생한 페이지의 URL을 담아서 보내게된다. 이를 활용한 외부 사이트에서 CSRF로 변조된 요청이 오는 경우를 막기 위한 방법 중 하나로 요청이 왔을 때 Referer 헤더를 검사해서 지정된 페이지에서 온 요청이 아닌 경우 드랍시키는 방식으로 보호할 수 있다. 이 또한 해당 페이지에서 스크립트가 실행된다면 Referer 헤더 역시 변조시킬 수 있다. 

    3. Same-site Cookie

    Same-site Cookie는 비교적 최근에 브라우저들에 적용된 세션 관련 정책이다. 로그인을 해서 세션이 발급될 때 "SESSIONID=VALUE; SameSite=Strict" 와 같이 서버에서 설정된 값으로 Same-site 값이 세션과 함께 브라우저에 저장된다. 그리고 해당 도메인으로 요청을 보낼 때 Same-site 가 아니면 세션값을 설정값에 따라 보낼지 말지 결정한다. 설정값은 크게 "Lax""Strict" 가 있으며 설정값에 따른 세션 전송 여부는 아래와 같다. 

    from https://www.netsparker.com/blog/web-security/same-site-cookies-by-default/

    예를들어 SameSite값이 Lax 이면서 해당 세션을 발급한 곳과 다른 사이트일 경우 GET 메소드에 대한 요청에는 세션을 함께 전송하지만 POST 메소드에 대한 요청에는 세션이 전송되지 않는다. Strict 옵션의 경우 모든 경우에 대해 다른 사이트일 경우 세션을 전송하지 않기 때문에 가장 안전하지만 서비스를 이용이 원활하지 않을 수 있기 때문에 적절히 조절해서 사용해야한다. 현대 브라우저들은 대부분 현재 Same-Site 정책을 적용하고 있다. 잘 사용한다면 효율적으로 CSRF를 보안할 수 있지만 쿠키가 전송되는 Request type을 잘 확인해야하며 일반 사용자의 경우 브라우저에서 기본적으로 SameSite 정책을 따르도록 설정할 수 있다.

    4. CAPTCHA

    웹을 사용하면서 흔히 볼 수 있는데 그림에 나와있는 문자를 입력하거나 "로봇이 아닙니다" 를 체크하는 등의 방식으로 해당 요청이 봇(Bot)에 의한 요청인지 아닌지 검증하는 기술이다. 자동화 도구들에 의한 요청 방지도 되면서 공격자가 요청 인자를 모두 파악하지 못하게 함으로써 CSRF도 자연스럽게 보안이 된다. 

    5. 2차 인증

    요청을 받을 때 사용자만 아는 정보(예. 사용자의 비밀번호)를 함께 입력받도록 하거나 추가 인증을 통해 공격자가 알 수 없는 값이 생기기 때문에 마찬가지로 CSRF 공격으로부터 보호할 수 있다. 

    이런 보호 기법들을 서비스에 맞게 적절히 사용한다면 사이트 외부에서 들어오는 CSRF는 보안이 가능하지만 사이트 내에 XSS 취약점이 있을 경우 CSRF처럼 사이트의 특정 권한을 타겟팅해서 악의적인 행위를 할 수 있기 때문에 XSS 취약점에 대한 보안도 철저히 할 필요가 있다. 

    3. CSRF 취약점

    2번에서 소개한 보안 기법들을 사용하면 CSRF로부터 안전할 수 있으나 해당 보호 기법들을 잘못 구현했을 때 보호기법들을 우회해서 CSRF를 exploit 할 수 있다. 아래에 취약하게 구현된 경우를 몇가지 나열해본다.

    - POST 메시지에 대해서만 CSRF 검증을 하는 경우(GET으로 요청 보냈더니 요청 받아짐)
    - CSRF Token 검증할 때 값을 비교하는게 아니라 존재 유무로 검증하는 경우(아무 token 넣었더니 우회)
    - 다른 사람의 Token을 넣었는데 우회가 되는 경우(세션과 token이 묶여있지않음)
    - 이미 사용된 Token이 재사용 되는 경우
    - Token을 POST 메세지 본문과 쿠키에 같이 전송되서 그 둘이 같은지 검사하는 경우(페이지에 쿠키를 설정하는 기능이 존재 한다면 쿠키에 아무 token을 넣고 csrf 페이로드에 같은 token을 넣어두면됨)
    - Referer 헤더가 존재하는지만 검증하는 경우
    - Referer 헤더 검증시 단순히 URL에 문자열 포함여부만 확인하는 경우(공격자가 개인서버 도메인에 타겟 도메인을 서브도메인으로 사용할 경우 우회가능)
    - XSS 취약점이 존재해서 Token이 탈취되는 경우 등

    댓글

Designed by Tistory.