Post

Wechall - Register Globals

Register Globals



1
2
3
4
5
6
7
8
9
This challenge is a relict of old PHP times, 
where register globals has been enabled by default, 
which often lead to security issues.

Again, your job is to login as admin

I have also setup a test account: test:test

Enjoy!


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
<?php
# EMULATE REGISTER GLOBALS = ON
foreach ($_GET as $k => $v) { $$k = $v; }
 
 
# Send request?
if (isset($_POST['password']) && isset($_POST['username']) && is_string($_POST['password']) && is_string($_POST['username']) )
{
        $uname = GDO::escape($_POST['username']);
        $pass = md5($_POST['password']);
        $query = "SELECT level FROM ".GWF_TABLE_PREFIX."wc_chall_reg_glob WHERE username='$uname' AND password='$pass'";
        $db = gdo_db();
        if (false === ($row = $db->queryFirst($query))) {
                echo GWF_HTML::error('Register Globals', $chall->lang('err_failed'));
        } else {
                # Login success
                $login = array($_POST['username'], (int)$row['level']);
        }
}
 
if (isset($login))
{
        echo GWF_HTML::message('Register Globals', $chall->lang('msg_welcome_back', array(htmlspecialchars($login[0]), htmlspecialchars($login[1]))));
        if (strtolower($login[0]) === 'admin') {
                $chall->onChallengeSolved(GWF_Session::getUserID());
        }
}
else 
{
?>
<form action="globals.php" method="post">
<table>
<tr>
        <td><?php echo $chall->lang('th_username'); ?>:</td>
        <td><input type="text" name="username" value="" /></td>
</tr>
<tr>
        <td><?php echo $chall->lang('th_password'); ?>:</td>
        <td><input type="password" name="password" value="" /></td>
</tr>
<tr>
        <td></td>
        <td><input type="submit" name="send" value="<?php echo $chall->lang('btn_send'); ?>" /></td>
</tr>
</table>
</form>
<?php
}
 
# EMULATE REGISTER GLOBALS = OFF
foreach ($_GET as $k => $v) { unset($$k); }
 
require_once 'challenge/html_foot.php';
?>






Solution



php 5.4 이전 버전에서 발생한 취약점으로 php.ini에 register_globals 라는 옵션이 있음.

이 옵션을 On 하게 되면 GET 또는 POST 방식 등으로 전될 된 모든 변수가 자동으로 php의 변수로 변환이 됨.


1
2
3
4
5
6
7
8
<?php 
	if(isset($get)){
		echo "success";
	}
	else{
		echo "fail";
	}
?>


위에 코드를 예시로 하면 $get에 아무 값도 없으므로 fail이 출력되지만 ?get=1을 하면 register_globals 옵션에 의해 get 변수로 변환되어 success가 출력됨.

따라서 문제 상에서 우리가 봐야 할 코드는 다음과 같음.


1
2
3
if (strtolower($login[0]) === 'admin') {
       $chall->onChallengeSolved(GWF_Session::getUserID());
}


$login[0] == 'admin' 이어야 하므로 ?login[0]=admin -> 성공






참고



Link
lactea.kr/entry/php-registerglobals-on-취약점






This post is licensed under CC BY 4.0 by the author.