
Xpath 는 XML 문서의 특정 요소나 속성에 접근하기 위한 경로를 지정하는 언어이다. Xpath 는 경로식을 사용하여 노드 형식으로 접근한다. 공격자는 이러한 문법을 이용하여 XML 에 악의적인 내용을 Injection 할 수 있다. 자세한 문법과 사용법은 Xpath 를 검색하면 많이 나오기 때문에 따로 설명하지 않고 실습하면서 사용하는 것들만 설명하며 진행하도록 하겠다.
bee-box 환경에서 실습해보자!
Level - low

로그인 창에서 아무 값이나 입력하면 다음과 같은 메시지가 뜨게 된다. 참인 조건을 만들어서 요청해보자!

AND 연산으로 이어지는 password 부분을 무력화시키기 위해 id 에 ' or 1 or ' 라고 입력하여 쿼리가 참이 되게 하였다. 그 결과, Welcome Neo 라는 문구가 뜨게 된다. 로그인 쿼리가 참이 되면 DB 의 가장 첫 번째 데이터를 불러오기 때문에 Neo 가 맨 첫 번째 데이터일 것이다.
이제 참과 거짓일 때의 출력문구를 모두 알았으니, Blind SQL Injection 과 같이 값을 하나하나 알아내면 된다.
접근 방법은 다음과 같다.
부모 노드 / 계정 노드 / 계정 정보 노드
현재 노드는 계정 노드이고 neo 라는 id 값은 하위 노드인 계정 정보 노드 중 하나일 것이다. 그렇다면 만약 neo 의 패스워드를 알고 싶다면 계정 노드의 하위 노드인 계정 정보 노드로 접근하면 된다.
일단 Xpath 에 익숙해지기 위해 여러 정보들을 알아내보자!
먼저 현재 노드의 상위 노드인 부모 노드의 이름을 알아내보자. 필요한 Xpath 함수는 다음과 같다.
name() : 노드의 이름을 반환하는 함수
string-length() : 문자열의 길이를 반환하는 함수
substring() : 지정한 문자열을 반환하는 함수
그리고 사용법은 다음과 같다.
1. 부모 노드 이름의 길이 반환
string-length(name(parent::*))
2. 부모 노드 이름의 첫 글자 반환
substring(name(parent::*),1,1)
이제 이 함수들을 이용하여 쿼리를 작성해보자.
쿼리는 [알고 싶은 정보] or [거짓 조건] 과 같이 전송하여 참인 출력값이 나오면 값을 기록하는 식으로 진행하면 된다. 이러한 쿼리 조건이 익숙하지 않다면 Blind SQL Injection 에 먼저 익숙해지는 것을 추천한다. 작성한 쿼리는 다음과 같다.
1. 부모 노드 이름의 길이를 알아내는 쿼리 ( {} 는 임의의 숫자 )
?login=neo' and string-length(name(parent::*))={} or 1=2 or '&password=&form=submit
2. 부모 노드 이름의 첫 글자를 알아내는 쿼리 ( {} 는 임의의 문자 )
?login=neo' and substring(name(parent::*),1,1)='{}' or 1=2 or '&password=&form=submit
해당 페이지의 로그인 폼에 직접 입력할 경우, 패스워드 부분부터는 적을 필요 없다. 하지만 길이와 이름을 하나하나 입력하면서 찾는 것은 비효율적인 일이기 때문에 쿼리 형식으로 Python 코드를 작성하여 값을 알아냈다.

그 결과, 아래와 같이 heroes 라는 부모 노드 이름을 알아냈다.

다른 정보들도 이런 식으로 쿼리를 작성하여 알아낼 수 있다.
이번에는 neo 의 자식 노드에 대해 알아내 보자.
먼저 자식 노드의 이름을 알아내는 Python 코드를 작성했다.

먼저, count() 함수를 이용하여 자식 노드의 개수를 알아내는 쿼리를 요청했다. 그리고 나서 각각의 자식 노드 이름을 알아내는 쿼리를 요청했다. 코드는 생각나는 대로 바로 짜서 간결하지 못하다. 아무튼 결과적으로 아래와 같이 6 개의 자식 노드 이름이 출력되었다.

이 중에 password 값을 알아내보자. 쿼리에 들어갈 함수 내용은 다음과 같다.
1. password 값의 길이
string-length(string(./password))={}
2. password 값
substring(string(./password),{},1)='{}'
string() 은 인자 값을 문자열로 반환해주는 함수이다. 위의 함수들을 이용하여 Python 코드를 작성하였다.


정상적으로 패스워드가 출력되었다.
참고로 neo 는 첫 번째 계정 노드의 값이라고 노출이 되어 바로 정보들을 알아냈지만, 만약 neo 가 아닌 다른 계정 정보를 알고 싶으면 heroes 노드로부터 다른 자식 노드 정보를 알아내야 한다.
Level - medium, high
상위 두 단계에서는 injection 을 수행할 수 없었다.
소스코드 분석

medium, high level 에서는 xmli_check_1() 함수가 동작하고 있었다.

해당 함수에서는 특수문자를 필터링하고 있다. 때문에 XPath 함수를 사용할 수 없다.
대응 방안
특수 문자 필터링
'웹 취약점(bee-box)' 카테고리의 다른 글
| XSS - Reflected(JSON) (0) | 2020.04.06 |
|---|---|
| XSS - Reflected (0) | 2020.04.03 |
| SSI (Server Side Includes) Injection (0) | 2020.03.25 |
| PHP Code Injection (0) | 2020.03.25 |
| OS Command Injection (0) | 2020.03.25 |