新手教程之和webshell学php(一)

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属性将无法发送给服务器.

学习一下。

哈哈,webshell应用了php很多语法上的奇淫巧技,相对于应用开发方式学php来说更有趣。

學習學習了。