Browser based CSRF Mitigation? Yoooh!!!!!! Same-Site-Cookie!

Chrome 76 부터 Same-Site-Cookie 설정이 default로 enabled되었다는 것을 보았다. 사용자의 Privacy와 CSRF를 막기위해 개발되었다. Privacy는 쿠키를 통한 사용자 트래킹 (?)을 막을 수 있게 되었다는데 이 글에선 CSRF를 중점적으로 다룰 것이다.

우선 CSRF가 무엇인지 이해하고 넘어가야 한다. 하나의 예시를 보여주도록 하겠다.

악의적인 공격자의 웹페이지에 아래와 같은 코드가 있다고 생각해보자.

<html>
<body onload=x.submit()>
<form id=x method=post action=http://vic.tim/delete/3>
</form>
</body>
</html>

vic.tim 사이트에 CSRF를 방어할 수 있는 로직이 없다면 피해자는 자신도 모르게 3번 게시글을 삭제할 것이다. 이를 방어하기 위해 지금껏 시큐리티 미들웨어나 프레임워크들이 했던 방식은 크게 2가지이다.

  1. CSRF Token 검증
  2. Referer 헤더 검증

위 방법은 CSRF 공격을 막는데 효과적이지만 모든 입력받는 컨트롤러에서 확인을 해줘야 하기 때문에 효율적이지는 못하다.

이제 세션쿠키에 헤더를 추가하는 것만으로도 CSRF를 방어할 수 있는 시대가 왔다. 간단한 예제를 통해 알아보자.

Cookie를 설정할 때 CookieName=foobar; Domain=..; Expires=…; 쿠키 key=value 말고 추가적으로 Domain, Expires와 같은 설정을 추가할 수 있다. 이곳에 Same-Site 라는 설정 값이 추가된 것이다.

SameSite의 값은 Strict, Lax, None을 지원한다. 각각의 기능을 설명해보면,

Strict – 사용자가 직접 주소창에 입력하는 top-level navigation을 제외한 모든 요청에 Cookie가 포함되지 않는다.

<?php
header("Set-Cookie: foo=bar; SameSite=Strict;");
header("Set-Cookie : bob=alice; SameSite=Lax;");
header("Set-Cookie  : juno=im;");
echo '<pre>';
var_dump($_SERVER['HTTP_COOKIE']);
echo '</pre>';
<a href="http://app.imjuno.com/q/">go</a>                                   
<br>
<form method="post" action="http://app.imjuno.com/q/">
    <button type=submit>go</button>
</form>
a tag를 이용한 접속

Lax와 Normal 쿠키만 전송되는 것을 확인할 수 있다.

post action을 통한 접속

FORM을 이용한 POST 요청은 Normal 쿠키만 전송된다. 아래는 요청 타입별로 어떤 Same-Site 쿠키가 전송되는지에 대한 정리표이다. 개발할 때 참고하면 좋을 것 같다.

MDN에는 아직 Experimental 기능이라고 나오지만 현재 모든 브라우저에서 지원하고 있다. Chrome이 가장 먼저 적용한줄 알았는데 이미 다른 브라우저들은 적용했더라 -_-

https://caniuse.com/#search=SameSite

구글에서 이미 서버사이드 프로그래밍에 자주 쓰이는 언어들에서 SameSite 쿠키를 사용하는 방법을 깃헙에 올려두었다.

사용자 세션에 SameSite=Strict를 사용할 경우 CSRF를 완벽하게 막을 순 있겠지만 a href를 통한 접속에 쿠키가 같이 보내지지 않기 때문에 유저 편의성을 해칠 수 있다. 예를 들면 이메일에서 링크를 눌러 접속한다던지….

마지막으로 어떠한 미티게이션을 도입하더라도 Silver Bullet은 없기 때문에 (XSS가 발생하면 무의미 해진다 ㅋㅋ) 서버의 코드를 잘 작성하는게 제일 중요하다는 것을 말하구 싶다~!~!

Defcon (26+27) CTF

기적같은 1년여간의 드래프트를 끝내고 defcon 27과 함께 올리는 후기인 것이다.

Defcon 26

짜잔! 데프콘 26 후기다. 원래 시간상 스페인 다녀온 여행기를 먼저 쓰려고 했지만, 게으름의 정점을 찍고 있는 나에게는 무리였다. 이번에 미국가서 LA는 못 갔다왔지만.. 고든램지 식당 3개 별 찍고, 총도 쏘고 여러가지 재밌는 액티비티를 한듯!

올해는 legitbs가 아니라 OOO가 운영을 했다. 컨셉 자체가 뭔가 중2병 걸린 것 같았는데 운영도 역시 그랬다! 그래서 대회중에 있었던 에피소드와 간단한 라이트업을 작성 할 것이다!!

우선 카테고리는 아래와 같다. Attack/Defense는 취약점 찾아서 팀들(23팀) 익스하고 패치해서 방어하는거다. KingOfTheHill은 없었던 카테고리인데, 짧은 길이도 쉘코드 짜기, 스테이지 더 많이 깨기등.. seccon 본선에서 나오는거라고 한다. (안가봐서 모름)

볼드 처리된게 우리가 풀어서 점수를 먹은 것이고 주황색문제들을 라이트업을 쓰겠다.

Attack / Defense

  • pointless
  • twoplustwo
  • pool
  • oooeditor
  • bew
  • vchat
  • reeducation

KingOfTheHill

  • reverse
  • doublethink
  • propaganda

reverse

가장 처음 나온 문제다! KingOfTheHIll 문제였고 (디스)어셈블 해서 빈칸에 해당하는 인스트럭션 혹은 “??”로 되어있는 옵코드를 맞추면 된다.

unknown.png (523×332)

위 사진은 LEVEL 3까지 넘어와 옵코드를 맞추는 문제다. LEVEL 1, 2는 옵코드에 해당하는 인스트럭션을 맞추면 되는 문제였는데 급하게 해서 사진이 없다.

LEVEL 1, 2풀때 옆에 어셈블된 헥스 값 있는 지 모르고 머리로 대충 게싱해서 점수 올렸다.
e.g.) rdx, rsi 순으로 레지스터 설정한 후 빈칸 있고 call하면 rdi 셋하는 거 선택… 이런식으로 초반에 빈집털이에 성공했다.

Screen Shot 2018-08-16 at 1.10.47 AM.jpg

이후에 스크립트를 아주 잘짠,, 고수 형님들에게 처참하게 털렸다. (PPP, DEFKOR00T, Sauercloud, 등..)

pointless

내 기억상 가장 처음 나온 어택 디펜스 문제다. 첫날 대회장에선 reverse 코드 짜고 있었기도 했고, 손도 못대고 있다가 호텔가서 풀었다. 그런 이유는 여러가지가 있었는데,,

  1. mips 어셈 처음봄
  2. 대회장 너무 추움
  3. 우리 테이블 앞에 큰 스피커 있는데 자꾸 이상한 소리나오는 영상 틀어줌

위 3가지 이유 덕분에 멀미 나서 토할 것 같았다 리얼루.. 아무튼 분석하면 매우 간단한? 프로그램인데..

  1. DH를 4겹으로 한 후(RSA -> AES -> AES -> AES) 메뉴에 접근할 수 있다.
  2. 메뉴에 memcpy stack overflow를 발생시키는 함수가 있고 stack leak도 가능하다.
  3. NX가 없기에 offset 맞춰준 후 스택으로 점프하면 된다.

이제 여기서 부터 문제가 발생했다. 딱 1일차 밤에 완성시키고 2일차에 싱글벙글 하며 갔는데, 본선장에 도착하니 네트워크가 DoS 맞고 있었나,, 뭐래나.. 연결이 좀 왔다갔다 하니깐 끊기는 거다.. 결국 이건 나중에 가서 고쳐졌는데 똑같이 거의 안됐다. 그래서 OOO도  서비스 완전히 내려버렸다 ^___^ 화나고 이해가 안되는건 서비스 완전히 내려버리기 전에 잠깐 maintenance 하는 시간이 있었는데 이때 서비스가 KingOfTheHill 1문제와 Attack/Defense(pointless/풀리지 않은 문제)가 있었음에도 KingOfTheHill 라운드는 계속 올라가며 점수를 주고 있었다는 것이다. 이에 대한 어떠한 보상 및 사과는 이루어지지 않았다!!!!!!!!!! (ㅠㅠ)

~~bew~~

2019년 08월 14일. 기억이 안난다. zz
머 이상한 웹 익스였던걸로 기억. nodejs

~~pool~~

2019년 08월 14일. 기억이 안난다. zz
코인빼오는 거였나?

Defcon 27

올해는 민교랑 익스플로잇 프레임워크 개발에 좀 많은 시간을 썼다. 조만간 오픈소스를 통해 공개할 예정이다. 사실 다른 빌리지 CTF를 통해 블랙뱃지를 얻어보려고 했지만, 테이블에 앉고 정신차리니 밤이라 실패했다고 한다 ㅠ_ㅠ. 작년에 가고싶었던 LA 여행은 성공적으로 했다고 한다. 지금 보스턴 가는 비행기 기다리면서 작성하고 있다.

telooogram

총 취약점 3개인 것 같은 2개가 있었다.

익스플로잇은 상대방의 avatar를 요청하는 기능으로 했다. file path를 전달하게 되는데 flag 를 넣게되면 플래그를 읽어서 해당 유저에게 보낸다.

두번째는 음성통화 기능에 존재하는 overflow다. 익스가 어려워 보여서 손절했다.

세번째는 unsafe한 deserialization을 하는데 이걸로 익스 어떻게 하는지 모르겠어서 손절했다.

아이폰 시뮬레이터 (홍보 차원에서?) 사용한 것 같았는데, 메세지를 폴링하는 방식이라 flag가 아닌 cred를 뺀 후 타 서버에서 (심지어 메시지 서버가 외부 접근이 되었음) 0.1초마다 크롤해주면 아무도 익스를 못하는 DoS 공격이 되어버린다.

어느 시점이후로 플래그가 몇개 안오길래 열심히 새로고침 시켜줬다 ㅋㅋ

aoool

태양이가 열심히 파서를 분석했다. 첫날만 열심히 하고 침대에서 뒹굴 메타를 시전해버렸기 때문에 안하다가 ELF 바이너리 인것 보고 잠깐 하기로 했다. 익스플로잇을 하나 작성해갔지만 정상적으로 작동이 되지 않고 계속해서 공격받고 있었다. 띵킹을 좀 하다가 ELF니깐 셀프바이너리 패치를 하고나서 uploads폴더에 올라간 익스플로잇을 빼오자는 생각을 했다. JUNO를 입력하면 쉘을 띄워주고 그 외엔 모두 정상 path를 타게해서 SLA 체크를 통과시켰다. 그 후 익스빼서 잘 돌렸다 슝슝

jtaste

셋째날 역시 침대에서 뒹굴대고 있었는데 다훈이형의 채찍질로 일어나서 풀었다. 이상하게 내 컴퓨터가 라우팅 설정이 잘못되어 있어가지구 VPN을 붙어도 접속이 안되었다. 그래서 코드만 보고 테스트 없이 익스플로잇을 작성했는데 바로 되었다고 한다. 그렇게 퍼스트블러드를 ~~~~~~~~~ ~! ~! ~! ~!~~!

P.S.

내년에는 ㅡ블랙뱃지를 받을 수 있도록 다른 전략을 세워봐야겠다. (i.e. 빌리지로 도망zz)