0x00 木马隐藏手段
- 程序中;
- 配置文件中;
- Win.ini中;
- 普通文件中; 注册表中;
- 驱动中(rootkit);
- 启动组(启动项);
- winstart.bat中(早于启动组);
- 启动文件中;
- 超链接中
0x01 木马发展
第一代:DLL(win中动态链接库的意思)木马。采用进程隐藏。采用内核推入式的嵌入方式,利用远程插入进程技术,嵌入到DLL进程,或者挂接PSAPI,实现木马程序的隐藏,甚至在win NT/2000下,都能达到良好的隐藏效果。灰鸽子和蜜蜂大盗是比较出名的DLL木马。
第二代: 驱动级木马。多数都使用大量的rootkit技术来达到在深度隐藏的效果,并深入到内核空间中。查杀难度更大。
0x02 分类
- 网游木马
- 网银木马
- 下载者
- 代理类(对花生壳和服务器,把中招者当跳板)
- FTP木马
- 通讯软件(QQ大盗)
- 网页点击类
- 其他
0x03 端口及加载方式
端口自定义。如灰鸽子使用的是8000端口。
加载方式一
定位于System.ini和Win.ini文件中。系统一启动,就上线了。
加载方式二
隐藏在注册表中(此方法最为隐藏)
注意某注册表项原始数值前被添加了“C:systemxxx.exe”,这样在执行原执行文件前都会先去执行xxx.exe这个程序。 例如:开机后运行QQ主程序,该xxx.exe(木马程序)就会先于登录程序被加载。
其他加载方式
0x04 远控原理
说明:远程控制软件工作原理:远程控制软件一般分客户端程序(Client)和服务器端程序(Server)两部分,通常将客户端程序安装到主控端的电脑上,将服务其器端程序安装到被控端的电脑上。使用时客户端程序向被控端电脑中的服务器端程序发出信号,建立一个特殊的远程服务,然后通过这个远程服务,使用各种远程控制功能发送远程控制命令,控制被控端电脑中的各种应用程序运行。
0x05 动态IP
个人用户通常使用动态IP,即每一次启动机器,从ISP分配到的IP就不一样。这样导致每次重启机器,我们的肉鸡就都掉了。这样我们就不能像在有固定IP的企业、政府部门、单位、组织等的服务器上直接使用现有(固有)的IP地址来配置远控的服务端程序。
0x06 动态域名
动态域名可以使您拥有一个固定的域名(虽然叫动态域名),对应一个可变的IP地址。这样Internet用户就可以使用这个固定的域名,方便地来访问您的计算机。
用户每次上网得到新的动态分配的IP地址之后,安装在用户计算机里的动态域名软件就会把这个IP地址发送到动态域名解析服务器,更新域名解析数据库。Internet上的其他人要访问这个域名的时候,动态域名解析服务器会返回正确的IP地址给他。 这叫动态域名。
有了一个动态域名,您会惊奇地发现,您现在也可以拥有一台Internet服务器!可以将网站搬回家!您可以拥有自己的WWW服务器、FTP服务器、Email 服务器!而且您还完全掌握自己的服务器,而不必担心由于服务器托管造成关键数据的不安全。
0x07 注册花生壳动态域名
花生壳就可以自动的将域名映射到我当前的主机的IP,不管我的IP怎么变。在生成木马服务端时,填写客户端IP的时候就填写动态域名即可。这样就解决动态IP的问题。
0x08 手工查DLL注入型木马
服务进程在服务管理器中的显示名称和服务名称是不同的概念。显示名称可以又木马制作者指定和正常服务混在一起。
然后在这个服务的“属性”中会显示可执行文件的路径。但是木马如果把自己注入到某一个进程当中,也就是说你看可能从服务的属性中得到的可执行文件是一个必备的系统文件或者原先的正常文件。这时候怎么办呢?
这时候就要看这个服务调用了哪些模块,也就是动态链接库DLL.方法是去注册表中的HKEYLOCALMACHINE--- SYSTEM---CurrentControlSet---Services里面的该服务名下的parameters中的键值,里面会告诉你调用的DLL的地址。那么我们如何来验证这个DLL是正常的还是恶意的呢?
微软提供的方法是校验码。我们通过工具来校验这个模块。不符合检验码的即视为可以。
0x09 无进程木马
第一种——无进程木马是 DLL 注入型木马
也就是通过修改注册表中某个本来正常的进程的参数parameters将一个DLL加载到这个进程当中。这样这个DLL是没有一个专门的木马进程的。但这种通过注册表来加载DLL的方法不是唯一的。还可以通过另外一个进程将DLL注入到一个新打开的正常进程当中,然后负责注入的进程退出。
第二种——无进程木马是线程注入型的木马
线程注入,就是木马程序将一个恶意线程放到了正常进程的线程序列中去执行。模块与线程一样,在其它进程内能够找到。这样的恶意线程可能会被专门的工具记录下来其基址。进程中后启动的线程的基址大于先启动的线程。我们不知道他注入到了哪一个进程中。其次,即使一个进程中有多个以进程名为名字的线程我们也无法确定那多出来的线程就是木马线程。所以,我们仍然要从自启动项入手来禁止线程注入。
第三种——无进程木马是纯驱动型木马
因为驱动程序由于其特殊性,使得它在系统中有着超越一切的权力,而且有着优先加载执行的优势,它是做为操作系统的一部分来运行的。系统的权限分为两种 R0 与 R3,一般的程序全部为 R3 权限,其行为受到了很多限制;而操作系统与驱动则为R0 权限,拥有对整个计算机的全部权力,可以为所欲为 。
在桌面我的电脑图标上按右键,依次选择“属性-- 硬件--- 设备管理器”就可以打开上面的窗口了,再勾选上 查看 “ 显示隐藏的设备 ” 就可以看到 非即插即用驱动程序 。
除了非即插即用外,其它的同级项目都是您机器上的硬件及它们的信息、资源、驱动等,他们是根正苗红的正经设备。由于这些都与硬件有关,所以,木马动它们的可能性很小,必竟木马也不想你的机器崩溃 啊。因此,大多数木马驱动都隐藏在“ ” 非即插即用驱动程序 下面,而这里面的则是那些虚拟设备了(注:非即插即用驱动程序并非就是虚拟设备驱动程序,这涉及到以前老版系统中的一些个问题,这里不再细说, 您只需要明白,在当前的情况下,这里面大多都是虚拟设备驱动程序就可以了。)
那么驱动级木马是真正的所谓的无进程木马吗?NO!驱动在哪个进程里呢?那就是 System进程,它们是做为系统的一部分来运行的。
第四种——无进程木马就是利用HOOK隐藏进程的木马:
上面说的三种,的确是没有自己的进程,只是利用了其它的进程。而利用技术手段隐藏进程的木马,则是有自己的进程,但是如果你破解不了他的隐藏技术,那你就看不到它的进程。
应用层 HOOK【检查结果】 在我们提出要求时呢,他会检查是否对他有害,或将对他有害的信息去掉,比如我们想查看进程,那他在将结果交给我们时,却把木马的进程自结果中抹去了,这样,我们自然是看不到木马进程了。
而最常见的内核HOOK【检查请求】,则是HOOK-SSDT,上面说了SSDT(系统服务描述表)就是一张表,标明了什么工作应该由什么函数负责。而 SSDT-HOOK就是木马将表上的内容给改了,本来交给某函数的请求被改成了交给由木马负责,这样,我们请求时,一查表发现查看进程的工作是由木马负责的,他就把这请求交给木马了,而木马呢?他可是知道表中原来的内容是什么的呀,他只是对请求进行一下过滤,发现没有对自己有害的,就直接转交给原部门了,对自己有害的,自然也就视情况滤掉或涂改了。比如我们在任务管理器要结束某个进程时,可能会无法完成操作。这其实不是系统拒绝你的操作,而是你要结束的进程自己所为。则就是因为这个进程HOOK了SSDT,结束进程的请求被交到了你要结束的进程,这个进程愿意你结束它,那么进程就会结束,它要是不愿意你结束,就无法操作。
如果想隐藏进程就可以把NtQuerySystemInformation给 HOOK 了。(结束进程是由 NtTerminateProcess 来完成的,如果HOOK了这个,那么在进程结束前,就有机会更改结果了,可以拒绝被结束)inline-HOOK。这是一种更难以查找的隐藏或更难终止进程的技术。它不去修改SSDT,而是直接换掉负责进程枚举的函数。修改SSDT后,通过对比正常的SSDT可以发现异常。INLINE-HOOK是针对函数的HOOK。如果在内核代码检测中把被inline-HOOK的函数恢复回去,则进程就能正常停止了。
小结一下:程序就像是为了实现某一目的而定的计划书;进程呢?就是组织工人分配资源开始执行这份计划;而 Windows 操作系统呢?就是一个为我们管理电脑也是管理这些执行计的工人的服务管理公司;我们有什么要求呢?就交给服务员将我们的要求提要给 Windows,由 Windows 来组织工人执行我们的要求,并将结果返回给我们。如果木马替换了服务员、更改了SSDT 表、或替换了 Windows 服务公司某职能部门的人员,我们得到的可能就是一个错的结果,或我们的要求得不到执行,就像结束进程一样。
还有没有更牛逼的隐藏方式?
系统活动进程链是记录系统中的进程的数据结构,但是不是唯一记载进程信息的地方。如果木马只是抹去了活动进程链中的数据,那么还可以从窗口、线程、句柄、对像、Csrss.exe中等许多地方找到它的信息。window枚举进程信息的地方就在系统活动进程链中,而专业的检测软件可以在其他地方枚举。
木马如果将所有能查询到自己进程的地方都抹掉信息,那么必须通过基于线程调度链的进程枚举技术来检测。木马不能抹去线程调度链中自己相关信息。否则自己进程也生存不下去了。
0x0A 注册表基础
自启动,顾名思义,就是无须用户干预而自行启动的程序,按启动方式又分为两种,一种是开机自运行的程序;一种是触发式启动的程序。
注册表从功能上说,它是一个存储各种设置信息的数据仓库,系统的全部设置几乎都存在那里。开机时需要加载的驱动、开启的服务、运行的程序等等也都存储在这里。
而从实质上来说呢,注册表其实是由一些记录配置信息的文件组成的,这些文件中的大部分存在“WindowsSystem32Config”目录下,还有一部分存在用户配置文件夹中。这些文件有一个很难听的名字叫做储巢,也就是朋友可能听过的 HIVE 文件。正常情况下,你无法对注册表 HIVE 文件进行任何的直接操作。
HIVE 文件的重要性使得系统对其保护很严密,这对直接操作 HIVE 文件造成了一定的麻烦,而风险性也进一步的提高。 这使得当前绝大多数安全软件,对操作 HIVE 文件来查杀木马都望而却步,但其效果却无疑是目前最好的。
最上层的是 根键 下面的叫做 子键 ,其与上面我们说的注册表文件一一对应,
对应关系如下:
-
HKEYLOCALMACHINESAM——WindowsSystem32configsam
-
HKEYLOCALMACHINESECURITY——WindowsSystem32configsecurity
-
HKEYLOCALMACHINESOFTWARE——WindowsSystem32configsoftware
-
HKEYLOCALMACHINESYSTEM——WindowsSystem32configsystem
-
HKEY_USERS.DEFAULT——WindowsSystem32configDefault
-
HKEYUSERSS-1-5-XXXXX——DocumentsandSettings<用户名>Ntuser.dat
-
HKEYUSERSS-1-5-XXXXX_Classes——DocumentsandSettings<用户名>LocalSettingsApplicationDataMicrosoftWindowsUsrclass.dat
还有其它的键呢?又对应哪些文件呢?呵,这要从注册表的数据类型说起了,除了上面的键外,其它的几个键是属于 REG_LINK 类型,直翻过来就是注册表链接了,这种类型的键是透明的指向另一个键的一个链接,也可以理解成这些键只是另外的某个子键的快速入口或某类相似键的汇总而已,本身并没有文件。
-
HKEYCURRENTUSER 中存储了一些与当前登录用户有关联的数据,也就是你个人的一些设定都存在了这里。
-
HKEYCLASSESROOT 中存储的是文件关联和 COM 对像的注册信息,什么样的文件由什么程序来打开就是存在了这里。
-
HKEYLOCALMACHINE 中存储的是系统相关的信息,比如:驱动、服务等。
-
HKEY_USERS 存储的是所有账户的信息。
-
HKEYCURRENTCONFIG 中存储的是当前硬件配置信息
0x0B 检查开机自启动的程序
系统启动时,由引导程序 Ntldr 来读入 system 注册表文件,加载里面列出的驱动程序。可是文件系统加载前,对文件的读取是无法实现的,那么 Ntldr 又如何读取 system注册表文件的呢?
因为 Ntldr 中内置了只读的 NTFS 与 FAT 文件系统代码,虽然很简单但足够用了。再追问下去,Ntldr 也是以文件形式存在的,那 Ntldr 这个文件又是如何读取的呢?
Ntldr是引导扇区中的引导代码加载的,而引导扇区中有更加简单的文件系统读取代码,区别是越向上越简单,一直到文件系统驱动接手后,才是完整的文件系统代码。
加载驱动和服务时,就是依照HKEYLOCALMACHINESYSTEMCurrentControlSetServicessr 键下的内容进行加载的,也就是在 System注册表文件中。下面的自建记录了每个驱动或服务的必要信息。
如Start:驱动或服务的加载启动顺序。可取值为,0->Ntldr 预先加载此值为零的驱动,在引导过程中这类驱动一直待在内存中;1->在标明为 0 的驱动初始化之后,值为 1的驱动开始被加载到内存中并初始化,其是在内核初始化的过程中加载的(参见进程篇的系统启动过程)。2-> Services.exe 启动后,由该进程来加载启动值为 2 的驱动或服务(Service.exe 的情况请参阅进程篇);3->Services.exe 根据需要加载这类的驱动或服务,也就是在服务管理器的启动一项中标明为 手动 的。 标明为手动并不是指一定要由用户来手动启动,而是由系统识情况启动,当系统需要相应的驱动或服务提供的功能时,系统就将自动启动此服务,而无须用户手动操作;4->驱动或服务并不加载到内存,当然也不启动了。也就是服务管理器中标为“ 禁用 "的服务,这一类的服务,即使系统需要用到其提供的功能,不会自动加载。这里不能忽视的一点是,有一些恶意代码将启动后将自己设置为禁用,这只是一种伪装。其在系统关闭时会重新将这个键值设置为0,以求得在下一次机器启动时率先被加载。故在查杀木马启动项时不能完全忽略掉键值为4的驱动或服务。
在大量对驱动和服务的检查中,我们还是用到微软签名来认证。在正常情况下,清除掉所有的非微软签名启动项,是不会影响系统正常使用的。但有些情况是需要注意的,比如:Tcpip.sys 是网络驱动,正常情况下是可以通过微软数字签名验证的。但有些下载软件比如迅雷会修改此驱动以达到最大的连接数,而由于 Tcpip.sys 被改动后,将不再能够通过微软的数字签名验证,所以,在不特别注意下,清除所有非微软认证的自启动项时,就会将这个驱动清掉,导致无法上网。
另外,向进程篇中提到的 Userinit.exe 的情况也是类似的,Userinit.exe 同样为系统必须的程序,但如果这种程序被感染(灰鸽子就可以做到)了,那么,直接清掉就会存在问题,当然了,安全程序在清这类启动必须的程序时是不会删掉启动项的,但作为我们用户来说一定要搞清除哪些是木马的启动项,那些是被修改或感染的系统启动项,对这种被修改或感染的系统文件的处理,最佳方式无疑就是利用“ 系统文件修复” 功能了。而千万不要直接手动清除相应的启动项,清掉后,将导致系统功能出现问题甚至不能进入系统。
所以,对启动项进行清理时,在隐藏微软验证的文件后,仍然要对剩余的进行判断,有针对性的清理。
0x0C 触发式启动的程序
一、最常见的就是文件关联式的触发启动
以.gif文件为例,在早期的win版本中,HKEYCLASSESROOT 键(设置文件关联程序的根键)下找到“giffile”子键下的 shellopencommand 键的默认值,标明了当你双击 gif 文件时,系统所要做的动作。这个键值是可以修改的,改成你想要的在双击某个.gif文件后启动那个程序。如果把这个键值指向一个木马程序,那么在双击.gif后将启动这个木马,当然木马也会在自己启动后,再度调用原有的程序将图片打开,这样,对你来说,是没有任何感觉的,你只知道双击一个图片后,图片打开了,而不会知道发生在这中间的一切。 当然,安全软件也会对文件关联及 COM 注册项等进行扫描。
二、自动播放式的触发启动
播放的本意,播放什么是由光盘中的 AutoRun.inf 文件指定的。此文件的内容,通常如下:
———————————
[autorun] open=AutoRun.exe
icon=AutoRun.ico
———————————
Open 那一行,指出了自动播放时系统自动运行的程序,icon 指出了所显示的图标。后来有人用于了硬盘与 U 盘,在 U盘或硬盘的分区,创建 Autorun.inf 文件,并在 Open 中指定木马程序,这样,当你打开硬盘分区或 U 盘时,就会触发木马程序的运行。 这类启动,大部分安全工具都进行了监管,在狙剑的自启动项中会列出每个磁盘或分区的自动播放式的自启动程序。
三、感染式的触发启动
病毒将自己的病毒体附加到了正常的程序上面,并修改了程序的入口地址为病毒体的执行地址,在病毒体中有指令去启动木马,最后再由病毒体执行完毕后跳回原程序的入口地址来执行原程序的功能,这一切对用户来说都是不可见的。 病毒的清除并不复杂,不外乎就是一个分析,从被感染程序中找到病毒体,清掉,再恢复原程序的入口地址,就OK了。但难就难在病毒与病毒是各不相同的,而新病毒又层出不穷,这就使得这种分析与清除工作需要大量的人力与精力。
四、修改式的触发启动
有修改引导扇区的、有修改系统文件的。修改方法与病毒感染大致相同,就是在正常的指令序列中插入自己调用病毒或木马程序的指令,以实现在自己的启动。 这种方式隐蔽性很强,但却很难逃过以数字签名验证为主要手段的启动项检查,因为一旦系统文件被修改,即不再能通过数字签名验证,前面提到的修改 Userinit.exe 的木马就是这样的一个例子。 这种方法启动的木马,还使得清理起来比较困难,因为他们修改了系统文件,需要用原有的文件进行还原性的替换修复,如果手头有系统安装盘还好一点,没有就比较麻烦了。
0x0D 自启动项的隐藏、保护与查杀
自启动项的隐藏与保护,跟进程的差不多,不外乎还是 HOOK。
系统查看或删除注册键与值时,也是用的上面的几个 API。而上面的一些个 API 是用于应用层的,它们又会调用系统内核中的 Nt系统的功能服务来进行接下来的处理(代表了 Nt 开头的那些与注册表相关的系统服务),而 Nt系统服务又调用了 Cm底层功能代码来进行操作,当然了,最终的操作都要实现在HIVE 文件上面去。
进程篇中的 SSDT-HOOK、 SSDT-INLINE—HOOK 在注册表 HOOK 时是完全有效的,HOOK 应用层的RegCreateKey、 RegOpenKey 或 RegDeleteKey 都可以实现注册键的防删除,而 HOOKRegEnumKey就可以实现注册键的隐藏,这种 HOOK 可以对付系统与大多数应用层的安全工具的检查;而HOOKNtCreateKey 等则同样可以实现隐藏与防删除且层次更深,而 HOOKCm*系统注册表操作函数,则更加邪恶,且已经有这类程序出现。总之,在注册表操作的任何一个环节进行 HOOK,都可以实现隐藏与防删除的目的。
如果不调用系统的注册表操作函数而直接对HIVE文件进行操作,那么任何注册表相关的HOOK在这时是不起作用的。
操作 HIVE 无疑是最底层的也是功能强大的,但用起来肯定不如使用自启动项管理方便,所以,一般情况下,这个是用不到的。
但一旦遇到变态的木马时,有这个功能,会让我们感到心里有底。 比如:一旦清除木马的启动项,系统马上就蓝屏的情况我就遇到过,这是木马变态般的自我保护,而其保护的基理就是注册了注册表改变通知的消息,一旦其注册表项被改变,他就会接到系统的通知,而他一旦接到通知,就会马上使系统崩溃,让我们对其所做的修改无效。
为什么马上系统崩溃就会使修改无效呢?这是因为系统的缓存机制在起作用,正常情况下,我们的修改只体现在了缓存中,系统通常是 5 秒钟为间隔的将缓存中的数据向磁盘中更新,而修改后马上崩溃,将使得系统来不及向磁盘中写入修改后的信息,导致修改无效。
面对这种木马的处理就是直接将start的键值设置为4.还是那就话直接操作 HIVE 文件绕过了系统所有的注册表操作环节,系统也不知道我们做了更改,即然系统都不知道,木马自然也得不到通知了。
0x0E 文件基本知识
一、文件格式
文件格式是文件的本质形体,更改扩展名并不会改变文件格式这个本质。但是系统默认情况下会根据扩展名来指定相应的程序来运行这个文件。当然,这个关联的程序时可以更改的。但是,只有关联的程序支持这种文件格式,不管这个文件的扩展名是什么,它都能运行这个文件。比如生成一个.mov文件,后期用户自己将扩展名改成.PNG,那么如果你用Photoshop是运行不了这个文件的,但是却可以用暴风影音来运行这个文件。这就是为什么要有格式工厂这样的格式转换工具。
总结成一句话就是,一个文件是否可以通过鼠标双击来执行,与其扩展名并没有必然联系。有联系的是该文件的文件格式与在系统中注册的打开此格式文件所使用的程序,缺一不可。
木马习惯于将自己改成pif 或 scr 是因为系统中默认的打开这两种格式文件的程序就是 Explorer.exe,与 exe 文件是一样的(双击exe可执行文件后EPLORER.exe就会开启线程来给这个EXE提供SHELL)。
在 Windows 系统中,可以执行的文件格式叫做 PE 格式(PortableExecutableFileFormat/可移植的执行体文件格式),包括了 EXE、 DLL 等。而可执行文件意指文件中存的是指令序列或与其有关的东西,是可以放到内存中一条条执行的。与其对应的是数据文件,其中存的并不是可指行的指令,而供查看的数据,包括图片、音乐、文档等。
二、文件系统格式
文件系统格式,则是指文件在磁盘中的存放规则,此规则说明的是文件是如何放到磁盘中的,又如何能找到它们。
我们接触最多的是 FAT 格式与 NTFS 格式。
文件格式有特定的程序来识别并读取使用,而文件系统格式则由特定的驱动来识别并读取使用,这就是我们经常听到的 FSD(文件系统驱动),而 FSD-HOOK 就是 HOOK 这几个驱动了:
- CDFS 格式:Cdfs.sys
- UDFS 格式:Udfs.sys
- FAT 格式:Fastfat.sys
- NTFS 格式:Ntfs.sys
三、文件读写机制
缓存是什么呢?缓存的用途是将频繁被操作的数据的一个子集保存在物理内存中,这样我们的频繁操作就可以直接操作内存,而不是频繁的读取磁盘了。智能预读是通过一种科学的计算,它决定哪一部分应该被事先读取,并保存在内存中。
此外,系统还会采用了一种延迟写的方法,我们所有的修改都存在了缓存中,当完成一定的积累后,系统再一次性的将所有修改写入磁盘,而这种写是在后台进行的,我们并没有更多的感觉。
这里需要注意的地方是,这种延迟写与前面自启动项篇中注册表HIVE文件的延迟写并不是完全相同的。当然了,原理与机制是相同的,都是为了减少读写磁盘的次数也都是利用了缓存机制。但注册表HIVE文件的延迟写是由一个专门的注册表文件操作线程负责的,每5秒触发并写入一次。而文件的延迟写是由缓存管理器的延迟写出器在一个系统辅线程上每秒钟一次的来执行的,而且,执行并不等于写入,执行一次意指计算一次,计算什么呢?计算是否需要写入磁盘写入多少又写入哪些。