Wargame/Root-me = Web - Server
<Root-me> PHP - register globals
지우친구 웅이
2022. 1. 14. 12:18
비밀번호를 입력할 수 있다.
문제 설명을 보면
개발자들이 종종 백업 파일을 주변에 남겨둔다고 한다.
BAK 파일은 동일한 목적으로 여러 응용 프로그램에서 모두 사용되는 백업 파일이다. 대부분의 BAK 파일은 백업을 저장해야하는 프로그램에 의해 자동으로 작성된다.
따라서, ./index.php.bak을 입력하면 index.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 <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;
?>
문제를 해결하기 위해서는
$password 값이 설정되어있어야 하고, 빈 문자열이 아니어야 한다.
그리고 auth($password, $hidden_password)가 1을 반환해야 한다.
또는, $_SESSION이 배열이어야 하고, $_SESSION["logged"]가 1이어야 한다.
따라서, URL에 ?_SESSION[logged]=1을 입력하면
비밀번호를 획득할 수 있다.
대부분의 웹 사이트에서는 $_SESSION[logged]를 사용할 수 없다.
register globals는 php.ini 설정의 내부 php 설정으로, 서버에 접근하는 방법을 제어하며 ON과 OFF 상태가 존재한다.
보안 문제로 인해 default는 OFF 상태이다.
ON 상태이면, Global 배열(GET[], POST[], REQUEST[] 등) 없이 양식 속성에 접근할 수 있다.
OFF 상태이면, Global 배열을 통해서만 모든 속성에 접근해야 한다.
문제 제목이 register globals인 것으로 보아 ON 상태임을 짐작할 수 있다.