RASP技术在关键信息基础设施防护中的局限性分析

2021-03-11 06:04王奕钧
信息安全研究 2021年3期
关键词:源代码调用示例

王奕钧

(公安部第一研究所信息安全部 北京 100048)

(wangyj@gov110.cn)

随着近年来网络安全工作的持续推进,公安部相关领导已经多次在全国性的安全大会上强调网络安全等级保护和关键信息基础设施保护已经进入了转型期,提出了“三化六防”新思想,即以“实战化、体系化、常态化”为新理念,以“动态防御、主动防御、纵深防御、精准防护、整体防护、联防联控”为新举措,构建网络安全综合防控体系,深入推进等保和关保的积极实践.传统的网络安全防护体系多依赖于网络层的防火墙、IDS/IPS、WAF、流量清洗等设备,出于降低对业务影响和便于业务部署的考虑,在服务器上几乎不安装防护软件,或仅安装威胁监测类的软件.而在2012年,Gartner引入了RASP[1](runtime application self-protection)一词,RASP属于一种新型应用安全保护技术,它将防护功能“注入”到应用程序中,与应用程序融为一体,使应用程序具备自我防护能力,当应用程序遭受到实际攻击伤害时能实时检测和阻断安全攻击,而不影响业务正常运行.

1 RASP技术介绍

RSAP技术是将防护模块自身注入到应用程序中,与应用程序融为一体,实时监测,阻断攻击,使程序自身拥有自保护的能力[2].并且应用程序无需在编码时进行任何修改,只需进行简单的配置即可.RASP技术原理示意图如图1所示:

图1 RASP技术原理示意图

相较于在网络层部署设备的检测方式,由于RASP技术将防护模块注入到进程中,所以RASP技术有如下特点:

1) 运行在应用程序内部,应用代码无感知;

2) 检测点位于应用程序的输入输出位置;

3) 输入点包括用户请求、文件输入等;

4) 输出点包括数据库、网络、文件系统等.

由此可见,相对于部署在网络层的防护手段,RASP技术更贴近网络攻击最后的落脚点,也就是有价值的数据、文件等.只要RASP技术使用的检测点选取合理,就可以获取到已经解码过的真实攻击负载,可以减少由于防护规则不完善导致的漏报.以网络层防护设备中比较有代表性的WAF为例[3],RASP技术与WAF设备的优缺点对比如表1所示:

表1 RASP技术与WAF设备特点对比表

由于RASP技术将防护模块注入到进程中,与应用融为一体,可以获取到应用运行时的上下文,根据运行时上下文或者监控到的敏感操作,对攻击进行精准的识别或拦截,因此RASP可在如下安全场景中发挥更大的作用:

1) 基于规则的漏洞攻击检测.

通过RASP实时采集Web应用的高风险行为、hook漏洞相关的函数,如检测SQL注入可hook mysqli_query、检测命令注入可hook system/exec、检测文件上传漏洞可hook move_uploaded_file、检测xss漏洞可hook echo/print,hook成功后当相关函数被调用时,RASP探针可对函数的参数进行规则匹配,判断是否存在漏洞攻击.以SQL注入、文件上传漏洞举例:

① SQL注入.比如在请求中检测到进程使用了union select即可以判断此请求存在恶意行为;

② 文件上传漏洞[4].以move_uploaded_file为例,move_uploaded_file(string filename, string destination),第1个参数为上传文件,如果检测到上传了1个动态PHP脚本后缀文件即判断存在上传漏洞.

2) Webshell检测.

Webshell文件是特殊的cgi文件,有文件操作、命令执行等管理功能.RASP探针可以采集进程中的数据或行为进行规则匹配或者行为统计分析,从而发现请求中是否包含Webshell的代码特征或进程行为.并且RASP探针监测的位置可以设置在代码混淆、解密之后,因此,RASP对于Webshell的监测具有不容易被绕过、特征库小的优点.

3) 基于污点追踪的漏洞检测.

污点追踪原理[5]借用了PHP变量结构体预留的一个标记位,通过追踪外部可控制的输入变量(如GET,_POST,REQUEST,REQUEST,_COOKIE等)是否未经安全处理进入危险函数执行,危险函数包括各种可能导致漏洞的函数,如命令注入时经常利用的函数system/exec,xss攻击经常利用的echo/print等.

2 RASP技术局限性分析

虽然RASP技术对于漏洞检测、Webshell检测具有检测机制上的优势,但使用RASP技术进行检测也不是万无一失的解决方案.下面将以PHP探针为例对RASP技术局限性进行分析,RASP PHP探针通常会以PHP解释器扩展的形式被加载,运行在PHP解释器层面,RASP PHP探针运行的层级如图2所示:

图2 RASP运行层级示意图

由图2可见RASP同级或者在其层级之下的操作,其监控基本上是失效的,这包括与PHP RASP同一级的其他扩展、PHP解释器之外的进程以及通过GLIBC的操作.主要绕过RASP监测的手段如下:

1) 函数监控不全.

PHP支持的函数多种多样,RASP探针不可能监控所有函数的调用,通常RASP 会监控常用的命令执行函数:system(),exec(),shell_exec(),passthru(),popen(),proc_open(),pcntl_exec(),‘单引号执行’等,这就给攻击者绕过监控提供了可能,例如利用Windows中COM组件完成对RASP监控的绕过,示例代码如图3所示:

图3 COM组件利用源代码示例

2) 函数参数混淆.

RASP检测基于函数和参数作安全策略,可以对参数作变形绕过检测,例如用来执行命令的函数system. RASP为了降低误报率,需要结合函数与参数联合判断,函数system底层原理是执行sh -c“函数参数”,因此通过命令混淆的方式,可以将RASP动态检测转化为对函数参数的静态检测,从而绕过RASP监测,尤其是存在命令注入漏洞的场景中,使用函数混淆的方式绕过RASP监控的成功率更高.示例代码如图4所示:

图4 参数混淆利用源代码示例

3) loader型函数.

loader型函数可以在执行函数本身的过程中把其中的参数按函数执行的方式加载.因此在改变函数调用的条件下,通过构造恶意参数,把函数参数巧妙地转义成payload即可实现攻击,并绕过RASP的监测.

例如函数imap_open(string mailbox, string username, string password, int [flags])的第1个参数mailbox用来传递邮件服务器的位置信息,但在建立ssh连接时可利用 代替空格,对参数-o ProxyCommand进行命令拼接,从而调用系统shell执行命令.示例代码如图5所示:

图5 imap_open函数利用源代码示例

除了函数imap_open,还有函数mail(to,subject,message,headers,parameters)的第5个参数parameters,可以用来设置命令行并传递给发送邮件时使用的程序.函数mail()的底层原理是调用sendmail程序, sendmail的参数-be支持运行扩展模式,可以对指定字符串扩展格式进行解析.示例代码如图6所示:

图6 函数mail利用源代码示例

4) LD_PRELOAD.

LD_PRELOAD是Linux中比较特殊的环境变量,它允许用户指定在程序运行前优先加载指定的动态链接库.在PHP中,可使用函数putenv()设置LD_PRELOAD环境变量来加载指定的so文件,因此劫持so文件中包含的自定义函数就可以达到执行恶意命令的目的.

函数mail(),error_log(),ImageMagick()经常被攻击者利用,用于触发已劫持的so文件,原因是这类函数在运行时能够启动子进程,便于预先加载已被重新设置的环境变量,从而劫持子进程所调用的库函数.

以函数mail()为例:函数mail()在运行时,会启动子进程来调用系统的函数sendmail(),函数sendmail()又继续引用函数getgid().那么就可以通过重写函数getgid(),并编译为so文件,其中假如代码执行了whoami命令,示例代码如图7所示:

图7 LD_PRELOAD payload源代码示例

在利用过程中,通过设置LD_PRELOAD环境变量引入自定义的so库.由于真正的恶意代码运行在PHP之外的进程,自然避过了RASP监控.示例代码如图8所示:

图8 LD_PRELOAD利用源代码示例

5) htaccess和mod_cgi.

在apache的Web环境中,我们经常会使用.htaccess这个文件来确定某个目录下的URL重写规则,如果.htaccess文件被攻击者修改,攻击者就可以利用apache的mod_cgi模块,直接绕过PHP来执行系统命令.利用这种攻击方法需要满足4个条件:

① apache环境;

② mod_cgi为启用状态;

③ 允许.htaccess文件,即在httpd.conf中,AllowOverride选项为All,而不是none;

④ 有权限写.htaccess文件.

例如,.htaccess文件的内容如图9所示:

图9 htaccess利用源代码示例

如果想读取Linux的密码文件,构造如下cgi-script.tt文件内容即可,如图10所示:

图10 htaccess payload源代码示例

6) PHP-FPM.

PHP-FPM是一个FastCGI协议解析器,默认监听在9000端口.PHP-fpm由于未授权访问的设计缺陷,它没有相应的访问验证,因此可以自行构造FastCGI协议,与PHP-fpm进行通信,使其动态加载上传的恶意PHP扩展.

FastCGI协议由多个record组成,和HTTP协议类似,也有header和body,但是和HTTP头不同,record头的长度固定为8 B,body是由头中的contentLength指定,其结构如图11所示:

图11 FastCGI结构体源代码示例

在传入的FastCGI协议数据包中,设置type=4,就可以给PHP-fpm传递环境参数,通过FastCGI协议指挥PHP-fpm加载自定义的扩展,这里涉及到PHP_VALUE和PHP_ADMIN_VALUE这2个环境变量,这2个环境变量用来设置PHP配置项,PHP_VALUE可以设置模式为PHP_INI_USER和PHP_INI_ALL的选项,PHP_ADMIN_VALUE可以设置所有选项.我们只要发送如下类似的请求就可以实现扩展的自动加载.示例代码如图12所示:

图12 FastCGI利用源代码示例

7) C接口.

FFI(foreign function interface)是PHP 7.4新加入的功能,即外部函数接口,允许从共享库中调用C代码,导致PHP直接加载外部的函数.例如利用FFI查看Linux的密码文件,示例代码如图13所示:

图13 C接口利用源代码示例

8) 已知漏洞.

PHP某些版本存在释放重引用漏洞,比如GC UAF,Json Serializer UAF,Backtrace UAF等,PHP函数的底层调用都要通过CG(function_table)获取所调用函数的handler.无论RASP是hook opcode还是hook function,本质上都没有从内存中删除所调用的函数,只是改变了函数执行的走向,指向了我们自定义的函数.因此,攻击者可以通过上述漏洞找到内存中对应的函数地址,将其封装为闭包实现调用,从而完成对RASP的绕过.以函数system为例,绕过原理简单总结如图14所示.

图14 漏洞绕过原理示意图

对于正常的PHP文件system(“whoami”)而言,由于PHP RASP将函数function_table指向从原来的内置函数zif_system改为自定义的监控函数fake_system,导致命令执行在RASP的控制之下.而通过上述漏洞的方式,可以在内存中直接找到函数zif_system地址,找到地址后,通过伪造闭包对象,将对象中的函数handler指向该地址,实现对函数zif_system的调用,从而绕过RASP监控.

9) GOT表劫持.

在Linux系统中,procfs文件系统是个特殊的存在,对应的是/proc目录,PHP可以通过/proc目录读写自己所在进程的内存,将非敏感函数地址替换成glibc中的system地址,从而执行命令,这个过程就是GOT表劫持.

例如,如果能将函数open地址换成system地址,那么便可以将fopen打开文件的命令,最终变成glibc调用system执行命令.GOT表劫持需满足3个条件:

① Linux内核版本≥2.98);

② 基于www权限的PHP-fpm/PHP-cgi work进程必须有权限读写/proc/self/目录;

③ open_basedir=off(或者能绕过open_basedir读写 /lib/ 和/proc/).

下面以system替换函数open为例,简单描述劫持GOT表的步骤:

1) 读取/proc/self/maps,找到PHP与glibc在内存中的基地址;

2) 解析/proc/self/exe,找到PHP文件中open@plt的偏移,解析libc.so,找到函数system的偏移地址;

3) 解析/proc/self/mem定位open@plt对应open@got的地址,以及libc.so中函数system的内存地址;

4) 将函数system的内存地址写入到open@got里;

5) 主动调用fopen(“/bin/whoami”),即相当于调用system(“/bin/whoami”).

3 RASP技术局限的解决方案

由上述分析可知,RASP技术的局限性的根源来自于无法hook所有的函数调用,黑客可以通过伪装、混淆、再调用的方式绕过RASP的检测,那么回到关键信息基础设施防护的本质,就是数据和文件不能被窃取和篡改,所以可以引入对进程行为可信认证的方式进行零信任防护[6],通过RASP探针结合污点追踪机制,首先需要增加一个操作系统底层驱动用来监控进程的行为,其次对标识出需要保护的文件或命令,然后在RASP探针监测到申请访问以上文件或执行以上命令时通知操作系统底层驱动放行对文件或命令的拦截.如果操作系统的底层驱动在没有RASP探针通知的情况下发现有进程要访问受保护的文件或命令,那么就拦截这些操作并报警.通过在操作系统不同部位对应用的行为进行联合判断,通过标记信任的数据源监测整个数据链路,从而杜绝绕过RASP监测的可能性.具体流程如图15所示.

图15 引入零信任机制的RASP监测流程图

4 结 语

对于关键信息基础设施“三化六防”的防护要求中强调实战化、体系化、常态化的防护思路,以及动态防御、主动防御、纵深防御、精准防护、整体防控、联防联控的防护措施[7],近年来新兴起的RASP技术作为落实主动防御、纵深防御、精准防护的网络安全防护手段,一直被业内广泛关注.随着更多的厂商在自己的产品线中加入了该技术的应用实践,越来越多的攻击者开始研究绕过RASP技术监测的办法.而在通过引入零信任的进程行为判断后,利用RASP技术与文件监控技术联合捕捉恶意进程行为,并对其进行拦截阻断,可以很好地实现对关键信息基础设施进行有效防护.本文给出了引入零信任机制的RASP监测防护方法,但在效率和性能上还有很大的研究空间,这是下一步关键信息基础设施防护研究工作的重点.

猜你喜欢
源代码调用示例
基于TXL的源代码插桩技术研究
2019年高考上海卷作文示例
核电项目物项调用管理的应用研究
常见单位符号大小写混淆示例
常见单位符号大小写混淆示例
“全等三角形”错解示例
软件源代码非公知性司法鉴定方法探析
基于语法和语义结合的源代码精确搜索方法
基于系统调用的恶意软件检测技术研究
揭秘龙湖产品“源代码”