Exploit-DB #38281
Description: Kaspersky AntiVirus - VB6 Parsing Integer Overflow
Type: dos
Platform: windows
Date: 2015-09-22
Author: Google Security Research

Exploit:
Source: https://code.google.com/p/google-security-research/issues/detail?id=522

Fuzzing VB6 executables produced the attached crash testcase:

(5a8.dc): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=ffffffff ebx=0a07e8ec ecx=0a07eb04 edx=00000000 esi=0907e924 edi=00000010
eip=13d64b78 esp=0ea6ee30 ebp=0ea6ee38 iopl=0         nv up ei pl nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00010202
13d64b78 0fb60e          movzx   ecx,byte ptr [esi]         ds:002b:0907e924=??

# where does esi come from?
0:121> ub @eip La
13d64b60 55              push    ebp
13d64b61 8bec            mov     ebp,esp
13d64b63 8b4514          mov     eax,dword ptr [ebp+14h]
13d64b66 57              push    edi
13d64b67 8b7d0c          mov     edi,dword ptr [ebp+0Ch]
13d64b6a f7d0            not     eax
13d64b6c 85ff            test    edi,edi
13d64b6e 0f849e000000    je      13d64c12
13d64b74 56              push    esi
13d64b75 8b7510          mov     esi,dword ptr [ebp+10h]

# Okay, it's a parameter
0:121> kvn1
 # ChildEBP RetAddr  Args to Child              
00 0ea6ee38 14424d8f 1656cae4 00[PII_REDACTED]e924 0x13d64b78
0:121> ub 14424d8f La
14424d77 8b4304          mov     eax,dword ptr [ebx+4]    <-- load index
14424d7a 03c3            add     eax,ebx                  <-- add to pointer
14424d7c 8d4c3bf0        lea     ecx,[ebx+edi-10h]        <-- probably load bounds of buffer
14424d80 3bc1            cmp     eax,ecx                  <-- check if index is in bounds
14424d82 771f            ja      14424da3                 <-- too late, overflow has already happened
14424d84 6a00            push    0
14424d86 50              push    eax < +0x10
14424d87 6a10            push    10h
14424d89 56              push    esi
14424d8a e8d1fd93ff      call    13d64b60

Looks like the code is doing

ptr += offset;
if (ptr > ptr+SizeOfBuffer)
 goto error;

This is obviously incorrect, because the offset can wrap. Where does that value come from?

0:121> dd ebx
0a07e8ec  00000228 ff[PII_REDACTED]00d0 000000f8
0a07e8fc  0000014f [PII_REDACTED] 000001bc
0a07e90c  [PII_REDACTED] [PII_REDACTED]
0a07e91c  [PII_REDACTED] 02a69b00 101b081b
0a07e92c  00083389 5a4f2f2b 02a69b02 101b081b
0a07e93c  00083389 5a4f2f2b 09194000 11cfdf6e
0a07e94c  a000748e f8260fc9 bac300ac 4551fc30
0a07e95c  204f1db8 383f2a55 77696e7e 4df2a25e

That is from the input file:

*0001e10: 2802 0000 3800 00ff d000 0000 f800 0000  (...8...........
 0001e20: 4f01 [PII_REDACTED] 0000 bc01 0000  O... ...X.......
 0001e30: [PII_REDACTED] [PII_REDACTED]  H...............
 0001e40: [PII_REDACTED] 009b a602 1b08 1b10  ...8............
 0001e50: 8933 0800 2b2f 4f5a 029b a602 1b08 1b10  .3..+/OZ........
 0001e60: 8933 0800 2b2f 4f5a 0040 1909 6edf cf11  .3..+/OZ.@..n...

Proof of Concept:
https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/38281.zip