XML
XML은 데이터를 트리 구조의 노드로 표현하며 사용자 정의로 데이터를 분류한다.
<?xml version="1.0" encoding="UTF-8"?>
<movies>
<action>
<id>f</id>
<name>matrix</name>
</action>
위의 예시에서 최상위 노드는 'movies'고 하위 노드는 'action'이다.
action의 하위 노드에는 'id'와 'name'이 있다.
이렇듯 XML로 사용자는 다양한 데이터를 편의에 맞게 분류할 수 있다.
Xpath
Xpath는 일종의 쿼리로, XML 데이터베이스 내용을 선택하고 조작하기 위하여 사용한다.
XML은 트리 구조로 정의되어 있어서 다음 예시처럼 '/' 문자를 사용하여 최상위 노드부터 질의할 곳을 지정한다.
$result = $xml->xpath ('/movies/action[id='" .$id ."' and name='" .$name . "']");
이외에도 Xpath에 사용하는 명령어는 다양하다.
Search
xmli_2.php 페이지는 영화를 장르별로 분류하여 영화 제목만 테이블 형태로 출력한다.
이번 실습의 목표는 해당 테이블에 존재하는 모든 사용자의 정보를 확인하는 것이다.
난이도 low
SQL 인젝션 취약점이 있는지 알아보기 위해 genre 변수에 작은따옴표를 입력한다.
GET 메서드로 요청하기 때문에 URL에 변수가 노출되는 것을 이용하면 입력할 수 있다.
위와 같이 XML과 관련된 경고 내용을 출력한다.
URL의 genre 변수에 항상 참인 쿼리를 입력한다.
정상 쿼리에서 contains 함수를 호출하므로 소괄호와 '[]'를 사용하여 정상 쿼리를 강제로 닫는 쿼리를 만든다.
특히 XML을 호출할 때는 중간에 주석 문자를 입력하지 못하므로 정상 쿼리의 나머지 부분도 문법 오류가 발생하지 않게 쿼리를 입력한다.
') or 1=1 ][(' or
contains 함수는 인자를 두 개 받으며 첫 인자에 입력한 문자열이 두 번째 인자에 있으면 true 값을 반환하고 아니면 false 값을 반환한다.
인젝션 결과 위의 사진과 같이 검색 가능한 모든 영화 제목을 출력하는데, 이는 항상 참인 결과를 출력하는 쿼리를 입력하였기 때문이다.
XML 데이터베이스의 내용을 출력하는 쿼리를 입력한다.
'|' 연산자를 사용하여 Xpath 쿼리를 생성한다.
Xpath에서 '|' 연산자는 AND 연산자처럼 서로 다른 쿼리를 연결할 때 사용한다.
')]|//*|siss[('
다음 페이지의 정상 쿼리를 닫고 | 연산자로 '//*'를 연결한 쿼리다.
'//*' 쿼리는 현재 노드로부터 모든 노드를 조회하는 Xpath 쿼리다.
정상 쿼리의 나머지 부분 때문에 문법 오류가 발생하므로 '|' 연산자로 쿼리를 연결한다.
'|' 연산자 뒤에 임의의 문자열을 입력하여 Xpath의 쿼리 문법 규칙을 맞추어 노드 명으로 해석하게 만든다.
XML 인젝션 공격이 성공하여 heroes 테이블에 존재하는 모든 사용자의 정보를 테이블 형태로 출력한다.
난이도 high
난이도 high에서는 genre 변수에 XML 인젝션에 사용되는 문자를 넣어도 결과가 나오지 않는다.
xmli_2.php 페이지의 코드를 확인해 보았다.
xmli_check_1 함수를 사용해서 입력 데이터를 우회하는 것을 확인할 수 있다.
xmli_check_1 함수는 functions_external.php에 정의되어 있다.
xmli_check_1 함수는 str_replace 함수를 호출한다.
str_replace 함수는 인젝션에 사용되는 문자를 공백으로 대체한다.
str_replace 함수는 첫 번째 인자에 대체하려는 문자, 즉 인젝션에 사용되는 문자를 입력하고, 두 번째 인자에는 대체할 문자를 입력한다.
마지막 인자에는 변경한 내용을 저장할 변수를 입력한다.
xmli_check_1 함수에서 str_replace 함수를 사용하여 대체하고 있는 문자는 ', [, ], :, ,, *, /, 스페이스이다.