智能ABC输入法溢出分析智能ABC输入法漏洞已经被人发现很久了,广泛用于网吧计费系统的破解。不过很少有人去研究他是怎么溢出的。所以我也是闲的无事分析一下他的溢出。
需要的工具:ollydbg 哪都有下载的地方。
首先用OD打开笔记本。然后切换输入法到智能ABC,输入v,左箭头delete ,回车(空格也可以)。然后立刻造成进程死掉,然后OD的信息会告诉你问题出在7380****.而7380****属于winabc.ime的地址。经过跟踪,确定出错指令为ImeToAsciiEx函数,此函数是用来处理输入的字符。每按一个键就会调用一次,当上面这个动作做完后又调用了 0x7380AC95函数。下面是这个函数的汇编代码
7380ACA1 |> 66:81FE 3D80 CMP SI,803D ;si为你按的那个键的hex值
7380ACA6 |. 75 26 JNZ SHORT WINABC.7380ACCE
7380ACA8 |. 803D B0298173 >CMP BYTE PTR DS:[738129B0],3 ;3为输入中间阶段
7380ACAF |. 0F84 E7010000 JE WINABC.7380AE9C
7380ACB5 |. 833D AC298173 >CMP DWORD PTR DS:[738129AC],1
7380ACBC |. 0F8E DA010000 JLE WINABC.7380AE9C
7380ACC2 |. C605 B0298173 >MOV BYTE PTR DS:[738129B0],1
7380ACC9 |. E9 CE010000 JMP WINABC.7380AE9C
下面在来看一段关于0x7380AC95的代码
7380ADB4 |> 56 PUSH ESI
7380ADB5 |. E8 58140000 CALL WINABC.7380C212
7380ADBA |. 85C0 TEST EAX,EAX
7380ADBC |. 74 20 JE SHORT WINABC.7380ADDE
7380ADBE |. 66:83FE 76 CMP SI,76 ; 与'v'比较
7380ADC2 |. C605 B0298173 >MOV BYTE PTR DS:[738129B0],3
7380ADC9 |. 0F94C0 SETE AL ; 不是的话al=0
7380ADCC |. A2 6C488173 MOV BYTE PTR DS:[7381486C],AL ; 是v的话进入v输入状态
7380ADD1 |. E8 F6110000 CALL WINABC.7380BFCC
7380ADD6 |. 391D CC558173 CMP DWORD PTR DS:[738155CC],EBX
7380ADDC |. EB 23 JMP SHORT WINABC.7380AE01
v的输入状态不同,比如Vabc 会输入abc英文,V1什么的为特殊字符和符号。
下面去找出问题的地方
7380AC81 |. 33DB XOR EBX,EBX
.......
7380AE08 |> 0FB7C6 MOVZX EAX,SI ; Case 3 of switch 7380ACE2
7380AE0B |. 50 PUSH EAX
7380AE0C |. E8 340A0000 CALL WINABC.7380B845
7380AE11 |. 2BC3 SUB EAX,EBX
7380AE13 |. 74 26 JE SHORT WINABC.7380AE3B
.......
7380AE3B |> 381D 6C488173 CMP BYTE PTR DS:[7381486C],BL ;DS:[7381486C]=2
7380AE41 |. 74 22 JE SHORT WINABC.7380AE65 ;没有发生跳转,正常情况下0x73811F52肯定大于0
7380AE43 |. 0FB705 521F817>MOVZX EAX,WORD PTR DS:[73811F52] ;DS:[73811F52]为0
7380AE4A |. 48 DEC EAX ;FFFFFFFF
7380AE4B |. C605 CC758173 >MOV BYTE PTR DS:[738175CC],2
7380AE52 |. 50 PUSH EAX
7380AE53 |. 68 561F8173 PUSH WINABC.73811F56
7380AE58 |. E8 FA140000 CALL WINABC.7380C357
7380AE5D |. 881D 6C488173 MOV BYTE PTR DS:[7381486C],BL ;函数将发生错误
7380AE63 |. EB 31 JMP SHORT WINABC.7380AE96
如果del删去V,DS:[73811F52]变量为0,但是DS:[7381486C]=2没有变为0,仍然在输入中途状态,dec eax是为了取得除了v之外的字母串的长度,结果这里变为 0xffffffff,7380AE5D |. 881D 6C488173 MOV BYTE PTR DS:[7381486C],BL 中 函数没有做检查。
7380C4C8 0FB745 10 MOVZX EAX,WORD PTR SS:[EBP+10] ; eax = 0xffff
7380C4CC 8BC8 MOV ECX,EAX
7380C4CE 8BFB MOV EDI,EBX
7380C4D0 037B 58 ADD EDI,DWORD PTR DS:[EBX+58]
7380C4D3 03F3 ADD ESI,EBX
7380C4D5 8B75 0C MOV ESI,DWORD PTR SS:[EBP+C]
7380C4D8 8BD1 MOV EDX,ECX
7380C4DA C1E9 02 SHR ECX,2 ; ecx = 0x3fff
7380C4DD 8943 54 MOV DWORD PTR DS:[EBX+54],EAX
7380C4E0 03C3 ADD EAX,EBX
7380C4E2 F3:A5 REP MOVS DWORD PTR ES:[EDI],DWORD PTR DS> ; 拷贝0x3fff个int
看到了吗,出错的地方。在这里溢出了。
还有这个问题
7380B416 /$ 803D C0558173 >CMP BYTE PTR DS:[738155C0],0AA
7380B41D |. 56 PUSH ESI
7380B41E |. 74 2D JE SHORT WINABC.7380B44D
7380B420 |. 66:8B0D 545E81>MOV CX,WORD PTR DS:[73815E54] ; cx = 0
7380B427 |. 66:49 DEC CX ; cx = 0xffff
7380B429 |. 0FB7C1 MOVZX EAX,CX
7380B42C |. 66:890D 545E81>MOV WORD PTR DS:[73815E54],CX
7380B433 |. 0FB690 405E817>MOVZX EDX,BYTE PTR DS:[EAX+73815E40]
7380B43A |. 0FB680 415E817>MOVZX EAX,BYTE PTR DS:[EAX+73815E41]
ds:0x73815E54表示当前输入栏中有多少字/词 DS:[738129B0]=0时上面的代码会被用到。当用退格消去输入栏中最后一个汉字时DS:[73815E54]=0,DS:[738129B0]应该变成3,表示进入输入状态.但是我们随便输入一个词,然后输入任意字符,按"←",退格,回车,在输入框中得到前一词的默认字,然后连按两次退格。输入第一个退格键,DS:[73815E54]=1,可是DS:[738129B0]并没有变成3,再次按下退格键,函数又执行到这里,cx变为0xffff,就出错了。
因为程序可以导致IME所HOOK的进程退出。所以像万象那样的网吧管理软件会立刻出错而退出进程.而3389登陆也会出错。不过对远程主机似乎没有影响。。。曾经还有人说这个可以造成远程主机重起。所以只是谣言。仔细想想就知道为什么不会对远程主机造成影响咯。
下面在来看一段关于0x7380AC95的代码
7380ADB4 |> 56 PUSH ESI
7380ADB5 |. E8 58140000 CALL WINABC.7380C212
7380ADBA |. 85C0 TEST EAX,EAX
7380ADBC |. 74 20 JE SHORT WINABC.7380ADDE
7380ADBE |. 66:83FE 76 CMP SI,76 ; 与'v'比较
7380ADC2 |. C605 B0298173 >MOV BYTE PTR DS:[738129B0],3
7380ADC9 |. 0F94C0 SETE AL ; 不是的话al=0
7380ADCC |. A2 6C488173 MOV BYTE PTR DS:[7381486C],AL ; 是v的话进入v输入状态
7380ADD1 |. E8 F6110000 CALL WINABC.7380BFCC
7380ADD6 |. 391D CC558173 CMP DWORD PTR DS:[738155CC],EBX
7380ADDC |. EB 23 JMP SHORT WINABC.7380AE01
v的输入状态不同,比如Vabc 会输入abc英文,V1什么的为特殊字符和符号。
下面去找出问题的地方
7380AC81 |. 33DB XOR EBX,EBX
.......
7380AE08 |> 0FB7C6 MOVZX EAX,SI ; Case 3 of switch 7380ACE2
7380AE0B |. 50 PUSH EAX
7380AE0C |. E8 340A0000 CALL WINABC.7380B845
7380AE11 |. 2BC3 SUB EAX,EBX
7380AE13 |. 74 26 JE SHORT WINABC.7380AE3B
.......
7380AE3B |> 381D 6C488173 CMP BYTE PTR DS:[7381486C],BL ;DS:[7381486C]=2
7380AE41 |. 74 22 JE SHORT WINABC.7380AE65 ;没有发生跳转,正常情况下0x73811F52肯定大于0
7380AE43 |. 0FB705 521F817>MOVZX EAX,WORD PTR DS:[73811F52] ;DS:[73811F52]为0
7380AE4A |. 48 DEC EAX ;FFFFFFFF
7380AE4B |. C605 CC758173 >MOV BYTE PTR DS:[738175CC],2
7380AE52 |. 50 PUSH EAX
7380AE53 |. 68 561F8173 PUSH WINABC.73811F56
7380AE58 |. E8 FA140000 CALL WINABC.7380C357
7380AE5D |. 881D 6C488173 MOV BYTE PTR DS:[7381486C],BL ;函数将发生错误
7380AE63 |. EB 31 JMP SHORT WINABC.7380AE96
如果del删去V,DS:[73811F52]变量为0,但是DS:[7381486C]=2没有变为0,仍然在输入中途状态,dec eax是为了取得除了v之外的字母串的长度,结果这里变为 0xffffffff,7380AE5D |. 881D 6C488173 MOV BYTE PTR DS:[7381486C],BL 中 函数没有做检查。
7380C4C8 0FB745 10 MOVZX EAX,WORD PTR SS:[EBP+10] ; eax = 0xffff
7380C4CC 8BC8 MOV ECX,EAX
7380C4CE 8BFB MOV EDI,EBX
7380C4D0 037B 58 ADD EDI,DWORD PTR DS:[EBX+58]
7380C4D3 03F3 ADD ESI,EBX
7380C4D5 8B75 0C MOV ESI,DWORD PTR SS:[EBP+C]
7380C4D8 8BD1 MOV EDX,ECX
7380C4DA C1E9 02 SHR ECX,2 ; ecx = 0x3fff
7380C4DD 8943 54 MOV DWORD PTR DS:[EBX+54],EAX
7380C4E0 03C3 ADD EAX,EBX
7380C4E2 F3:A5 REP MOVS DWORD PTR ES:[EDI],DWORD PTR DS> ; 拷贝0x3fff个int
看到了吗,出错的地方。在这里溢出了。
还有这个问题
7380B416 /$ 803D C0558173 >CMP BYTE PTR DS:[738155C0],0AA
7380B41D |. 56 PUSH ESI
7380B41E |. 74 2D JE SHORT WINABC.7380B44D
7380B420 |. 66:8B0D 545E81>MOV CX,WORD PTR DS:[73815E54] ; cx = 0
7380B427 |. 66:49 DEC CX ; cx = 0xffff
7380B429 |. 0FB7C1 MOVZX EAX,CX
7380B42C |. 66:890D 545E81>MOV WORD PTR DS:[73815E54],CX
7380B433 |. 0FB690 405E817>MOVZX EDX,BYTE PTR DS:[EAX+73815E40]
7380B43A |. 0FB680 415E817>MOVZX EAX,BYTE PTR DS:[EAX+73815E41]
ds:0x73815E54表示当前输入栏中有多少字/词 DS:[738129B0]=0时上面的代码会被用到。当用退格消去输入栏中最后一个汉字时DS:[73815E54]=0,DS:[738129B0]应该变成3,表示进入输入状态.但是我们随便输入一个词,然后输入任意字符,按"←",退格,回车,在输入框中得到前一词的默认字,然后连按两次退格。输入第一个退格键,DS:[73815E54]=1,可是DS:[738129B0]并没有变成3,再次按下退格键,函数又执行到这里,cx变为0xffff,就出错了。
因为程序可以导致IME所HOOK的进程退出。所以像万象那样的网吧管理软件会立刻出错而退出进程.而3389登陆也会出错。不过对远程主机似乎没有影响。。。曾经还有人说这个可以造成远程主机重起。所以只是谣言。仔细想想就知道为什么不会对远程主机造成影响咯。