XSS htmlspecialchars 함수 우회
htmlspecialchars 함수는 사용자가 입력한 문자열에서 특정한 특수 문자를 HTML 엔티티로 변환해주는 PHP 함수이다. 크로스 사이트 스크립팅(XSS, Cross Site Scripting) 취약점을 방지하기 위해 사용되며, 사용자가 입력한 문자열 중 ', ", <, >, & 문자를 HTML 엔티티 문자로 변환한다.
여기서 잠깐 크로스 사이트 스크립팅 취약점은 웹 애플리케이션이 부적절한 입력값들을 검증하지 않고 받아들일 때 발생되는 취약점이다.
크로스 사이트 스크립팅 취약점이 존재하는 웹페이지를 통해 공격자는 사용자들의 정보를 쉽게 얻을 수 있다. 크로스 사이트 스크립팅 취약점의 종류로는 reflected XSS, stored XSS, DOM XSS 세가지 종류가 존재한다
크로스 사이트 스크립팅 취약점이 발견되었다면 이 함수를 시큐어 코딩 함수로 제시한다. 하지만, 이 함수를 우회하는 방법이 있지 않을까? 궁금점이 생겼다.
실제로 운영중인 웹 사이트 취약점 진단 중 htmlspecialchars 함수로 검증하고 있어 htmlspecialchars bypass, htmlspecialchars 함수 키워드로 검색했다. 검색한 결과 대부분 크로스 사이트 스크립팅 취약점의 권고 함수로 제공되므로 우회할 수 없다는 이야기일 뿐이었다.
혹시 XSS Cheat Sheet에 있는 모든 공격 패턴을 대입하면 하나 정도는 스크립트가 실행되지 않을까? 모든 공격 패턴을 자동화하여 대입해도 단 하나도 우회가 되지 않았다.
하지만, 특정 상황의 조건이 부합된다면 htmlspecialchars 함수를 우회하여 현재 로그인 중인 사용자의 쿠키 값을 출력할 수 있다는 글을 봤다.
소스코드를 보면 사용자가 이름 입력 폼에 특정 문자열을 입력하면 GET 방식으로 전달된 name 매개변수를 htmlspecialchars 함수로 불필요한 문자를 변환하여 웹 브라우저에 출력한다.
실질적으로 이름을 입력하면 name 매개변수에 이름 주입되면서 웹 브라우저에 'name is 이름'이 출력된다.
10행의 htmlspecialchars 함수가 존재하는 라인을 주석처리하고, 기존의 주석처리 되어 있던 9행의 주석을 해제한다.
name 매개변수에 구글 로고 이미지 주소를 주입하면 스크립트가 실행되어 웹 브라우저에 구글 로고가 출력된다.
name 매개변수에 DATA URLs 형식의 데이터를 주입하면 웹 브라우저에 스크립트가 실행된다. Data URLs는 data: 스킴이 접두어로 붙은 URL로 컨텐츠 작성자가 작은 파일을 문서 내에 인라인으로 임배드할 수 있다.
○ data:text/html;base64,PHNjcmlwdD5hbGVydCgiRGF6ZSBIYWNrIik8L3NjcmlwdD4=
○ <iframe>, <embed>, <object>, <img> 등
document.cookie 함수 우회
1. 이벤트 핸들러가 필터링 되어 있다.
○ onload, onmouseover, onclick 등 대부분의 이벤트 핸들러가 필터링
2. ondbclick은 필터링 되어 있지 않다.
○ <img src=x ondbclick=alert(document.cookie)>
○ 하지만, 하이퍼링크로 설정되어 있으므로 더블클릭할 수 없다.
3. document.cookie가 필터링 되어 있다.
○ document.cookie를 입력하면 임의의 문자열로 치환
○ <script></script>는 허용
○ 가장 기본적인 난독화인 eval()를 이용
○ "><script>var t0='alert(';var t1='docu';var t2='ment';var t3='.coo';var t4='kie';var tt=')';eval(t0+t1+t2+t3+t4+tt)</script>
▶ XSSF(Cross Site Scripting Framework) 사용법