好久没看题了,记录一道感觉还挺有意思的题目
一进去题目界面非常简洁,一个计算器
这个简洁的界面,好像似曾相识,总感觉好像以前做题时遇到的ssti题目的界面,果断来一波ssti
emem有WAF,尝试下绕过,发现他过滤了好多ssti用到的字符或者关键字,于是决定找一找别的出路
看了下源代码,发现有个/calc路径
去那边看看发现站是python写的,然后还爆出了源代码,看到了waf的黑名单,真的麻了,ssti应该是很难走了,看看哪里有危险函数吧
这段应该就是这道题的核心了,可以看到我们传入的num会被waf过滤,然后才会到我们的eval函数里,这里我尝试了下num传一些python代码进去,这个黑名单太绝了,搞不定,果断放弃这条路,下面还有个os.system(log),我们来研究一下这个玩意。
log = “echo {0} {1} {2}> ./tmp/log.txt”.format(time.strftime(“%Y%m%d-%H%M%S”,time.localtime()),ip,num)这句话命令执行的最终效果应该是把时间,ip,num写到./tmo/log.txt里去,其中num我们可控,如果我们直接注入命令那他能执行吗?
这里我们注入的命令没有执行,不过也很合理,因为这里是个字符串,所以他直接写入log.txt里了,这时候如果我们用点linux命令执行的特性,让他知道这一串是我们想要执行的命令,效果会是什么样呢?
反引号可以用,但是这里用不了,被waf拉黑了,同时我们要注意一点num还会被扔到eval里去,直接扔一个字符串到eval里会报错,eval必须不报错才能走到我们的os.system(),我们传入的肯定会是一个字符串其内容不为python代码,但是又要让eval不报错,最好的办法就是用python的注释了。
python中第一种注释方法是用#,但在Linux中不会把#当作注释,所以就可以用这个方法绕过eval(),并成功到达os.system执行系统命令,而#前面一定要有东西,不然会报错。
很可惜这道题把#过滤了没法用,但python中还有个多行注释’‘’,我们可以用这个,同样,在linux中不会把’‘‘当成注释,他解析时会把前两个‘凑一对,因此在Linux中’’'等价于‘。
我们可以这么构造传参给num
'''ls'
whoami
'pwd'''
这样shell执行系统命令时就会是这样
'ls'
whoami
'pwd'
这样命令就成功逃逸出来了,然后扔到实际环境看看吧,因为实际环境中把空格给过滤了,所以要tab代替,填了它的url编码%09
emem样式应该是没问题的,但是没收到curl的请求,再把换行符也换成url编码%0a
剩下的部分就不多说了,这道题的学习到这里就结束了,主要是利用了python和shell对不同字符解析的差异来做的。