Request, Response 패킷 인코딩 그리고 XSS 취약점 패킷 탐구

만두다섯개·2023년 12월 25일

SK 루키즈 16기

목록 보기
38/52

XSS 취약점, 경로 탐색 취약점을 공격 시 사용하는 여러 방식에서 사용하는 문장의 종류에 대해 분류해보고자 한다.

<script>alert(1)<script>

브라우저에서는 HTML, Javascript를 사용해 사용자에게 페이지 내용을 보여주거나, 메시지를 출력한다.

  1. 경로 탐색 취약점 공격
    이전에 풀어봤던 10. Lab: File path traversal, traversal sequences stripped with superfluous URL-decode 에서 목표 파일의 내용을 확인하기 위해 아래와 같이 정상적인 GET 방식의 Request를 변조해 전송한다.

두 번 URL 인코딩한 내용을 사용해 공격한다.

즉, Request 패킷이 URL 인코딩 이유
1. HTTP 웹 서버에서 RESTfull 설계를 사용한다.
2. HTTP 메서드(GET,POST,PUT,DELETE)가 리소스에 대한 작업을 정의한다.
3. 이 과정에서 클라이언트가 보낸 인코딩 된 Resquest 패킷(BrupSuite-raw로 본 데이터)을 디코딩 하여 사용한다.

(디코딩 : 서버 측에서 인코딩된 패킷을 처리하는 과정. * 서버 측에서만 디코딩하는 것이 아님.)

아래의 (# 요청 패킷의 URL 인코딩)과정으로 인해 URL 인코딩 된 요청이 웹 서버에서 디코딩 되어 처리 후, 응답으로 다시 URL 인코딩 된 응답을 클라이언트에서 받아, 브라우저가 이를 디코딩 하여 사용자에게 보여준다.

(이 과정에서 CSP, Http only 플래그 설정 등이 동작)

요청 패킷의 URL 인코딩

아래 사진에는 Request 패킷을 raw 형식으로 확인하고 있다.

해당 내용들은 문자열로 전송되고 있다.
그러나 일부 부분들은 URL 인코딩 되어 전송된다.
일부분에 대해서는 특수문자를 사용하거나, 사용하지 않는다. 이 차이가 뭘까?

POST /WebGoat/attack?Screen=82&menu=1100 HTTP/1.1
Host: victim:8080
Proxy-Connection: keep-alive
Content-Length: 129
Cache-Control: max-age=0
Authorization: Basic d2ViZ29hdDp3ZWJnb2F0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Origin: http://victim:8080
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36
Content-Type: application/x-www-form-urlencoded
Referer: http://victim:8080/WebGoat/attack?Screen=82&menu=1100
Accept-Encoding: gzip, deflate
Accept-Language: ko-KR,ko;q=0.8,en-US;q=0.6,en;q=0.4
Cookie: JSESSIONID=80A42BCBB9AF3F94C12B1762BF7972E8

HelpFile=XPATHInjection.help+%2526+type+C%3A%5CFullstackLAB%5Ctools%5Capache-tomcat-7.0.109%5Cconf%5Ctomcat-users.xml&SUBMIT=View

특수한 의미를 가지는 특수문자들은 URL 인코딩으로 전송 시, 혼란 방지와 데이터의 무결성을 보장할 수 있다.
따라서,
1. 주소와 파라미터
2. 쿠키 값
3. HTTP Request 본문 데이터
등, 특수문자가 사용되거나 포함될 경우에는 URL인코딩이 적용 될 수 있다.
URL으로 인코딩 되지 않고 문자열로 전송되는 값들( 예시 : Cache-Control: max-age=0 등)은 보통 제어 값 설정이다. 제어 값 설정에는 특수문자가 사용되지 않거나, 필요하지 않다. 그러나 특수문자가 사용되거나 포함될 경우에는 URL인코딩이 적용 될 수 있다.

XSS 취약점에서 요청/응답 패킷

위 사진에서는 Request 패킷에 스크립트 문장을 포함해 전송하고, Resposne로 스크립트로써 동작하는 스크립트문을 받는다.
XSS 취약점을 방지하기 위해 사용하는 replace와 같은 특정 문자열을 대체하는 메소드 사용 방식이 존재한다. (# xss_check_1 함수)
이 방식이 XSS 취약점 보안의 근본적인 방법은 될 수 없는 이유는

1. <script>alert(1)</script> //특수문자만 URL 인코딩 0회한 결과
2. %3Cscript%3Ealert%281%29%3C%2Fscript%3E //특수문자만 URL 인코딩 1회한 결과
3. %253Cscript%253Ealert%25281%2529%253C%252Fscript%253E // 특수문자만 URL 인코딩 2회한 결과
  1. xss_check_1 함수가 위 스크립트 문장 중, 특수한 의미를 가진 HTML( < : 태그의 시작 )를 HTML 엔티티 ( < : 아무 의미 없는 문자열)로 변경해준다.
  2. 웹 서버에서 이를 처리하기 전, urldecode를 함으로써 Request 패킷을 한번 디코딩해 사용한다.

해당 문제에서는 웹 서버가 디코딩 된 Request 패킷을 사용한다는 것은, 단순히 내용을 출력 ( echo ) 하기만 한다.
이는 공격자가 몇 번 URL 인코딩 한 Request 패킷을 전송하더라도, xss_check_1 함수는 1회 인코딩 된 HTML 특수문자를 HTML 엔티티로 변경한다는 것을 의미한다.
따라서 2회 이상 URL 인코딩 한 스크립트 문장은 xss_check_1 함수에서 아무런 replace 도 일어나지 않고, 웹 서버에서 사용 ( echo ) 한다.

웹 브라우저는 URL 인코딩 된 Response를 자동으로 URL 디코딩 해 페이지에 보여주므로, 공격이 성공된다. (횟수 상관 없이)

따라서 웹 서버측에서 XSS 취약점 방지 목적으로 시큐어 코딩을 한다면, htmlentities PHP 기본 함수를 사용해야 한다.
추후 상세한 XSS 취약점 보안 방법에 대해 기술예정.

XSS 취약점 방어 방법

  1. 모듈 프로젝트 이후 단순히 입/출력에서 필터링이 존재하기 보다, 더 많은 것들은 고려해서 방어해야한다고 생각했다.
  2. 그러나 단순히 XSS 취약점 방어 관점에서는 입/출력 필터링이 기본적인 방어 방법이고, 그 외에 다른 데이터들과 사용 환경 등에 따라 효육적으로 고려해야 한다.
profile
磨斧爲針

0개의 댓글