HTML Injection
Injection
인젝션 : 공격자가 악의적으로 주입한 데이터를 웹 애플리케이션에서 데이터베이스의 정상적인 쿼리 일부로 인식하고 실행할 때에 발생하는 취약점
데이터를 입력받거나 데이터베이스 정보를 요청하는 곳에는 인젝션 공격이 가능하다. 공격 방법이나 사용 언어에 따라 인젝션의 종류가 달라지는데, 대표적인 유형으로 SQL 인젝션, HTML 인젝션, OS Command 인젝션, LDAP 인젝션 등이 있다.
HTML 인젝션
HTML 인젝션 : 코드 인젝션 공격의 하위 개념으로, 취약한 매개변수에 악의적인 HTML 코드를 삽입하는 공격
공격자는 사용자가 연결을 요청한 페이지에 HTML 태그를 삽입하여 의도하지 않은 내용을 보게 하거나 악의적인 사이트에 연결 시킬 수 있다.
HTML 인젝션 중에 반사(Reflected) 기법 : URL에 악의적인 HTML 태그를 삽입하여 링크를 클릭한 사용자의 PC에서 HTML 태그가 실행되게 하는 공격이다.
특히 GET 방식은 사용자가 입력한 값을 검증하지 않고 그대로 출력해 데이터를 전송할 경우 URL에 변수명과 입력 값을 노출하게 된다. 이는 HTML 태그를 이용한 악의적인 공격으로 이어질 수 있다.
반사(GET)

HTML Injection-Reflected(GET) 항목을 선택하면 나오는 htmli_get.php는 사용자가 입력한 값을 그대로 출력하는 페이지이다.
이때 입력 값을 검증하지 않으면 웹 브라우저는 공격자가 입력한 HTML 태그를 해석하고 관리자가 의도하지 않은 내용을 출력할 수 있다.
이번 실습에서 목표로 하는 것은 위와 같은 화면을 출력하는 것이다.

난이도 low

First name에 siss를 작성하고 Last name에 esc를 작성했더니 Welcome 뒤에 이어서 출력되는 것을 확인할 수 있었다.
HTML injection - Reflected(GET)기법은 위에서 설명했듯이 사용자가 입력한 값을 검증하지 않고 그대로 출력한다.
이미지와 html 문법 등을 삽입해서 확인해 보았다.


그 전에 개발자 도구를 통해서 해당 페이지를 구성하는 태그들을 살펴보았다.
success는 <h1>success</h1>, 꿀벌 이미지는 <img src="./images/bee_1.png">를 이용해서 출력할 수 있을 것 같다.

예상대로 잘 출력되었다.
http://192.168.125.136/bWAPP/htmli_get.php?firstname=%3Ch1%3Esuccess%3C%2Fh1%3E&lastname=%3Cimg+src%3D%22.%2Fimages%2Fbee_1.png%22%3E&form=submit
GET 메서드로 요청하기 때문에 웹 브라우저의 URL 입력 부분에 변수가 노출된다.
따라서 URL 입력란의 'firstname'과 'lastname'이라는 변수에 입력한 HTML 태그가 보인다.
난이도 medium
http://192.168.125.136/bWAPP/htmli_get.php?firstname=%3Ch1%3Esuccess%3C%2Fh1%3E&lastname=%3Cimg+src%3D%22.%2Fimages%2Fbee_1.png%22%3E&form=submit
URL 입력란에 'firstname'과 'lastname'이라는 변수가 노출된다.

그러나 html 태그가 실행되지 않고 그대로 문자열로 출력되었다.


보안 레벨에 대한 것은 /bWAPP/htmli_get.php 파일에 있다고 한다.
터미널창에서 파일을 확인해보자.

보안 레벨이 0(low)면 no_check($data);를 실행시킨다.
보안 레벨이 1(medium)면 xss_check_1($data);를 실행시킨다.
보안 레벨이 2(high)면 xss_check_3($data);를 실행시킨다.

포함한 파일들의 목록이다.
이 네 파일 중 한 파일에 xss_check()를 정의해두었을 것이다.
functions_external.php 파일에서 함수를 확인할 수 있었다.

보안 레벨이 0(low)면 no_check($data)는 $data를 바로 리턴하는 것을 확인할 수 있다.

보안 레벨이 1(medium)면 xss_check_1($data)는 "<"를 "<"로, ">"를 ">"로 변환한 뒤 디코딩을 통해 데이터를 출력하는 것을 확인할 수 있다.

보안 레벨이 2(high)면 xss_check_3($data)는 "<", ">" 외에도 "&", '"', "'" 까지 변환한 것을 확인할 수 있다.
현재 보안 레벨은 1이므로, 태그에 사용되는 '<'와 '>' 문자를 URL 인코딩하여 입력한다.
URL 인코딩은 아스키 코드의 HEX 값에서 %를 붙인 값으로, 두 분자를 인코딩하면 '<'은 %3C, '>'은 %3E로 변환된다.
URL인코딩을 통해 이를 우회할 수 있다.
해당 사이트를 이용해서 인코딩을 수행했다.
URL 인코딩 - 온라인 URL 인코더
www.convertstring.com
<h1>success</h1> → %3ch1%3esuccess%3c%2fh1%3e
<img src="./images/bee_1.png"> → %ef%bb%bf%3cimg+src%3d%22.%2fimages%2fbee_1.png%22%3e
인코딩이 완료되었다.

잘 출력되었다.
난이도 high

설명을 위해 아까 보았던 난이도 high의 터미널을 가져왔다.
htmlspecialchars라는 함수를 이용해서 입력값을 우회한다.
htmlspecialchars 함수는 PHP에서 제공하는 기본 함수로, HTML에서 사용하는 특수 문자를 UTF-8로 반환한다.
문장 내에 HTML코드가 들어가는 특수문자를 포함시켜 입력하고 화면으로 출력할 때, HTML의 특수문자가 HTML태그로 적용되는 것이 아니라 일반 문자로 인식되어 그대로 출력한다.
따라서 HTML 코드를 이용한 방법을 사용할 수 없게 되었기 때문에 문제를 풀 수 없다.
php 공식 htmlspecialchars 함수 매뉴얼 문서이다.
PHP: htmlspecialchars - Manual
One MUST specify ENT_HTML5 in addition to double_encode=false to avoid double-encoding.The reason is that contrary to the documentation, double_encode=false will NOT unconditionally and globally prevent double-encoding of ALL existing entities. Crucially,
www.php.net