안녕하세요 오랫만에 글을 작성하네요
제보한 프로그램에 대해 간단히 PoC를 해보려고 합니다.
0. WordPress Plugin
WordPress 플러그인 중 하나인 iframe 플러그인 입니다
10만 유저 가까이 설치하여 사용중이며 플러그인 자체는 굉장히 심플합니다.
WordPress 내에서는 보안적인 이유때문에 iframe 태그 사용이 금지되어있습니다.
그로 인해 해당 플러그인을 사용하여 iframe 태그를 사용하는 방법 밖에 없어 사용하는 유저수가 많은것으로 판단됩니다.
사용법은 간단합니다.
위 사진의 내용처럼 shortcode를 이용하여 iframe태그를 사용하면 끝입니다.
Shortcode란 WordPress 내에서 사용하는 매크로 기능이라고 보시면 됩니다.
기본적으로 대괄호를 사용하여 지정된 코드나 파라미터를 사용하면 일반 스크립트 태그로 변환되어 적용됩니다.
소스코드를 보니 기존 iframe 태그 처럼 들어갔네요
1. Disallow_unfiltered_html
PoC 들어가기 전에 WordPress 설정 파일 중 wp-config 파일 내 일부 설정을 변경해줘야합니다.
Disallow_unfiltered_html은 WordPress 내 허가되지 않는 HMTL 태그 및 코드 사용 금지하기 위해 사용되는 필터링이며 해당 필터링이 설정되어있지 않은경우(false) 취약점으로 인정되지 않으니 주의해주시기 바랍니다.
iframe에서 사용하는 파라미터들의 shortcode입니다.
저 중에서 src 파라미터부분을 이용해 취약점을 재현하겠습니다.
2. Vulnerable point
플러그인 소스코드를 살펴보겠습니다.
단순한 플러그인이다보니 소스코드 양이 많지는 않습니다
우리가 이용할 취약한 부분을 살펴보겠습니다.
아까 document에서 확인했던 내용과는 다르게 src 파라미터 뿐만 아니라 srcdoc도 사용하네요
저부분을 이용해보겠습니다.
그전에 워드프레스에서 사용하는 필터링 함수 부분을 한번 살펴보고 넘어가겠습니다.
함수 | 설명 | |
htmlspecialchars_decode() | HTML 특수 문자열을 디코딩하는 함수입니다. | |
wp_kses() | 주어진 텍스트를 필터링하여 허용된 HTML 태그와 속성만 허용합니다. 특히 $allowed_tags 배열의 구성을 이용해 필터링 합니다. 사용자 입력 데이터를 받는 경우, 특히 신뢰할 수 없는 소스에서 HTML을 수용하는 경우 $allowed_tags를 엄격하게 설정해야 합니다 | |
esc_html() | HTML 특수 문자열을 이스케이프하여 출력을 안전하게 만듭니다. |
3. PoC
iframe src 파라미터에 스크립트를 삽입해 보겠습니다.
코드를 확인해보니 src 파라미터에 프로토콜(http://)이 강제로 삽입되어 있네요.
"src" 속성(attribute)은 <script>, <img>, <iframe> 등과 같은 태그에서 외부 리소스의 경로를 지정하는 역할을 하는데,
iframe 태그는 보안상의 이유로 http://"를 강제로 명시함으로써, 브라우저에게 명시적으로 HTTP 프로토콜을 사용한다 합니다.
아까 소스코드에서 확인하였던 srcdoc 부분을 스크립트 사용하지 않고 삽입해보았습니다.
srcdoc 속성을 사용한결과, 기존의 iframe과 body 태그가 추가된 것을 알 수 있습니다.
<iframe> 요소의 srcdoc 속성에 설정된 값은 인라인으로 포함되는 HTML 문서를 정의합니다. 이 때 <body> 태그가 자동으로 사용되는 이유는 HTML 문서의 기본 구조를 유지하기 위해서입니다.
<iframe srcdoc="<p>Hello, World!</p>"></iframe>
이 경우 브라우저는 내부적으로 아래처럼 해석하며 <body> 태그를 추가합니다
<iframe srcdoc="<html><head></head><body><p>Hello, World!</p></body></html>"></iframe>
저는 이점을 이용해서 취약점을 발생시켰습니다.
srcdoc 속성을 이용해 스크립트를 삽입해 보겠습니다.
아까 소스코드에서 본것처럼 스크립트가 필터링들에 거쳐 제거된것을 알수있습니다.
그럼 취약하게 설정된 sanitized 함수을 이용해보겠습니다.
4. 원인 분석
원인은 아까 확인하였던 이부분입니다.
최초 발생 원인은 htmlspecialchars_decode 함수 입니다.
htmlspecialchars_decode함수 이후 wp_kses, esc_html 함수가 정상 동작하지 않는것을 확인하였습니다.
아래 두 함수는 주석처리 후 echo문을 통해 값을 확인해보겠습니다.
1. htmlspecialchars_decode
첫번째로 htmlspecialchars_decode 함수를 거쳐 스크립트 구문들이 디코딩 되었습니다.
디코딩만 하기때문에 당연히 스크립트가 동작됩니다.
2. wp_kses
두번째로 wp_kses 함수는 지정된 $allowed_Tags 배열에 따라 입력된 HTML을 필터링처리 해야 합니다.
허용한 HTML태그가 없기에 필터링 처리가 되어야하는데 이부분부터 정상적으로 필터링이 되지 않았습니다.
3. esc_html
결국 세번째 함수 esc_html도 필터링 처리 되지 않았네요
두번째 함수인 wp_kses함수부터 필터링처리 되지 않고 패스되어서 XSS가 발생하였으며, 아래의 이벤트핸들러 필터링 처리 부분도 자연스레 패스되었네요
주 원인은 불필요한 함수를 많이 써서 코드들이 꼬이면서 시작된게 원인이었었습니다.
htmlspecialchars_decode함수에서 인코딩, 디코딩 되는 시점부터 HTML 태그로 인식못하고 패스되어 삽입한 스크립트 구문이 그대로 들어갔네요.
5. 보안대책
사실 보안 조치는 생각보다 간단합니다
위에 src 처럼 srcdoc도 esc_html 함수만 사용하면 됩니다.
지금으로서는 wp_kses 함수나 esc_html 함수 둘중에 하나만 사용하거나 아니면 sanitize_text_field 함수를 사용하는 것이 좋아보이네요.
마지막)
연구원들이 재현이 안되어서 사진과 동영상 증적을 찍고 실랑이 한달간 연구원들과 회의를 통해 결국 재현이 증명되었습니다.
회의를 통해 알게된 결과 도커환경에서 구성된 워드프레스의 경우에는 재현이 안되었다고하네요..
취약점이 발생되었으면 그걸 증명하고 설명하는 과정도 중요하다고 느꼈습니다.