Wireshark 2 Preview n*8字节越界读取bug

此bug已提交至官方论坛,bugtrack id 10529,https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=10529
漏洞作者:blast(http://nul.pw

事发此崩溃:

(14b4.1dd8): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
*** ERROR: Symbol file could not be found.  Defaulted to export symbols for F:\Program Files\Wireshark\Qt5Core.dll - 
*** WARNING: Unable to verify checksum for qtshark.exe
*** ERROR: Module load completed but symbols could not be loaded for qtshark.exe
Qt5Core!QPersistentModelIndex::row:
00000000`5f2d5bd0 488b01          mov     rax,qword ptr [rcx] ds:baadf00d`baadf00d=????????????????

(注:上面这个崩溃是从调试器启动的,所以堆上未初始化的数据是以baadf00d这个填充模式填入的,实际运行时应该是00000000`00000000,上面是越界8字节的情况)

查看崩溃附近的代码:

0:000> ub .
Qt5Core!QPersistentModelIndex::operator!=+0x58:
00000000`5f2d5bc8 cc              int     3
00000000`5f2d5bc9 cc              int     3
00000000`5f2d5bca cc              int     3
00000000`5f2d5bcb cc              int     3
00000000`5f2d5bcc cc              int     3
00000000`5f2d5bcd cc              int     3
00000000`5f2d5bce cc              int     3
00000000`5f2d5bcf cc              int     3
0:000> u .
Qt5Core!QPersistentModelIndex::row:
00000000`5f2d5bd0 488b01          mov     rax,qword ptr [rcx]
00000000`5f2d5bd3 4885c0          test    rax,rax
00000000`5f2d5bd6 7403            je      Qt5Core!QPersistentModelIndex::row+0xb (00000000`5f2d5bdb)
00000000`5f2d5bd8 8b00            mov     eax,dword ptr [rax]
00000000`5f2d5bda c3              ret
00000000`5f2d5bdb 83c8ff          or      eax,0FFFFFFFFh
00000000`5f2d5bde c3              ret
00000000`5f2d5bdf cc              int     3

崩溃发生在Qt5Core!QPersistentModelIndex::row的第一行,函数试图将第一个参数(rcx)解引用给eax时崩溃。

0:000> .frame /c 1
01 00000000`001da420 00000000`5f8755e6 qtshark+0x90612
rax=baadf00dbaadf00d rbx=00000000001da6e8 rcx=baadf00dbaadf00d
rdx=0000000002c04e00 rsi=0000000000000014 rdi=00000000001da630
rip=000000013f820612 rsp=00000000001da420 rbp=00000000001da589
 r8=0000000000008000  r9=0000000000000008 r10=0000000000350268
r11=00000000001d9d88 r12=0000000002d3f300 r13=0000000000000003
r14=0000000002d49d30 r15=0000000002d3f300
iopl=0         nv up ei pl nz na po nc
cs=0033  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00010206
qtshark+0x90612:
00000001`3f820612 498b4c2448      mov     rcx,qword ptr [r12+48h] ds:00000000`02d3f348=00c4a43f01000000
0:000> dd rcx
baadf00d`baadf00d  ???????? ???????? ???????? ????????
baadf00d`baadf01d  ???????? ???????? ???????? ????????
baadf00d`baadf02d  ???????? ???????? ???????? ????????
baadf00d`baadf03d  ???????? ???????? ???????? ????????
baadf00d`baadf04d  ???????? ???????? ???????? ????????
baadf00d`baadf05d  ???????? ???????? ???????? ????????
baadf00d`baadf06d  ???????? ???????? ???????? ????????
baadf00d`baadf07d  ???????? ???????? ???????? ????????

看看r12是从哪儿传来的,上方有一个mov rcx,rax,

0:000> uf . 
qtshark+0x905e0:
00000001`3f8205e0 4053            push    rbx
00000001`3f8205e2 4154            push    r12
00000001`3f8205e4 4883ec48        sub     rsp,48h
00000001`3f8205e8 488bda          mov     rbx,rdx
00000001`3f8205eb 4c8be1          mov     r12,rcx  ;here
00000001`3f8205ee ff15c4b21100    call    qword ptr [qtshark+0x1ab8b8 (00000001`3f93b8b8)]
00000001`3f8205f4 49837c244800    cmp     qword ptr [r12+48h],0
00000001`3f8205fa 0f84a1010000    je      qtshark+0x907a1 (00000001`3f8207a1)

qtshark+0x90600:
00000001`3f820600 488bcb          mov     rcx,rbx
00000001`3f820603 ff158f931100    call    qword ptr [qtshark+0x1a9998 (00000001`3f939998)]
00000001`3f820609 488bc8          mov     rcx,rax
00000001`3f82060c ff158e931100    call    qword ptr [qtshark+0x1a99a0 (00000001`3f9399a0)]

为了验证,在函数开头下断点,重新启动程序:

0:000> g
Breakpoint 0 hit
qtshark+0x905e0:
00000001`3f3d05e0 4053            push    rbx
0:000> r
rax=000000013f515d48 rbx=0000000002aff6c0 rcx=0000000002aff6c0
rdx=000000000023a488 rsi=0000000000000014 rdi=000000000023a3d0
rip=000000013f3d05e0 rsp=000000000023a218 rbp=000000000023a329
 r8=000000000023a490  r9=000000000023a3d0 r10=000000005fb1a340
r11=000000005fa55228 r12=000000000023a3d0 r13=0000000000000003
r14=0000000002b09fe0 r15=0000000002aff6c0
iopl=0         nv up ei pl nz na po nc
cs=0033  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000206
qtshark+0x905e0:
00000001`3f3d05e0 4053            push    rbx

执行期间可以发现:

0:000> 
qtshark+0x90603:
*** ERROR: Symbol file could not be found.  Defaulted to export symbols for F:\Program Files\Wireshark\Qt5Core.dll - 
00000001`3f3d0603 ff158f931100    call    qword ptr [qtshark+0x1a9998 (00000001`3f4e9998)] ds:00000001`3f4e9998={Qt5Core!QList<QItemSelectionRange>::front (00000000`5f962d00)}
0:000> 
qtshark+0x90609:
00000001`3f3d0609 488bc8          mov     rcx,rax
0:000> r rax
Last set context:
rax=baadf00dbaadf00d

看来是Qt5Core!QList::front 的问题,重启bp qtshark+0x90603。

让我们看一下正常的操作是什么:

Breakpoint 0 hit
qtshark+0x90603:
00000001`3f9e0603 ff158f931100    call    qword ptr [qtshark+0x1a9998 (00000001`3faf9998)] ds:00000001`3faf9998={Qt5Core!QList<QItemSelectionRange>::front (00000000`5f462d00)}
0:000> r
rax=0000000000000000 rbx=000000000030a0d8 rcx=000000000030a0d8
rdx=0000000000000000 rsi=0000000000000014 rdi=000000000030a048
rip=000000013f9e0603 rsp=0000000000309e20 rbp=0000000000309f89
 r8=0000000000008000  r9=0000000000000008 r10=00000000003e0268
r11=0000000000309788 r12=0000000002c2f440 r13=0000000000000003
r14=0000000002c39e20 r15=0000000002c2f440
iopl=0         nv up ei pl nz na po nc
cs=0033  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000206
qtshark+0x90603:
00000001`3f9e0603 ff158f931100    call    qword ptr [qtshark+0x1a9998 (00000001`3faf9998)] ds:00000001`3faf9998={Qt5Core!QList<QItemSelectionRange>::front (00000000`5f462d00)}

进入之后,

0:000> t
Qt5Core!QList<QItemSelectionRange>::front:
00000000`5f462d00 488b11          mov     rdx,qword ptr [rcx] ds:00000000`0030a0d8=80c6310500000000
0:000> 
Qt5Core!QList<QItemSelectionRange>::front+0x3:
00000000`5f462d03 48634208        movsxd  rax,dword ptr [rdx+8] ds:00000000`0531c688=00000000
0:000> t
Qt5Core!QList<QItemSelectionRange>::front+0x7:
00000000`5f462d07 488b44c210      mov     rax,qword ptr [rdx+rax*8+10h] ds:00000000`0531c690=f0c52d0500000000
0:000> r
rax=0000000000000000 rbx=000000000030a0d8 rcx=000000000030a0d8
rdx=000000000531c680 rsi=0000000000000014 rdi=000000000030a048
rip=000000005f462d07 rsp=0000000000309e18 rbp=0000000000309f89
 r8=0000000000008000  r9=0000000000000008 r10=00000000003e0268
r11=0000000000309788 r12=0000000002c2f440 r13=0000000000000003
r14=0000000002c39e20 r15=0000000002c2f440
iopl=0         nv up ei pl nz na po nc
cs=0033  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000206
Qt5Core!QList<QItemSelectionRange>::front+0x7:
00000000`5f462d07 488b44c210      mov     rax,qword ptr [rdx+rax*8+10h] ds:00000000`0531c690=f0c52d0500000000
0:000> t
Qt5Core!QList<QItemSelectionRange>::front+0xc:
00000000`5f462d0c c3              ret
0:000> r
rax=00000000052dc5f0

这一次执行结果是返回了一个指针。

这是不正常的走向:

0:000> r
rax=0000000000000000 rbx=00000000001da648 rcx=00000000001da648
rdx=000007feebae9ff0 rsi=0000000000000014 rdi=00000000001da590
rip=000000013f860603 rsp=00000000001da380 rbp=00000000001da4e9
 r8=0000000000000005  r9=0000000000000069 r10=0000000000000000
r11=0000000000000002 r12=00000000027bf3f0 r13=0000000000000003
r14=00000000027c9e30 r15=00000000027bf3f0
iopl=0         nv up ei pl nz na po nc
cs=0033  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000206
qtshark+0x90603:
00000001`3f860603 ff158f931100    call    qword ptr [qtshark+0x1a9998 (00000001`3f979998)] ds:00000001`3f979998={Qt5Core!QList<QItemSelectionRange>::front (00000000`5f962d00)}
0:000> t
Qt5Core!QList<QItemSelectionRange>::front:
00000000`5f962d00 488b11          mov     rdx,qword ptr [rcx] ds:00000000`001da648=10cf6b0200000000
0:000> 
Qt5Core!QList<QItemSelectionRange>::front+0x3:
00000000`5f962d03 48634208        movsxd  rax,dword ptr [rdx+8] ds:00000000`026bcf18=01000000
0:000> 
Qt5Core!QList<QItemSelectionRange>::front+0x7:
00000000`5f962d07 488b44c210      mov     rax,qword ptr [rdx+rax*8+10h] ds:00000000`026bcf28=0df0adba0df0adba
0:000> 
Qt5Core!QList<QItemSelectionRange>::front+0xc:
00000000`5f962d0c c3              ret

由于每次操作会产生2个selection change事件,所以有问题的是第二个操作。

Qt5Core!QList<QItemSelectionRange>::front:
mov     rdx,qword ptr [rcx]
movsxd  rax,dword ptr [rdx+8]
mov     rax,qword ptr [rdx+rax*8+10h]
ret

而这个函数的整个操作就这4行。

rdx = *rcx;
rax = *(rdx+8);
return *(rdx+rax*8+0x10);

综合一下就是:

return *(*rcx+(*(rdx+8))*8+0x10);

实际执行起来是:

return *(*arg1+0x10);

或者

return *(*arg1+0x18);

//取决于选的数量

由于我们没有符号,不知道具体代表什么,但是再出问题的部分,如果执行:

0:000> r
rax=0000000000000001 rbx=000000000015a6c8 rcx=000000000015a6c8
rdx=0000000005143d90 rsi=0000000000000014 rdi=000000000015a610
rip=000000005f462d07 rsp=000000000015a3f8 rbp=000000000015a569
 r8=0000000000008000  r9=0000000000000008 r10=0000000001f30268
r11=0000000000159d68 r12=0000000002d3f220 r13=0000000000000003
r14=0000000002d49bb0 r15=0000000002d3f220
iopl=0         nv up ei pl nz na po nc
cs=0033  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000206
Qt5Core!QList<QItemSelectionRange>::front+0x7:
00000000`5f462d07 488b44c210      mov     rax,qword ptr [rdx+rax*8+10h] ds:00000000`05143da8=0df0adba0df0adba
0:000> dd rdx+10
00000000`05143da0  02d678b0 00000000 baadf00d baadf00d
00000000`05143db0  abababab abababab abababab abababab

看到好玩的了吧,这纯粹是越界访问了。那么既然选一个就是+0x8,如果可以选上更多的数据,是否就可以读到后面的0x00000040 00000000呢?我猜应该是可以的吧=v=

0:000> .cxr
Resetting default scope
0:000> dd rdx+10
00000000`05143da0  02d678b0 00000000 baadf00d baadf00d
00000000`05143db0  abababab abababab abababab abababab
00000000`05143dc0  00000000 00000000 00000000 00000000
00000000`05143dd0  00000040 00000000

标签:none

添加新评论

captcha
请输入验证码