我正在尝试制作一个机器人命令(.e args),以使您可以使用机器人命令执行任何代码。 我该怎么办?我尝试过:
cmd = message.content.slice(2);
cmd;
但是当我尝试输入Discord时它什么也没做,例如.e message.channel.send(“ Hello world!”) 我将如何进行这项工作?
答案 0 :(得分:1)
首先,我想说这是一个非常糟糕的主意,我真的希望你知道自己在做什么。
但是,我将自己作为大学的CTF(夺旗)挑战来实现(由其他学生解决)。 您可以找到完整的source code here。
现在,首先,您可以使用eval(cmd)
,但这是可怕的想法,因为这会使服务器遭受代码注入攻击。因此,为避免这种情况,我们将使用VM(虚拟机)。在这种情况下,我决定使用软件包vm2
。最重要的是,我决定要授予对文件系统的访问权限(对于CTF挑战),但是授予对实际FS模块的访问权限将带来灾难,因此我决定使用memfs
在以下环境中模拟FS模块记忆。
注意:以下代码是用typescript编写的,它是javascript的超集。
// index.ts
import { Client, Message } from 'discord.js';
import * as fs from 'fs';
import { vol as mfs} from 'memfs';
import * as path from 'path';
import { VM } from 'vm2';
const fakeFileSystemRoot = path.join(__dirname, '..', 'fake_file_system');
mfs.fromJSON(
fs.readdirSync(fakeFileSystemRoot)
.map((fileName) => [fileName, fs.readFileSync(path.join(fakeFileSystemRoot, fileName)).toString('utf8')])
.reduce((res, [fileName, file]) => ({...res, [fileName]: file}), {}),
);
const secrets = require(path.resolve(__dirname, '..', 'secrets.json'));
const client = new Client();
const handleMessage = (message: Message) => {
if (message.channel.type.toLowerCase() !== 'dm') {
return;
}
if (message.author.bot) {
return;
}
const recursiveCatch = (cb) => {
try {
cb();
} catch (err) {
recursiveCatch(() => {
const msg = String(err) || 'error message cannot be empty';
message.channel.send(msg);
console.log('Err:', msg);
});
}
};
recursiveCatch(() => {
const out = [];
const vm = new VM({
eval: false,
wasm: false,
timeout: 100,
sandbox: {
console: {
log: (...args: any[]) => out.push(args.map(String).join('')),
info: (...args: any[]) => out.push(args.map(String).join('')),
warn: (...args: any[]) => out.push(args.map(String).join('')),
error: (...args: any[]) => out.push(args.map(String).join('')),
debug: (...args: any[]) => out.push(args.map(String).join('')),
},
fs: {
readSync: mfs.readSync.bind(mfs),
readFileSync: mfs.readFileSync.bind(mfs),
readdirSync: mfs.readdirSync.bind(mfs),
statSync: mfs.statSync.bind(mfs),
fstatSync: mfs.fstatSync.bind(mfs),
lstatSync: mfs.lstatSync.bind(mfs),
},
},
});
console.log('In:', message.content);
const returnValue = vm.run(message.content);
out.push(returnValue);
const outStr = out.join('\n');
if (outStr.length > 0) {
message.channel.send(outStr);
console.log('Out:', outStr);
}
});
};
client.on('ready', () => {
client.on('message', (message: Message) => handleMessage(message));
client.on('messageUpdate', (oldMessage, newMessage: Message) => handleMessage(newMessage));
});
client.login(secrets.discord_token)
.then(() => {
console.info(`Login successful`);
})
.catch((err) => {
console.error(`Login failed`);
throw err;
});