패스워드만 입력받는 로그인창이 주어진다.
$_POST['key']=value
과 같은 범용 딕셔너리($_GET, $_POST, $_SERVER
등)를 key와 value를 쌍으로 한 변수로 생성하는 것을 말한다.
이렇게 되면 해당 공격자가 php 코드안에서 처리될 임의의 변수를 생성하는 것이 가능해진다.
이를테면, $bob = 123
을 생성하고 싶을 경우 get 파라미터로 ?bob=123
을 보내게 되면 register_globals를 만드는 과정에서 $bob = 123
이라는 변수가 생성된다.
해당 취약점을 이용하려면 생성해야할 변수이름을 알아야 하고 그러기 위해선 소스코드나 관련 힌트가 존재해야 한다.
문제를 보면
It seems that the developper often leaves backup files around...
백업파일이 존재한다고 나와있다.
일반적으로 자주 사용되는 형식인 xxx.bak
을 이용해서 index.php
의 백업파일을 접근해보면 파일이 다운로드 된다.
소스코드를 확인해보자
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;
?>
중간에 register globals를 처리하는 루틴이 있으며,
마지막에 내가 입력한 값 $password
와 비교 대상인 $hidden_password
와 같거나
혹은 $_SESSION["logged"]
의 값이 1이면 패스워드가 출력된다.
$hidden_password
를 새로 생성할 경우 플래그값이 덮어써지므로 조건1을 건드려서는 안되고
조건2에 해당하는 $_SESSION["logged"]
값을 1로 생성하자.
?_SESIOn[logged]=1