HEX Encoding을 이용한 XSS 필터링 우회

⚠️ XSS에 대한 전반적인 내용은 Cullinan > XSS 페이지에서 관리하고 있습니다. 해당 페이지에서 최신 데이터가 유지되니 참고 부탁드려요 :D

웹 취약점 분석 중 가장 많이 발견되는 XSS 취약점에 관한 이야기입니다. 대체로 쉽게 필터링 없이 들어가는 사례도 많았지만 분석했던 대다수의 서비스는 강한 필터링이 적용되어 있었습니다. 그러나 이 필터링에도 규칙이 존재하며 해커는 필터링 규칙을 파악할 시 쉽게 우회가 가능합니다.

오늘은 여러가지 우회 상황 중 이번에는 HEX Encoding을 통한 필터링 우회를 이야기할까 합니다.

HEX Encoding이란?

HEX 인코딩은 &#x 문자열을 통해 웹에서 hex 데이터를 표현하는 방법입니다. 편하게 부르기 위해 hex 인코딩이라 칭하지만 대부분의 인코딩 디코딩 툴에서는 HTML 으로 표기하는 경우가 많습니다.

간단한 XSS 필터 및 일반적인 XSS 구문 삽입

원리는 간단합니다. A를 나타내는 hex 값인 41에 &#x를 붙여주게 되면 &#x41 즉 텍스트 A를 의미하게 됩니다. 대부분의 XSS 필터는 입력값에 대해 특수문자를 < > 등으로 변환하여 공격자가 스크립트를 사용할 수 없도록 하는데요, 이러한 필터링 부분이 사용자 입력에 대해 검증한다면 공격자는 인코딩된 데이터를 이용해 필터링 규칙을 우회할 수 있습니다.

예를들어 아래와 같이 XSS 필터링 함수가 구현되어 있다고 생각해봅시다.

<?
 function XSSFilter($inputString)
 {
  $output = str_replace("<","&lt;",$inputString);
  $output = str_replace(">","&gt;",$output);
  return $output;
 }
?>

<?
 $sqlIn = $_GET['title'];
 $sqlIn = XSSFilter($sqlIn);
 db_connect($sqlIn);  // 뭐 이런식으로 있다고 가정합시다.
?>

아무튼 위와 같은 경우에서는 get으로 title 파라미터에 값을 전송하여 db_connect를 통해 게시글에 글을 쓴다고 했을 때 < > 문자열에 대해서 필터링 되어 들어가게 됩니다. 대부분의 게시판은 태그 사용이 필요하기 때문에 주로 삽입 구간에서 XSS 필터를 적용합니다.

/?title=<script>alert(45)</script> 와 같은 형태로 공격구문을 넣었을 때 게시글에는 필터링되어 아래와 같이 나타나게 될 것입니다.

&lt;script&gt;alert(45)&lt;/script&gt;

HEX Encoding 을 통한 XSS

위에서 했던 방법과는 약간 다른 방법으로 XSS 구문 삽입을 시도해보겠습니다. 동일하게 title 파라미터에 스크립트 구문을 넣지만, hex 형태로 넣어보겠습니다.

/?title=%26%23x003C;script%26%23x003E;alert(45)%26%23x003C;/script%26%23x003E; 

위와 같이 전송 시 아까 만든 XSSFilter 함수는 str_replace 함수에서 문자열들이 걸러지지 않습니다. 이대로 DB 저장 후 게시판 같은 곳에서 노출이 될 때 hex 인코딩이 풀어져 나타난다면 아래와 같이 완전한 스크립트 구문이 나타납니다.

<script>alert(45)</script>

XSS 우회

사실 XSS 우회 방법에 대해서는 정해진게 없다고 생각됩니다. 기본적으로 인코딩이 많이 알려져 있지만 실제로 가장 중요하다고 생각되는건 XSS 필터 함수의 규칙인 것 같습니다. 코드를 보지 못하더라도 우리는 테스트를 통해 로직을 유추할 수 있고, 이를 기반으로 보호 로직을 우회할 수 있습니다. 그래서 잘 안되더라도 한번 더 보는게 가장 좋은 우회 방법이라고 생각합니다.