欢迎来到 嗅灵易学

零基础也能上手的脚本技术课,一对一答疑带你入门

[投稿]MYSQL注入入门#1

[投稿]MYSQL注入入门#1

1.       万能密码登录


登录逻辑代码如上,


什么是sql注入?

有时候我们需要用户输入一些参数来帮助构造sql语句,完成数据库查询。但是因为输入的数据没有进行任何限制,所以当数据中包含了而已sql语句,就能劫持原来的sql语句,产生sql注入。

在登录时随便输入用户密码,



拼接成如上sql语句。

要想成功进行登录,就必要


$row有数据,则select语句where必须为真,那么拼接后的sql语句只需要满足where为真的条件即可,这里pwd字段进行了md5加密,无法构造,可以从user字段入手。

接下来用户名输入admin’ or ‘1’=’1,密码随便


拼接成这样,因为and优先级大于or,所以where结果是true or (true and false)=true,登录成功

2.       猜解注入获取密码

如果这时候我除了登录外,我还想获取用户密码,应该怎么办?

第一步:先构造出登录成功的语句

为了方便,使用发包方式


输入的是user’#,这样就能注释后面语句,相当于where user=’admin’#,为true登录成功

第二步:猜测密码字段

现在我们是不知道表中有什么字段,首先要获取密码字段。这里我们知道登录的时候肯定用的是用户表,所以这里不需要猜测用户表。

常见的密码字段有pwd,pass,password,以及与form表单中相同的字段。另外也可以使用字典爆破。

现在输入admin' and pass!=''#


假如pass不是密码字段,不存在这个字段的话,一般就会报错或者本来是登录成功的变成登录失败,因为密码一般不为空,所以字段存在就为true,而user=’admin’也是true的,所以可以利用这个特性判断字段是否正确。

这里经过几次尝试,得出pwd是密码字段


第三步:获取密码长度

Mysql中有一个length函数,来获取当前字段的值的长度


因为where是否为true取决于pwd字段,所以只要用二分法就能获取密码的长度,如上图length(pwd)>20是为true的,所以密码大于20位,


失败,密码在21-40位之间


31-40位之间


以此类推,得到密码位32位

第四步:猜解密码

Mysql中mid函数MID(字符串,位置,长度)。ASCII函数获取一个字符的ascii值,常用的acsii的值有‘0’为48,‘A’为65,‘a’为97。

因此输入admin' and ascii(mid(pwd,1,1))>65#


发现第一位密码为数字


小于52


大于48


不大于50


最终确定第一位密码的ascii值是50,对应的字符为’2’。

接下来31位也如此处理,admin' and ascii(mid(pwd,2,1))>65#

最后得到结果是

21232f297a57a5a743894a0e4a801fc3

是md5加密,扔去解密

http://www.cmd5.com/


3.       UNION注入绕过无密码字段查询


这个与(1)的区别就是密码验证不是判断是否有数据返回,而是通过用户查询的这条记录,然后判断传入的密码是否跟数据库中的相同。

当如果依旧输入admin'#


发现登陆失败,为什么呢?

因为虽然构造sql语句成功,也返回了结果


但是这里的判断还是没有通过,因为密码不正确。

那有什么方法呢?

如果能控制返回结果不就行了么。

第一步:判断表中有多少个字段

使用order by可以进行判断表中有多少个字段,order by除了可以按字段名排序外,也可以按字段的列数来排序。


这里表示按第3列排序

但是如果这里写4


就报错了。

证明用户表有3个字段。

第二步:使用UNION查询

在mysql里union可以把两条语句查询的结果合并,但两个结果集字段的列数要相等

这里我们先清除语句1的结果,合并的结果就只能是语句2了


select null,null,null

上面这条语句是最终结果,但是我不知道密码账号分别在第几个字段,所以这里可以将所有字段都填入密码

首先将随便一个字符串md5加密

Md5(’123’)=’ 202cb962ac59075b964b07152d234b70’

最后输入

用户名admin' and 0 union select '202cb962ac59075b964b07152d234b70','202cb962ac59075b964b07152d234b70','202cb962ac59075b964b07152d234b70'#

密码123


为什么这样能登录成功?

当输入上面语句时,构造的语句为

select * from user where user='admin' and 0 union select '202cb962ac59075b964b07152d234b70','202cb962ac59075b964b07152d234b70','202cb962ac59075b964b07152d234b70'


返回的结果是

select '202cb962ac59075b964b07152d234b70','202cb962ac59075b964b07152d234b70','202cb962ac59075b964b07152d234b70'


但判断的时候


输入的密码正好是123


的md5值正确,登录成功

4. 添加密码字段获取密码

这是(3)的另一种方法,这里我想既然你sql语句不写密码字段,那我就写回去。

第一步:猜解密码字段

(2)中提到了方法,这里不再讲述

第二步:猜解密码

这里跟(2)的差不多,但也有点不同



无论where是true还是false都是登录失败,原因(3)中提到了,那该怎么区分?

Mysql中的if函数IF(条件,返回1,返回2),当条件成立返回返回1,否则返回返回2,这里如果输入admin' and IF(length(pwd)<7,'test',exp(~1))#

exp(~1)在mysql里会报错,那么一个报错,一个登录失败,就能进行区分



5.with rollup(更新)

在CTF上面看到这种思路,这里加上..


本来 with rollup是分组后这些统计函数的结果再总体统计一次


这行是with rollup新增的

但是如果不用sum这些函数







对谁进行分组谁就变成NULL

利用这个特性,这里我干脆所有都变成NULL



可以看到最后一行是全NULL的

回到[3]的题目


这里我就是取全NULL的一行,但是有一个问题,就算pwd="",经过md5后也是有值的

不过php的md5有一个特性就是md5的参数如果传入一个数组会返回NULL


登录成功

注意:上传附件及图片大小不得大于30M。

⚠️ 版权声明:
本博客所有内容(含教程、源码、工具)仅供个人技术学习与研究交流使用,严禁商用、倒卖、二次分发及非法用途
未经作者书面授权,任何组织或个人不得转载、复制或用于其他平台,违者将追究相关责任。

0 0 0 举报
复制成功