목표 : Race Condition (Cookie)
idx 값과 함께 Access Denied 안내가 발생한다.
소스 코드를 보자.
<?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>
PHP
복사
1) is_numeric() 특정 데이터의 값이 숫자인지 아닌지를 확인하여 결과를 반환하는 함수
쿠키 값에 영문자가 들어가있으면 거절되고 종료된다.
2) 1초 sleep 한 후에 get 인자로 auth가 들어오는 지 확인한다.
idx.txt 파일 내용을 가져오고 그 값이 현재 idx랑 일치한다면 문제를 푼다.
3) ./readme/{$_SESSION['idx']}.txt라는 파일을 생성해 세션 값을 쓰고 닫는다.
4) 127.0.0.1이 아니면 1초 뒤에 파일과 연결을 끊는다.
쿠키 인증 단계를 넘어간 1초 사이에 파일에 idx 세션 값을 쓰고, 세션 값을 쓴 파일에 접근하면 된다.
즉 다른 쿠키로 1초 내 두 번 접근 하면 된다.
둘 다 로그인한 채 PHPSESSID를 다른 숫자로 바꿔놓는다.
https://webhacking.kr/challenge/web-37/?mode=auth
PHP
복사
세션 쿠키 값을 바꿨으므로 둘 다 첫 새로고침에는 재로그인이 필요하다. 쿠키 값은 다행히 다시 바뀌지 않는다.
그대로 둘다 1초내로 동시에 새로고침하면 해결된다.