feature
昨天在逛先知,从入侵到变现——“黑洞”下的黑帽SEO分析中看见样本shell
http://43.255.29.112/php/dd.txt
觉得这个shell写的非常赞!!
所以看看代码分析一波,大佬请直接忽略
如有写错的地方,还请多多包涵!
webshell主要包含如下功能:文件管理、搜索文件、扫描后门、反弹端口、执行命令、执行PHP、执行SQL、系统信息。
function chkgpc(check_magic_quotes_gpc 检查是否开启了魔术引号)
代码
if (get_magic_quotes_gpc())
{
$_POST = chkgpc($_POST);
}
function chkgpc($array)
{
foreach ($array as $key => $var) {
$array[$key] = is_array($var) ? chkgpc($var) : stripslashes($var);
}
return $array;
}
实现思路
首先判断服务器是否开启了魔术引号,如果开启了对POST参数进行递归处理,删除转义.
知识点
魔术引号(magic_quotes_gpc)
效果
转义如下字符
'
"
\
NULL
'NULL'
作用
防止sql注入
思考魔术引号开启是否真的就万无一失?
宽字节注入, stripslashes使用不当等
variable myfile(shell_absolute_path shell绝对路径)
代码
$myfile = $_SERVER['SCRIPT_FILENAME'] ?
strdir($_SERVER['SCRIPT_FILENAME']) : strdir(__FILE__);
$myfile = strpos($myfile, 'eval()') ?
array_shift(explode('(', $myfile)) : $myfile;
实现思路
通过$_SERVER['SCRIPT_FILENAME']或__FILE__获取脚本的绝对路径
第二段代码不知道是什么意思
知识点
$_SERVER 超级全局变量
_FILE_ 魔术常量
$_SERVER['SCRIPT_FILENAME']获取不到以CLI模式的运行的脚本路径,也就是说你在命令行中运行php shell.php,是获取不到绝对路径的.
strpos() 如果字符出现在第一位,返回0.如果字符串没有找到,返回false.
判断一个字符串是否包含某个字符,错误的写法是这样的
if(!strpos($string, 't'))
正确应该这么写
if(false !== strpos($string, 't'))
array_shift()弹出数组第一个元素,会修改原数组,引申array_pop()弹出数组最后一个元素
functon strdir(string dir 格式化路径)
代码
function strdir($str)
{
return str_replace(array('\\', '//', '%27', '%22'), array('/', '/', '\'', '"'), chop($str));
}
知识点
chop()函数移除字符串右端的空白字符或其他预定义字符,这里第二个参数为空,默认移除如下参数
"\0" - NULL
"\t" - 制表符
"\n" - 换行
"\x0B" - 垂直制表符
"\r" - 回车
" " - 空格
str_replace() 老生常谈,使用str_replace绕过关键字检查.
variable THISDIR(shell当前路径)
代码
define('THISDIR', strdir(dirname($myfile) . '/'));
variable ROOTDIR(网站的根目录)
代码
define('ROOTDIR', strdir(strtr($myfile, array(strdir($_SERVER['PHP_SELF']) => '')) . '/'));
知识点
strtr()替换,通过$_SERVER['PHP_SELF']取出脚本的相对路径,将路径变更为空.
variable EXISTS_PHPINFO(判断是否存在php_info)
代码
define('EXISTS_PHPINFO', getinfo() ? true : false);
function getinfo(是否存在phpinfo方法,同时校验密码)
global password;
$infos = array($_POST['getpwd'], $password, function_exists('phpinfo'));
if ($password != '' && md5($infos[0]) != $infos[1]) {
echo '请勿使用非法用途'
exit();
}
@setcookie("new", 951);
if (@$_COOKIE["new"] != 95) {
@setcookie("new", 95);
}
return $infos[2];
实现思路
比较密码是否相同,如果密码不正确,退出.
同时判断服务器是否存在phpinfo方法并返回.
知识点
md5() ctf常见考点,这里不扩展了.
setcookie() 设置cookie值,这里有两个小知识点扩展.
httponly,禁止js读取到cookie中的某个key.比如通常会把PHPSESSID设置成httponly,这样即使存在xss,也无法获取到phpsessid.
secure, 当secure属性设置为true时.协议不同的域名无法共享cookie,例如在https的某个站点设置了cookie,当用户访问http的该站点时,设置了secure属性将无法发送给服务器.