PHP代码审计之WEB安全系列基础文章(七)XSS篇

【如需转载,请详细表明来源,请勿设置原创】

嗨,大家好,我是闪石星曜CyberSecurity创始人Power7089。

欢迎大家扫描下方二维码关注 “闪石星曜CyberSecurity” 公众号,这里专注分享渗透测试,Java代码审计,PHP代码审计等内容,都是非常干的干货哦。

公众号

今天为大家带来PHP代码审计基础系列文章第七篇之XSS篇

这是【炼石计划@PHP代码审计】知识星球第二阶段的原创基础系列文章,拿出部分课程分享给零基础的朋友学习。本系列原创基础文章涵盖了PHP代码审计中常见的十余种WEB漏洞,是匹夫老师精心的创作,欢迎关注我的公众号跟着一起学习。

【炼石计划@PHP代码审计】是一个系统化从入门到提升学习PHP代码审计的成长型知识星球。这里不仅注重夯实基础,更加专注实战进阶。强烈推荐加入我们,一起来实战提升PHP代码审计。

公众号

PHP代码审计之XSS(跨站脚本攻击)

pikachu靶场安装

在本节的部分内容会用到pikachu靶场来进行演示教学,pikachu源码会与文章一起下发,大家使用phpstudy将pikachu放入www进行搭建即可,具体搭建方法如下:

将源码放置在phpstudy中WWW目录下,修改inc/config.inc.php文件,将phpstudy中设置的数据库用户名、密码以及端口填入,这里注意如果数据库端口不是默认的3306,那么需要在DBHOST中跟端口号

image-20220717173918010

这里选择pikachu根目录即可,PHP版本建议使用PHP7以下的版本。

image-20220717173228036

然后点击上方的初始化进行安装

image-20220717173436840

如果出现如下内容就表示安装成功了。

image-20220717174024201

1.XSS原理

​ XSS(Cross Site Scripting),为了不和层叠样式表(Cascading Style Sheets, CSS)的缩写混淆,故将跨站脚本 攻击缩写为XSS,他的中文名称为:跨站脚本攻击。而XSS的重点不在于跨站,而在于XSS中执行的JavaScript脚本情况。

​ Web程序代码中把用户提交的参数未做过滤就直接输出到页面,参数中的特殊字符被恶意进行闭合造成原有的html页面被嵌入恶意的脚本内容,黑客可以利用该漏洞执行恶意JavaScript代码,当用户浏览该页之时,嵌入其中Web里面的JavaScript代码会 被执行,从而达到恶意攻击用户的目的。

2.XSS分类

XSS常被分为三种类型:

  • 反射型XSS:直接将HTTP请求中的用户可控数据输出到HTML页面中的跨站脚本注入,由于用户可控数据没有被存储,因此只能在单次请求中生效。
  • 存储型XSS:又叫特久型XSS,直接将HTTP请求中的用户可控数据存储至数据库中,再从数据库中读取出来输出到HTML页面上,由于数据经过存储,可以持续被读取,攻击影响面和危害都较高。
  • DOM-XSS:特殊的反射型XSS,将用户可控数据通过JavaScript和DOM技术输出到HTML中,利用方式通常与反射型XSS类似。

2.1 反射型XSS

反射型XSS对于访问者来说是一次性的,当攻击者将构造好的恶意URL发送给访问者,访问者点击URL将我们的请求传递给服务器,服务器将不加处理的脚本“反射”回访问者的浏览器而使访问者的浏览器执行相应的脚本,最简单的代码如下。

反射型XSS执行方式:浏览器——>后端——>浏览器

示例代码:

1
2
3
4
<?php
highlight_file(__FILE__);
echo $_REQUEST['xss'] ;
?>

我们通过参数xss传入我们自定义的XSS脚本,脚本被前端页面解析并执行。

image-20220717170602216

在页面右击查看源码处我们可以发现我们输入的JavaScript脚本。

image-20220717170720901

2.2 存储型XSS

​ 存储型XSS与反射型XSS的区别在于,存储型XSS是被存储在数据库中的,攻击者只需将JavaScript脚本输入,后端将攻击者输入的JavaScript脚本保存到数据库中,访问者在每次访问存在XSS页面时存储在数据库中的JavaScript脚本就会被执行。

存储型XSS执行方式:浏览器——>后端——>数据库——>后端——>浏览器

pikachu存储型XSS靶场中存在如下代码:

xss_stored.php

这里代码24-26行,通过POST接收参数后,将数据插入到数据库中。

image-20220717174855954

这里代码80-83行,通过select查询数据库中刚才插入的数据并通过echo输出content字段内容,在这个过程中将我们插入的数据保存到数据库中并且进行任何过滤所以造成存储型XSS。

image-20220717175318811

这里我们输入JavaScript代码,成功执行并弹窗。

image-20220717175853246

image-20220717180012479

image-20220717180423340

在数据库中也可以发现我们的JavaScript代码被存储到数据库中。

image-20220717180054785

2.3 DOM型XSS

​ DOM型XSS与反射型XSS差不多,只不过DOM型XSS中会调动一些JavaScript中的函数来获取客户端提交的内容,定义了一个节点名字和值,然后再返给客户端。

DOM型XSS执行方式:URL-->浏览器

pikachuDOM型XSS靶场中存在如下代码:

xss_dom.php

在这里接收一个GET传入的值

image-20220717182421850

在代码56-58行,表单中调用domxss()函数,在代码49-50行,获取text内容赋值给变量str并拼接到a href标签中通过innerHTML将内容输入到页面。

image-20220717182534803

通过闭合’>将我们想要执行的JavaScript代码分离出来

image-20220717184043919

image-20220717184255591

3.XSS审计函数

​ 在XSS审计中我们其实多关注一些输出打印函数即可,它们的作用就是将输入的内容显示在前端页面,只要这些函数中内容可控且输出前没有进行完善的过滤就会造成XSS漏洞。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
print

print_r

echo

printf

sprintf

die

var_dump

var_export

4.XSS审计注意点

4.1 htmlspecialchars函数

​ 在htmlspecialchars()函数中,默认情况下不会对'进行转义,如果是代码中像下面这种情况,传入的text内容,在下面的input表单中输出且是被单引号包裹,我们就可以闭合单引号,在标签内构造XSS来绕过htmlspecialchars()函数。

1
2
3
4
5
6
7
<?php

highlight_file(__FILE__);
$content = htmlspecialchars($_GET['text']);
?>

<input type='text' class='find' value='<?=$content?>' >

我们可以在标签内闭合单引号,然后通过onclick在标签内构造一个点击事件来触发XSS。

image-20220717231558872

image-20220717231630813

4.2 编解码中存在的问题

​ 很多时候开发在写代码时存在一些逻辑缺陷,导致过滤函数无法发挥实际的效果,如下代码中首先通过text传入参数,然后紧接着对传入的参数进行htmlspecialchars()实体化编码,这里似乎没有问题。但浏览器的运行机制会默认对传入的参数进行一次url解码,由于代码中最后一段又进行了一次url解码并使用echo输出。那么我们就可以对传入的内容进行两次url编码来绕过htmlspecialchars()函数的过滤,从而造成xss。

1
2
3
4
5
6
7
8
<?php

highlight_file(__FILE__);

$content=$_REQUEST['text']; //接收参数并进行url解码
$cont=htmlspecialchars($content); //对传入的特殊字符进行实体化编码
echo urldecode($cont); //最后,url解码输出
?>

我们对中特殊字符进行两次URL编码%253Cscript%253Ealert('xss')%253C/script%253E,由于浏览器会首先对我们传入的数据进行一次URL解码,变成%3Cscript%3Ealert('xss')%3C/script%3E,在传入htmlspecialchars()函数时就会绕过该函数的过滤,在最后echo时又进行一次URL解码,最终还原我们的JavaScript代码<script>alert('xss')</script>

image-20220717233803489

image-20220717233835427

image-20220717233851679

5.XSS代码审计总结

1
2
在黑盒测试中XSS遵循一个见框就插的原则,而在PHP代码审计中我们主要关注上述的一些输出打印函数和代码中的一些编写逻辑来绕过某些过滤函数从而构造XSS payload进行利用。
pikachu靶场中XSS模块还有很多XSS关卡,大家可以在靶场练习的同时结合代码审计来了解靶场其中的过滤规则,这样可以更深入的了解XSS漏洞的触发原理。

PHP代码审计之WEB安全系列基础文章(七)XSS篇
http://example.com/2022/10/10/PHP代码审计之WEB安全系列基础文章(七)之XSS篇/
作者
Power7089
发布于
2022年10月10日
许可协议