
old-60 문제이다.
소스코드를 한번 보자
<?php
include "../../config.php";
if($_GET['view_source']) view_source();
login_chk();
echo "Your idx is {$_SESSION['idx']}<hr>";
if(!is_numeric($_COOKIE['PHPSESSID'])) exit("Access Denied<br><a href=./?view_source=1>view-source</a>");
sleep(1);
if($_GET['mode']=="auth"){
echo("Auth~<br>");
$result = file_get_contents("./readme/{$_SESSION['idx']}.txt");
if(preg_match("/{$_SESSION['idx']}/",$result)){
echo("Done!");
unlink("./readme/{$_SESSION['idx']}.txt");
solve(60);
exit();
}
}
$p = fopen("./readme/{$_SESSION['idx']}.txt","w");
fwrite($p,$_SESSION['idx']);
fclose($p);
if($_SERVER['REMOTE_ADDR']!="127.0.0.1"){
sleep(1);
unlink("./readme/{$_SESSION['idx']}.txt");
}
?>
<html><head><title>Challenge 60</title></head><body><a href=./?view_source=1>view-source</a></body></html>
소스 코드를 보니 우선 ?mode=auth 를 만족해야 할 것 같다.
그러기 위해서는 일단 세션값을 숫자로 만들어야 하겠다.

개발자도구에서 PHPSESSID 를 그냥 숫자로 바꿔버리고 다시 로그인해준다.
그러고 ?mode=auth 를 접근하면

Auth~ 가 떴다.
이제 고민을 하며 코드를 보다 보면 sleep(1) 이라는 부분이 눈에 띌 것이다. (난 그랬다^^)
그러고 다시 코드를 보면 왠지 모르게 race condition 취약점이 떠오르는 느낌이다.
$p = fopen("./readme/{$_SESSION['idx']}.txt","w");
fwrite($p,$_SESSION['idx']);
fclose($p);
if($_SERVER['REMOTE_ADDR']!="127.0.0.1"){
sleep(1);
unlink("./readme/{$_SESSION['idx']}.txt");
이 부분을 잘 보면 1초안에 txt 파일을 삭제하도록 되어 있는데,
if($_GET['mode']=="auth"){
echo("Auth~<br>");
$result = file_get_contents("./readme/{$_SESSION['idx']}.txt");
if(preg_match("/{$_SESSION['idx']}/",$result)){
echo("Done!");
unlink("./readme/{$_SESSION['idx']}.txt");
solve(60);
exit();
이 부분은 또 txt 파일의 내용을 제대로 받아와야 한다.
따라서 파일이 삭제되는 1초 안에 txt 파일의 내용을 받아오도록 해야 한다.
간단하게 설명하자면, 공유 자원인 txt 파일을 sleep(1) 하는 동안에 동시에 접근시켜서 하나는 unlink 되기 전에 txt 파일의 내용을 가져오게 하는 방법이다.
나는 내 피지컬을 믿고 edge 와 chrome 두 개의 브라우저를 사용해서 1초 안에 각각 새로고침을 눌렀다.

풀었다!
'Web > webhacking.kr' 카테고리의 다른 글
| Webhacking.kr old-14 (0) | 2025.03.17 |
|---|---|
| Webhacking.kr old-01 (0) | 2025.03.17 |
| webhacking.kr old-15 (0) | 2024.10.18 |
| webhacking.kr old-51 (2) | 2024.10.17 |
| webhacking.kr old-42 (3) | 2024.10.16 |