作者:sunwear
也感謝dencefire的幫忙 :)
智能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登陸也會出錯。不過對遠端主機似乎沒有影響。。。曾經還有人說這個可以造成遠端主機重起。是以隻是謠言。仔細想想就知道為什麼不會對遠端主機造成影響咯。
本文轉自loveme2351CTO部落格,原文連結: http://blog.51cto.com/loveme23/8583,如需轉載請自行聯系原作者