CMS 文件管理系统:SQL 时间盲注
本文发表在博客园乌漆 WhiteMoon(https://www.cnblogs.com/linfangnan/),只要不是在博客园看到这篇文章的都是爬虫的哈。
任务目标
在CMS 文件管理系统:SQL Bool 盲注中,我们已经实现了 Bool 盲注。此处对 cms 系统进行时间 SQL 盲注,通过获取到的管理员密码登录。
查找注入点
首先先找找注入点,经判断在搜索框的 keywords 可能存在 SQL 注入。
在文章阅读框的 id 参数也可能是注入点。
判断注入类型
由于文章阅读框的参数比较简单,所以用这个参数来测试,首先先注入正常的参数,网页回显正常的信息。
尝试注入个单引号闭合,网页回显 MySql 报错,后端的 SQL 语句后面的内容注释后,网页仍然不能回显正确的信息。经过以下所有的测试都一样,也就是说我们注入的引号没有起到闭合的作用,这是一个数字型注入。
1' OR 1 = 1--+
1') OR 1 = 1--+
1')) OR 1 = 1--+
1" OR 1 = 1--+
1") OR 1 = 1--+
1")) OR 1 = 1--+
那就是数值型注入了,直接用注释把后面的东西注释掉,不用引号闭合。
1 OR 1 = 1--+
注意到在文章阅读在页面 id 后用 AND 连接 sleep() 函数,页面就会超时,说明后台 SQL 语句执行了睡眠函数,因此可以使用时间盲注。
获取数据库名
首先先搞清楚数据库名的长度,查询 id 为 33 的文章后用 AND 闭合确定数据库长度的语句。payload 由 IF 函数和 sleep() 函数组成,如果后面这个语句查询成功则页面会超时,显示不出文章。
?id=33 AND IF(LENGTH(database())=1,sleep(1),1)--+
一个一个测试太慢了,可以使用 Brup 来进行爆破,首先拦截包发给测试器,选择攻击模式为“狙击手”,设置填充数据的位置。
设置有效载荷,从长度 1 测试到长度 10。
由于 IF 语句执行成功时界面将超时不返回数据,所以攻击之后可以明显的看到,数据库名的长度为 3。
用 Brup 的重发器进行验证,可以看到响应的时间超过 1 秒。
获取数据库名
爆数据库名,使用 SELECT database() 查询数据库名,然后用 SUBSTRING() 挨个提取字符进行判断。
?id=33 AND IF(SUBSTRING((SELECT database()),1,1)='a',sleep(1),1)--+
使用 Brup 进行测试,注意此处要选用“集束炸弹”,因为 2 个需要填充的字符不同。第一个用于确定第几位数据库名,第二个是具体的字符,需要 2 个有效载荷。
第一个有效载荷为 3 个数字,因为我们刚刚测出数据库长度为 3。
第二个则为一个简单清单,内容是字母、下划线和数字集合。
进行攻击,根据结果可以看出数据库名为 “cms”。
获取表名
由于数据库中有多张表,所以需要挨个进行测试。先编写出 payload,它不仅要设置每次返回 1 张表名,还要对每张表名的每个字符进行判断。
?id=33 AND IF(SUBSTRING((SELECT table_name FROM information_schema.tables WHERE table_schema='cms' LIMIT 1,1),1,1)='a',sleep(1),1)--+
还是一样使用 Brup 进行测试,设置 3 个有效载荷,分别是第 n 行表名,表名的第 n 个字符,和用于测试的具体字符。
第一个是第 n 行表名,设置为数字 0 ~ 10。
第二个是表名的第 n 个字符,设置为数字 1 ~ 20。
第三个是用于测试的具体字符,设置为字母、下划线和数字集合。
进行攻击后,由于此处数据比较复杂,把结果导出查看。注意分隔符可以选用“,”,这样可以用 csv 格式打开,比较方便查看。
对 csv 进行排序之后,就可以获得所有表名。
获取字段名
先写出获取字段名的 payload,跟获取表名的 payload 思想一样。
?id=33 AND IF(SUBSTRING((SELECT column_name FROM information_schema.columns WHERE table_schema='cms' AND table_name='cms_users' LIMIT 0,1),1,1)='a',sleep(1),1)--+
还是一样使用 Brup 进行测试,设置 3 个有效载荷,分别是第 n 行字段名,字段名的第 n 个字符,和用于测试的具体字符。具体的有效载荷设置和前面思想一样,不再赘述。
攻击完成后保存为结果表,用 csv 格式打开,排序得到 cms_users 所有字段名。
cms_users 表拥有 3 个字段,分别是 userid、username、password。
获取敏感信息
先写出获取用户名和密码的 payload,此处我们换个写法。
?id=33 AND IF(SUBSTRING((SELECT group_concat(concat_ws(':',convert(username using gbk),convert(password using gbk))) FROM cms.cms_users),1,1)='a',sleep(1),1)--+
由于我们使用 group_concat 函数把用户名和密码拼接在一起,所以查询结果只有一个字符串。此时设置的有效载荷只有 2 个,只需要挨个判断这个字符串的内容就行,思想与上面一样不再赘述。
攻击结束,保存为结果表,用 csv 格式打开。
排序之后就可以查看爆出来的结果了,如果用户名和密码太多,也可以写 Python 处理,此处不再赘述。