Web-Server) php filter, Local file inclusion, register global
Wargame/Root-Me

Web-Server) php filter, Local file inclusion, register global

1. php filter

Retrieve the administrator password of this application.

: 일단 rootme 는 제목부터 힌트가 너무 심하긴 한것같다ㅋㅋㅋㅋ.

예전에 php filter를 활용한 webhacking.kr문제를 풀어본적이 있어서 일단 php:://filter를 사용해서 index,php파일을 요청해보았다. 그랬더니 일단 base-64로 인코딩한 문자열을 얻을수 있었다. burpsuite로 디코딩해보았더니 그 php 파일의 내용이 전부 보였다.

 

 login.php 파일도 전부 볼수 있지 않을 까 싶어서 request에서 파라미터를 살짝 변조해보았다.

 

역시 login.php 파일의 내용을 살펴볼 수 있었다. 

<?php
include("config.php");

if ( isset($_POST["username"]) && isset($_POST["password"]) ){
    if ($_POST["username"]==$username && $_POST["password"]==$password){
      print("<h2>Welcome back !</h2>");
      print("To validate the challenge use this password<br/><br/>");
    } else {
      print("<h3>Error : no such user/password</h2><br />");
    }
} else {
?>

<form action="" method="post">
  Login&nbsp;<br/>
  <input type="text" name="username" /><br/><br/>
  Password&nbsp;<br/>
  <input type="password" name="password" /><br/><br/>
  <br/><br/>
  <input type="submit" value="connect" /><br/><br/>
</form>

<?php } ?>

여기서 config.php파일을 include하고 있어서 아마 여기서 $username , $password 변수를 얻을 수 있을 듯 해서

한 번더 php filter로  config.php파일을 요청해보았다.

 

admin의 아이디와 패스워드를 얻을 수 있다. 패스워드 그대로 validate가 된다! php filter를 알고 있다면 어려운 문제는 아니었을 것 같다. 모른다면 webhacking.kr old 25참조~

 

2.PHP register global

:우선, register_globals이 뭔지부터 알아보자.
register globals는 PHP의 내부적인 세팅 중 하나이다. 서버에 액세스하는 방법을 제어한다.
on 상태에서는 global배열( GET[], POST[], REQUEST[] 등) 없이 양식 속성에 액세스가 가능하고, off 상태에서는 global배열을 통해서만 모든 속성에 액세스가 가능하다. on 상태여야 취약한 상태일 것이라고 추정이 가능하다.

일단 힌트에서 backup file이 있을 것이라고 했기 때문에  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;

?>

-> 소스코드를 천천히 훑어보면 $_SESSION["logged"]=1;이어야 global 배열에 접근하지 않고 바로 통과가 가능한 것으로 보인다. 아마 register_global을 on 상태로 만들어줘야 하는 것 같다. 그런데.. session변수를 어디서 접근해야 되는지 애매해서 다른 방법을 찾아보기로 했다. 

쭉 아래로 살펴보면 validate된 상태를 얻을수 있는 조건이 있는데, password와 hidden_password가 같으면 통과가 되는 듯 하다. 파라미터로 p=a&&hp=a 로 넘겨줘 보았다.

 

일단 hidden_password가 a로 주어진 상태라 이렇게 뜨지만, hidden password의 존재는 알렸기 때문에 파라미터를 없애고 새로고침 하면 패스워드를 얻을 수 있다.

 

 

3. Local file inclusion

:LFI 문제이다. 뭔가 이전 문제보다 쉬운 것 같다. 일단 files 파라미터에 ../를 가볍게 넣어보았다.

 

admin? 파일이 존재한다. 저 파일로 이동해보자.

 

 

index.php 파일이 존재하고, 잘 읽으면 패스워드를 얻을 수 있다. 30점 짜리인데 허무한 점이 없지않아 있다..