워게임/Root Me

[Root Me] PHP - register globals - 웹해킹 / 백업파일

SecurityMan 2022. 7. 20. 11:00

 

PHP register globals 와 관련된 웹해킹 문제

 

register globals 는 php 설정파일인 php.ini 파일에 있는

 

옵션 중 하나인데

 

이 값이 만약 on 으로 설정되어 있을경우, 외부에서 GET 이나 POST로 전달된 값들이

 

자동으로 php 변수로 바뀌게 된다.

 

반응형

 

문제 설명에 힌트가 살짝 적혀있다.

 

개발자들은 종종 백업파일을 남겨놓는다고 한다.

 

 

문제페이지에 접속하면 이렇게 비밀번호 입력하는 창이 나온다.

 

 

개발자가 남겨둔 백업파일을 먼저 찾아본다.

 

보통 백업파일은 파일명 뒤에 .bak 이런식으로 저장하는 경우가 많다.

 

주소창 맨 뒤에 index.php.bak 이라고 입력해보면

 

 

이렇게 백업파일이 자동으로 다운로드 된다.

 

아이콘은 한글파일인데 무시해도 된다.

 

<?php


function auth($password, $hidden_password){
    $res=0;
    if (isset($password) && $password!=""){
        if ( $password == $hidden_password ){
            $res=1;
        }
    }
    $_SESSION["logged"]=$res;
    return $res;
}



function display($res){
    $aff= '
	  <html>
	  <head>
	  </head>
	  <body>
	    <h1>Authentication v 0.05</h1>
	    <form action="" method="POST">
	      Password&nbsp;<br/>
	      <input type="password" name="password" /><br/><br/>
	      <br/><br/>
	      <input type="submit" value="connect" /><br/><br/>
	    </form>
	    <h3>'.htmlentities($res).'</h3>
	  </body>
	  </html>';
    return $aff;
}



session_start();
if ( ! isset($_SESSION["logged"]) )
    $_SESSION["logged"]=0;

$aff="";
include("config.inc.php");

if (isset($_POST["password"]))
    $password = $_POST["password"];

if (!ini_get('register_globals')) {
    $superglobals = array($_SERVER, $_ENV,$_FILES, $_COOKIE, $_POST, $_GET);
    if (isset($_SESSION)) {
        array_unshift($superglobals, $_SESSION);
    }
    foreach ($superglobals as $superglobal) {
        extract($superglobal, 0 );
    }
}

if (( isset ($password) && $password!="" && auth($password,$hidden_password)==1) || (is_array($_SESSION) && $_SESSION["logged"]==1 ) ){
    $aff=display("well done, you can validate with the password : $hidden_password");
} else {
    $aff=display("try again");
}

echo $aff;

?>

 

index.php.bak 파일의 내용은 위와 같다.

 

 

auth 함수의 내용을 살펴보면

 

인증을 할때 password만 검증하는것이 아닌것을 알 수 있다.

 

password 와 hidden_password 의 값이 같아야

 

$_SESSION["logged"] 값이 1로 세팅되면서 인증이 수행된다.

 

 

register globals 취약점을 이용해본다.

 

URL에 ?password=1&hidden_password=1 라고 전달해서

 

password와 hidden_password의 값을 1로 세팅해버린다.

 

그럼 인증이 성공해서 well done 이라는 문구가 뜨는것을 볼 수 있다.

 

 

그리고 나서 새로고침을 해주면 원래 비밀번호를 찾을 수 있다.

 

새로고침 안하고 한번에 푸는 방법도 있다.

 

 

아까 봤듯이 auth 함수에서

 

인증이 성공하면 $_SESSION["logged"] 변수에 1 이 세팅되므로

 

 

URL에 ?_SESSION[logged]=1 이라고 입력하면 된다.

반응형