<?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");
}
?>
먼저 PHPSESSID가 is_numeric()에 안걸리면 안되기 때문에 '12345'로 변조해보겠슴다
이후 로그인을 다시 해주고, URL에 ?mode=auth를 입력합니다
코드대로 'Auth~'가 출력되네요
세션 ID를 숫자로 바꾸지 않고 바로 auth mode로 가면 Access Denied가 뜹니다
그 다음 코드를 보면
$result = file_get_contents("./readme/{$_SESSION['idx']}.txt");
txt파일을 문자열로 읽어오는 코드인데, idx가 같으면, 'Done!'을 띄우며 문제가 풀려요
하지만 마지막 if문에서 접속한 IP가 127.0.0.1이 아니면 1초 뒤 unlink()로 파일을 삭제해버립니다
그런데 접속한 주소가 127.0.0.1이 되게 변조하는 법을 못 알아봤어요..
라업을 찾아보니 Race Condition 문제라는데 개념은 알아도 이게 어떻게 적용되는지 몰라서
한참을 이해 못했는데.. 결국 if문 조건은 아무 관련이 없었고, sleep()이 핵심이었습니다.
슬립하는 그 1초 사이에 다른 클라이언트로 똑같이 접속하면
원래 클라이언트와 경쟁해서 flag를 볼 수 있을 것 같다는 생각이 들었어요
그래서 이번엔 크롬이 아닌 익스플로러로 접속했어요
세션 ID를 똑같이 숫자로, 하지만 크롬에서의 '12345'와는 다르게 '123'으로 설정해줍니다
새로고침 후, 재로그인까지 끝내고
양쪽에 두 창을 동시에 띄운 후 1초 안에 크롬-익스 또는 익스-크롬 순으로 새로고침을 누릅니다
이 의미는 하나(먼저 새로고침 누른 브라우저)는 txt파일 생성용으로,
하나(두번째로 새로고침한 브라우저)는 문제 푸는 용으로 쓰겠다는 뜻입니다
제 경우엔 크롬에서 문제가 풀렸으니 익스가 txt 파일 생성용으로 쓰인 거져
127.0.0.1이 중요한게 아니라, sleep(1) 사이에 다른 클라이언트가 접속해서
'파일 삭제-파일 생성-문제 해결' 단계가 뒤섞이도록 새로고침을 몇 번 눌러주면,
어느 순간에 파일 삭제보다 문제 해결의 순서가 앞서서 문제가 풀리는.. 겁니다!
'Wargame > webhacking.kr' 카테고리의 다른 글
Challenge old 42 (200) (0) | 2020.02.18 |
---|---|
Challenge old 61 (200) (0) | 2020.02.18 |
Challenge old 59 (200) (0) | 2020.02.17 |
Challenge old 58 (150) (0) | 2020.02.17 |
Challenge old 56 (250) (0) | 2020.02.11 |