WebHacking

[root-me] PHP register globals

BIGFROG 2020. 1. 6. 17:51

우선, register_globals이 뭔지부터 알아보자.

 

register globals는 internal PHP setting이다.

 

서버에 액세스하는 방법을 제어하며,

 

ON상태와 OFF상태가 있다. 디폴트 값은 OFF이다(보안 문제 때문).

 

ON상태 - Global배열( GET[], POST[], REQUEST[] 등) 없이 양식 속성에 액세스 가능

 

OFF상태 - Global배열을 통해서만 모든 속성에 액세스 가능

 

OFF 상태인 경우, Global배열을 이용해서 파라미터를 받으면 액세스가 가능하다.

 

아무래도 보안에 취약한 점을 이용해서 문제를 냈을테니까,

 

register globals가 ON상태임을 예상할 수 있다.

 

먼저, 힌트에서 준 백업 파일을 찾아보자.

 

패스워드가 어떤 방식으로 인증을 거치는지 알아야 되니까, 소스코드가 필요하다.

 

url에 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;

 

?>

 

[첫 번째 풀이]

 

맨 아래 부분에 $aff값을 echo하기 전에 hidden_password를 불러온다.

 

따라서 저 부분을 포함하는 if문의 조건(이 방법에서는 OR연산의 두 번째 조건)이 True가 되게 만들어야 한다.

 

간단하게 $_SESSION["logged"]의 값이 1이면 될 것 같다.

 

url에는

ch17/?_SESSION[logged]=1 로 넣어주면 flag를 얻을 수 있다.

 

*URL을 작성하고 아래 버튼(connect)을 누르면 안된다. URL창에서 엔터 키를 눌러서 값을 전달해줘야 한다.

 

 

[두 번째 풀이]

 

마지막 if문의 첫 번째 조건에 주목한다.

 

1. isset(&password)이므로 무언가 값이 들어가서 True를 만들어 줘야 한다.

2. $password != "" - 마찬가지로 password에는 값이 들어가야 한다.

3. auth($password,$hidden_password)==1 - 위의 auth 함수에서 두 인자를 비교해서 같은지를 확인한다.

 

그래서 나는 url에 password=1&hidden_password=1을 넘겨주었다.

?password=1&hidden_password=1 로 넘겨주면,

You can validate with the password : 1

이라는 문구가 출력된다. 당연히 1은 답이 아닌데,

여기서 중요한 것은 서버에서 내가 hidden_password를 알고 있다고 인식했다는 것이다.

따라서 이 상태에서 url을 원래 상태(ch17까지만 있는 상태, url에 파라미터 없음)로 되돌려서 새로고침해주면 원래의 hidden_password가 호출된다.

 

'WebHacking' 카테고리의 다른 글

[root-me] Local File Inclusion - Double encoding  (0) 2020.01.06
[root-me] Local File Inclusion  (0) 2020.01.06
[root-me] File upload - MIME type  (0) 2020.01.06
[root-me] PHP filters  (0) 2020.01.06
[root-me] File upload - null byte  (0) 2020.01.06