HackCTF Web의 5번째 문제는 Guess me다.
문제 링크: http://ctf.j0n9hyun.xyz:2030/
다음 코드에서 플래그가 출력되도록 하는 동작을 수행하면 되는 것 같다.
이 문제를 풀 때 extract() 함수에서 $_GET과 같은 사용자의 입력 데이터가 사용되는 것을 봐서 이 문제는 PHP의 extract 함수의 취약점에 대해 묻는 문제라고 판단했다.
PHP의 extract 함수는 배열에서 변수를 가져온다. extract 함수를 사용하면 기존에 사용하고 있는 변수에 데이터를 덮어씌울 수 있다. 따라서 extract 함수에 사용자의 입력($_GET, $_POST, $_FILES)과 같은 신뢰할 수 없는 데이터가 올 수 있다면 변수를 변조해서 공격할 수 있게 되는 것이다. php의 extract 문서에서는 아래와 같이 사용자의 데이터와 같이 신뢰할 수 없는 데이터를 사용하지 않는 것을 권고하고 있다.
extract 함수에 대한 취약점까지 알아봤으니, 다시 코드에 대해 살펴보자.
$filename = 'secret.txt';
extract($_GET);
처음 filename은 secret.txt다. extract()에서 $_GET의 사용자 입력 데이터가 사용된다. 이 부분에서 우리가 입력한 값으로 filename의 값을 덮어써서 변조할 수 있지 않을까 예상해 볼 수 있다.
if(isset($guess)) {
$secretcode = trim(file_get_contents($filename));
isset()은 해당 변수가 설정되었는지 확인하는 함수다. 조건문이 작동해서 flag를 얻어야 하기 때문에 GET 방식으로 데이터를 입력할 때 guess 변수를 설정해 줘야 한다는 것을 알 수 있다.
file_get_contents()는 전체 파일을 문자열로 읽어들이는 PHP 함수다. trim 함수의 경우 문자열의 맨 앞, 맨 뒤의 여백을 제거한다. 따라서 이 과정을 거친 secret.txt 파일의 값이 secretcode 변수에 저장된다는 것을 알 수 있다.
if($guess === $secretcode) {
$flag = file_get_contents('flag.txt');
echo "<p>flag is.""$flag</p>;
}
guess 변수와 secretcode 변수의 값과 자료형이 모두 동일해야 조건문이 작동하면서 flag 값을 알 수 있다. secretcode에 해당하는 값은 secret.txt에서 전체파일을 문자열로 읽어 들인 값이다.
secret.txt를 읽어 들이는 데서 오류가 발생했다.
소스 파일에도 있었다. 이를 file_get_contents() 함수와 trim() 함수를 사용한 값을 직접 guess 변수 값을 지정해서 문제를 푸는 방법도 있지만, 위에서 설명한 extract 함수의 취약점을 이용하면 더 쉽게 문제를 풀 수 있다.
filename을 GET 방식으로 변조할 수 있다.
위와 같이 변조해서 문제를 풀었다. fliename을 NULL 값으로 설정했는데 NULL은 php에서 False와 자료형까지는 동일하지 않지만 동일한 의미를 가진다고 한다. 즉, NULL과 False의 비교에서 ===(identical) 비교는 False를 반환하지만, == (equal) 비교에서는 True를 반환한다.
또한, guess 변수도 선언해줬다. 결국엔 덮어써진 filename의 입력 값과 guess의 입력 값이 모두 NULL이다. 따라서 자료형과 의미가 모두 동일하고, === (identical) 비교 연산이 True가 되어서 flag를 출력하는 조건문이 동작하는 것이다.
화면에 나온 flag를 입력하면 문제가 풀린다. extract 함수의 취약점을 이용해 플래그를 얻을 수 있는 문제였다.
[HackCTF-Web#7] Login - 100 points (0) | 2021.03.24 |
---|---|
[HackCTF-Web#6] Read File - 100 points (0) | 2021.03.23 |
[HackCTF-Web#4] 보물 - 100 points (0) | 2021.01.24 |
[HackCTF-Web#3] Button - 50 points (0) | 2021.01.01 |
[HackCTF-Web#2] Hidden - 50 points (0) | 2020.12.31 |
댓글 영역