-
Notifications
You must be signed in to change notification settings - Fork 456
Description
模板注入 src/controller/admin/template.js
/**
-
网站首页模版编辑
-
@returns {*}
*/
async homeAction() {
const gid = await this.model('temp_group').where({isdefault: 1}).getField('gid', true);
const map = {
module: 'home',
controller: 'index',
action: 'index',
type: this.para('type') || 1,
gid: gid
};
const temp = await this.model('temp').where(map).find();
let temppath;
if (temp.type == 2) {
temppath =${think.ROOT_PATH}/view/${temp.module}/mobile/;
} else {
temppath =${think.ROOT_PATH}/view/${temp.module}/;
}
const templateFile =${temppath}${temp.controller}${this.config('view.nunjucks.sep')}${temp.action}${this.config('view.nunjucks.extname')};
if (this.isPost) {
const data = this.post();
data.id = temp.id;
data.module = map.module;
data.controller = map.container;
data.action = map.action;
data.name = temp.name;
data.type = temp.type;
data.gid = temp.gid;
console.log(data);
// await this.model("temp").add(data);
temp.pid = temp.id;
delete temp.id;
temp.baktime = new Date().getTime();
temp.lastuser = this.user.uid;
console.log(temp);
// return false;
// 修改前先备份
if (data.html != temp.html) {
const bak = await this.model('temp_bak').add(temp);
const res = await this.model('temp').update(data);
if (!think.isEmpty(res)) {
fs.writeFileSync(templateFile, data.html);
return this.success({name: '添加成功!'});
}
} else {
return this.fail('请先修改模板!');
}
} else {
// 首页网站编辑
// console.log(this.adminmenu["10"]);
this.meta_title = '首页模板';if (think.isFile(templateFile)) {
const tempcon = fs.readFileSync(templateFile, 'utf8');
temp.html = tempcon;
}
// console.log(temp);
this.assign('temp', temp);
return this.display();
}
}
可以看到通过nunjucks模板对前端进行渲染,对传入的post请求的html参数只有判空校验,所以可以通过模板注入命令执行来进行RCE,直接构造调用child_process的命令执行,我们这里进行弹计算器演示


然后访问首页进行渲染

成功弹出计算器,其他的模板也存在该注入问题