Web: Guess me
문제: http://ctf.j0n9hyun.xyz:2030
php 소스코드가 주어져있다.
비밀코드를 맞히면 플래그를 획득할 수 있는 문제다.
소스코드를 하나씩 분석해보자.
$filename = 'secret.txt'
파일이름 변수에 'secret.txt'가 들어있다.
extract($_GET);
$_GET 배열의 키값을 변수로 만들어준다.
ex) $_GET['filename'] => $filename
if($guess)
$guess로 설정된 변수가 있는지 검사한다.
$secretcode = trim(file_get_contents($filename));
$filename에서 공백을 지운 내용을 $secretcode에 담는다.
if ($guess === $secretcode)
$guess와 $secretcode가 같으면 flag를 출력한다.
즉 secret.txt 파일의 내용에서 공백을 제거한 값이 $guess의 값과 같다면 flag를 출력한다.
secret.txt 파일의 내용이 무엇인지 확인해봤다.
음...역시 쉽게는 안 풀리겠지....
이번엔 코드 자체의 취약점을 찾아보는 방법으로 접근하고자 했다.
가장 먼저 file_get_contents() 함수의 취약점을 찾아봤다.
1. file_get_contents() 함수는 인자의 값을 통해 웹사이트의 정보를 가져오는 함수다.
2. 인자에 해당하는 경로를 찾지 못 하면 Null을 반환한다.
취약점이 될 수도 있는, 위와 같은 file_get_contents() 함수들의 특징을 알아냈다.
위의 특징들을 이용하려면 $filename을 변경할 수 있어야 할 것 같다.
ex) $filename을 알고 있는 다른 웹사이트 경로로 변경 or 존재하지 않는 경로로 변경
두 경우 모두 file_get_contents()의 반환값을 우리가 알 수 있기 때문에 $guess 값을 알맞게 설정해서 flag를 획득할 수 있다.
음...그런데 $filename을 어떻게 변경해야 할까.
찾아보니 extract() 함수의 취약점에서 이 의문을 해결할 수 있었다.
extract() 함수가 변수 선언 뒤에 나타나면 해당 변수의 값을 overwrite할 수 있는 취약점이 있다고 한다.
문제 php코드에서
$filename = 'secret.txt';
extract($_GET);
이 부분이 취약점의 원인이 되는 것이다.
이 경우에 $filename이 사용자에 의해서 덮어쓰기가 가능하다고 한다.
첫 번째 방법
$filename을 존재하지 않는 경로로 변경
$secretcode == Null
$guess도 Null로 설정
→ $filename을 hi로 변경하고, $guess엔 아무 값도 주지 않음
두 번째 방법
$filename을 알고 있는 웹사이트 경로로 변경
$secretcode == {해당 웹사이트에서 공백을 제외한 내용}
$guess == $secretcode가 되도록 $guess 값 설정
→ 이전에 풀었던 robots.txt 문제에서 사용했던 flag경로와 flag를 각각 $filename과 $guess로 설정
느낀점
이번 문제는 extract() 함수의 취약점을 알고있는지 물어보는 문제였다.
필자는 해당 함수의 취약점을 몰라 다른 함수의 취약점을 살펴보았었다.
정확한 접근은 아니었지만, 비슷한 접근을 통해 문제를 해결하는 일이 점점 늘어나고 있는 것 같다.
앞으로도 꾸준히 문제 풀이를 하면 더욱 정답에 가까운 접근을 할 수 있을 거라고 생각한다.
'Study > Web Hacking' 카테고리의 다른 글
[suninatas] Game 02 (1) | 2022.05.10 |
---|---|
[suninatas] Game 01 (1) | 2022.05.10 |
[HackCTF] 보물 (1) | 2022.05.02 |
[HackCTF] Button (1) | 2022.04.05 |
[HackCTF] Hidden (1) | 2022.04.04 |