Open HTTP Redirect * 발표 시작 전 pyacket 설치하라고 하자 redirect가 뭔가 -> 특정 URL로 접속했을 때, 서버가 "이 페이지 말고 다른 페이지로 가세요" 라고 알려줌 --> 이 때 사용자는 다른 페이지로 이동됨 Open HTTP Redirect -> '웹 애플리케이션'이, 사용자가 입력한 외부 주소를 검증 없이 신뢰 -> 원하는 악성 사이트로 사용자를 튕겨 보낼(접속하게 만들기, redirection)수 있는 것 HTTP 응답 코드(status code) -> 웹 서버가 요청을 어떻게 처리했나? 에 대한 정보 100번대 : 요청 접수됨 200번대: 요청 성공적으로 처리됨 300번대: Redirection 됨(요청 완료를 위해 이 페이지로 가야 함) --> 301 Moved Permanently(너가 요청한 페이지는 영구적으로 다른 위치로 이동되었다) --> 302 Found(요청한 페이지가 있기는 한데, 임시로 다른 URL로 이동되어 있다) --> 304 Not Modified(기존 페이지 데이터에서 수정되지 않았으니, 캐시 데이터를 사용해 페이지를 봐라) 400번대: client error(웹 서버 입장에서의 오류는 아닌데, 너의 요청이 잘못되었다) --> 너한테 권한이 없다(401 Unauthorized), 접근이 금지되어 있다(403 Forbidden).. 등 500번대: server error(웹 서버 입장에서 내가 요청을 처리 못 했다.) * 개발자 입장에서 볼 때는, 200번대가 좋은 것, 400번대는 너(고객) 잘못, 500번대가 내(웹 서버를 개발한 개발자) 잘못 응답 코드는 '약속'의 개념이라, 요청 처리 성공하고도 의도적으로 500번대 코드를 보낼 수도 있다. 장난이나 풍자가 섞인 HTTP 응답 코드도 있음 -> 451 Unavailable For Legal Reasons: 서버/정부/통신사 등이 법적으로 검열하는 정보라 못 보여준다 -> 418 I'm a teapot : 이스터 에그 비슷한거임. 궁금하면 뭔지 찾아보자 1. 칼리로 dvwa에 들어가자 2. admin / password 로그인 3. reset db 하기 4. 레벨 low로 맞추기 5. open http redirect 누르자 6. pyacket 패킷 캡쳐 키고, 패킷 잡아보자(quote1 누르기) 7. dvwa 서버와 칼리 서버 사이 HTTP 통신 패킷을 잡고, Flow 보기를 누르자 패킷 설명 1. 3-way handshake를 거친다(왜냐하면 HTTP는 TCP/IP를 기반으로 하니까) 2. 칼리->dvwa서버로 HTTP 요청을 보낸다(quote 1) 3. dvwa->칼리 응답을 준다(http 302 -> 너가 찾는 페이지가 있기는 한데, 여기에 있다) 4. 칼리->dvwa로 다시 GET 요청을 보낸다(찾는 페이지 가져다주라고 다시 함) 5. 응답을 받는다. * 이때, Location 헤더에 http://나 https://가 없다면, 현재 페이지 URL 뒤에 Location 헤더의 값을 붙여 이동한다 quote 1을 누를때, 마우스 계속 올려놓고 있다보면 redirection 되어서 해당 페이지로 와지는 링크라는 걸 알 수 있다 특정 페이지로 이동하긴 하나, 웹 서버를 한 번 더 거쳐서 해당 페이지로 이동한다는 데 포인트가 있다. -> DVWA 실습은 여기서 끝. 의문이 들 수 있다 "왜 바로 악성 링크로 이동하게 하지 않고, 웹 서버를 한 번 더 거치는가?" 크게 3개의 이유가 있음 1. 보안 솔루션 우회의 목적 - 도메인을 보고 악성 링크로 걸러버릴 수 있음 --> 신뢰받는 사이트의 도메인 뒤에 리다이렉션을 걸면, 필터링을 통과하는 경우가 있다 2. 심리적인 요소 - 사용자가 링크를 클릭할 때, 처음 보는 도메인이면 클릭을 꺼리지만, naver나 google 등 본 적이 있는 도메인이면 의심을 잘 하지 않는다 3. 기술적인 제약 우회(제일 메인) - OAuth Token을 탈취할 수 있다 * OAuth가 뭐냐? -> Open Authorization. 특정 애플리케이션에 내 계정의 일부 권한을 넘겨주기 위한 프로토콜 * 요즘에 구글/네이버 아이디로 다른 서비스에 가입/이용할 수 있는게 많다 -> 이거임(피파 로그인 창 켜서 예시 들기) OAuth 동작과정 1. 네이버 아이디로 로그인하기 클릭 -> 네이버의 인증 서버로 이동 --> 이때, URL에는 게임사가 등록한 식별값(client_id)와, [인증이 끝나면 돌아갈 주소: "redirecet_uri", 즉 게임사의 url이 붙어 있음] 2. 네이버 인증 서버에서 인증 마침 3. 네이버 인증 서버가 임시 인증 코드를 붙여, redirect_uri로 브라우저를 다시 튕겨보냄 --> 이때, open http redirection 취약점을 이용하면, 1번 과정에서 redirect_uri에 내 서버의 url을 붙여넣어놓을 수 있다. --------> 앞에는 게임사 서버의 URL를 넣고, 그 뒤에 redirect로 공격자 서버의 url을 넣는다. ---> 이러면, 임시 인증 코드를 탈취 가능하다 ----> 탈취한 임시 인증 코드를 네이버 인증 서버로 보내, access token을 교환받아 올 수 있다. -----> access token을 사용해 사용자의 정보를 털 수 있다. * 하지만 이 시나리오는 OAuth 2.0에서는 안 먹힘 -> 그렇지만 털어낸 임시 코드를 이용해 게임사 서버로 보내면, 해당 계정의 로그인 세션을 탈취할 수는 있다(게임 계정 도용) + 여기서 포인트는 네이버/구글 계정이 털리는 게 아니라, 네이버 계정으로 게임사에 로그인된 세션을 털릴 수 있는 것 -> 시크릿 창 열어서 피파 로그인창 -> 네이버로 로그인 버튼 누른 후, URL에 있는 OAuth2.0과 redirect_uri 값 보여주자. --> 구글/카카오 등 인증 서버는 사전에 등록된 서비스 주소 A로만 인증 토큰을 전달하도록 해 놓음 ---> 공격자는 자신의 사이트로 바로 토큰을 받아올 수 없다 ----> 따라서 사전에 등록된 서비스 주소 A의 Open HTTP Redirect 취약점을 이용해, 서버 A를 경우해 토큰을 받아올 수 있다 - Referer 헤더의 존재(스펠링은 Referrer가 맞으나, 웹 표준 RFC 1945를 제정 시 오타낸걸 그냥 지금까지 쓴다고 함) -> Redirect 요청을 브라우저가 처리할 때, "나는 이 페이지에서 리다이렉션 된 것임"을 나타내기 위해 보고 있던 페이지의 URL을 Referer 헤더에 넣어 줌 -> 두 번째 HTTP Request GET 패킷(리다이렉션된 URL 요청)에서 볼 수 있음 --> 이때 Referer 헤더에 들어 있는 URL에 특정 민감 정보가 노출될 수 있다 지금은 이 취약점이 어디에 있나? 이전에는 이게 큰 취약점이어서 단독 항목으로 있다가, OWASP 2017부터는 OWASP 2021 A01: Broken Access Control의 하위 항목으로 들어감 CWE-601: URL Redirection to Untrusted Site (https://cwe.mitre.org/data/definitions/601.html) 주정통 기준으로는 WEB-21 HTTP 리디렉션 항목에 있음 프로젝트 할때 어디를 막아야 하나? -> redirection 응답을 보낼 때, 필터링 코드를 꼼꼼히 짜자.. 정도 -> 리디렉션을 할 URL은 화이트리스팅을 거치자 -> 상대 경로만 허용하고, 절대 경로는 허용하지 말자(내부 리디렉션만 허용) -> OAuth를 사용할 일이 있다면, 와일드마스크(*) 사용하지 말고 완전 일치(Exact Match)되는 URL만 허용하자