Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

msilib.OpenDatabase Type Confusion #68782

Closed
JohnLeitch mannequin opened this issue Jul 8, 2015 · 5 comments
Closed

msilib.OpenDatabase Type Confusion #68782

JohnLeitch mannequin opened this issue Jul 8, 2015 · 5 comments
Assignees
Labels
OS-windows stdlib Python modules in the Lib dir type-security A security issue

Comments

@JohnLeitch
Copy link
Mannequin

JohnLeitch mannequin commented Jul 8, 2015

BPO 24594
Nosy @pfmoore, @tiran, @tjguk, @zware, @zooba
Files
  • _msi.patch: _msi.c patch
  • msilib.OpenDatabase_Type_Confusion.py: Repro
  • Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

    Show more details

    GitHub fields:

    assignee = 'https://github.com/zooba'
    closed_at = <Date 2016-09-09.19:10:34.569>
    created_at = <Date 2015-07-08.23:26:41.559>
    labels = ['type-security', 'library', 'OS-windows']
    title = 'msilib.OpenDatabase Type Confusion'
    updated_at = <Date 2016-09-09.19:10:34.568>
    user = 'https://bugs.python.org/JohnLeitch'

    bugs.python.org fields:

    activity = <Date 2016-09-09.19:10:34.568>
    actor = 'steve.dower'
    assignee = 'steve.dower'
    closed = True
    closed_date = <Date 2016-09-09.19:10:34.569>
    closer = 'steve.dower'
    components = ['Library (Lib)', 'Windows']
    creation = <Date 2015-07-08.23:26:41.559>
    creator = 'JohnLeitch'
    dependencies = []
    files = ['39885', '39886']
    hgrepos = []
    issue_num = 24594
    keywords = ['patch']
    message_count = 5.0
    messages = ['246474', '246475', '275223', '275391', '275395']
    nosy_count = 7.0
    nosy_names = ['paul.moore', 'christian.heimes', 'tim.golden', 'python-dev', 'zach.ware', 'steve.dower', 'JohnLeitch']
    pr_nums = []
    priority = 'normal'
    resolution = 'fixed'
    stage = 'resolved'
    status = 'closed'
    superseder = None
    type = 'security'
    url = 'https://bugs.python.org/issue24594'
    versions = ['Python 2.7', 'Python 3.5', 'Python 3.6']

    @JohnLeitch
    Copy link
    Mannequin Author

    JohnLeitch mannequin commented Jul 8, 2015

    The msilib.OpenDatabase method suffers from a type confusion vulnerability caused by the behavior of MsiOpenDatabase(), the underlying win32 function utilized. This is due to the unorthodox handling of the szPersist parameter: when an MSIDBOPEN_* value is passed, it is treated as a predefined persistence mode. However, when a larger value is passed, it is treated as a string pointer, which is used as the path to a new file.

    Because the Python method msilib.OpenDatabase passes its persist parameter through to MsiOpenDatabase, it may be possible for an attacker to trigger the type confusion bug should the seemingly innocuous persist parameter be exposed as attack surface. This could have a few consequences:

    1. An attacker might be able to leverage this vulnerability to probe for valid addresses, which could then be used in another exploit to bypass ASLR/DEP.
    2. An attacker might be able to leverage this vulnerability to dereference aribtrary values in memory, disclosing secrets.
    3. An attacker may be able to spray memory with specially crafted string values, then leverage this vulnerability to pass one of the values as a persist string. Because this would lead to the creation of an MSI file in a location now controlled by the attacker, it could potentially be exploited to achieve remote code execution.

    A Python script that demonstrates the vulnerability is as follows:

    import msilib
    msilib.OpenDatabase("",0x41414141)

    And it produces the following exception:

    0:000> r
    eax=41414141 ebx=00000000 ecx=0027f8c0 edx=41414142 esi=0027f8c0 edi=00000000
    eip=757252aa esp=0027f874 ebp=0027f89c iopl=0 nv up ei pl zr na pe nc
    cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00010246
    KERNELBASE!lstrlenA+0x1a:
    757252aa 8a08 mov cl,byte ptr [eax] ds:002b:41414141=??
    0:000> !analyze -v -nodb


    •                                                                         *
      
    •                    Exception Analysis                                   *
      
    •                                                                         *
      

    FAULTING_IP:
    KERNELBASE!lstrlenA+1a
    757252aa 8a08 mov cl,byte ptr [eax]

    EXCEPTION_RECORD: ffffffff -- (.exr 0xffffffffffffffff)
    ExceptionAddress: 757252aa (KERNELBASE!lstrlenA+0x0000001a)
    ExceptionCode: c0000005 (Access violation)
    ExceptionFlags: 0000000
    NumberParameters: 2
    Parameter[0]: 0000000
    Parameter[1]: 41414141
    Attempt to read from address 41414141

    CONTEXT: 0000000 -- (.cxr 0x0;r)
    eax=41414141 ebx=00000000 ecx=0027f8c0 edx=41414142 esi=0027f8c0 edi=00000000
    eip=757252aa esp=0027f874 ebp=0027f89c iopl=0 nv up ei pl zr na pe nc
    cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00010246
    KERNELBASE!lstrlenA+0x1a:
    757252aa 8a08 mov cl,byte ptr [eax] ds:002b:41414141=??

    FAULTING_THREAD: 00000d38

    PROCESS_NAME: python.exe

    ERROR_CODE: (NTSTATUS) 0xc0000005 - The instruction at 0x%08lx referenced memory at 0x%08lx. The memory could not be %s.

    EXCEPTION_CODE: (NTSTATUS) 0xc0000005 - The instruction at 0x%08lx referenced memory at 0x%08lx. The memory could not be %s.

    EXCEPTION_PARAMETER1: 0000000

    EXCEPTION_PARAMETER2: 41414141

    READ_ADDRESS: 41414141

    FOLLOWUP_IP:
    msi!CApiConvertString::operator unsigned short const *+1b1d
    622e1fa1 40 inc eax

    NTGLOBALFLAG: 70

    APPLICATION_VERIFIER_FLAGS: 0

    APP: python.exe

    ANALYSIS_VERSION: 6.3.9600.17029 (debuggers(dbg).140219-1702) x86fre

    BUGCHECK_STR: APPLICATION_FAULT_INVALID_POINTER_READ_FILL_PATTERN_41414141

    PRIMARY_PROBLEM_CLASS: INVALID_POINTER_READ_FILL_PATTERN_41414141

    DEFAULT_BUCKET_ID: INVALID_POINTER_READ_FILL_PATTERN_41414141

    LAST_CONTROL_TRANSFER: from 622e1fa1 to 757252aa

    STACK_TEXT:
    0027f89c 622e1fa1 41414141 41414141 623e22d0 KERNELBASE!lstrlenA+0x1a
    0027fcf 1d162217 01c54334 41414141 0027fd10 msi!CApiConvertString::operator unsigned short const *+0x1b1d
    0027fd18 1e0aafd7 0000000 01d86940 01d7ea08 _msi!msiopendb+0x37
    0027fd30 1e0edd10 01d7ea08 01d86940 0000000 python27!PyCFunction_Call+0x47
    0027fd5c 1e0f017a 0027fdb4 01c86b18 01c86b18 python27!call_function+0x2b0
    0027fdcc 1e0f1150 01cb4030 0000000 01c86b18 python27!PyEval_EvalFrameEx+0x239a
    0027fe00 1e0f11b2 01c86b18 01cb4030 01c8aa50 python27!PyEval_EvalCodeEx+0x690
    0027fe2c 1e11707a 01c86b18 01c8aa50 01c8aa50 python27!PyEval_EvalCode+0x22
    0027fe44 1e1181c5 01d43a20 01c8aa50 01c8aa50 python27!run_mod+0x2a
    0027fe64 1e118760 68e8740 003f2e93 00000101 python27!PyRun_FileExFlags+0x75
    0027fea4 1e1190d9 68e8740 003f2e93 00000001 python27!PyRun_SimpleFileExFlags+0x190
    0027fec0 1e038d35 68e8740 003f2e93 00000001 python27!PyRun_AnyFileExFlags+0x59
    0027ff3c 1d00116d 00000002 003f2e70 003f1940 python27!Py_Main+0x965
    0027ff80 75847c04 7ffde000 75847be0 0c2f39c0 python!__tmainCRTStartup+0x10f
    0027ff94 77c9b90f 7ffde000 0e681648 0000000 KERNEL32!BaseThreadInitThunk+0x24
    0027ffdc 77c9b8da ffffffff 77c806e0 0000000 ntdll!__RtlUserThreadStart+0x2f
    0027ffec 0000000 1d001314 7ffde000 0000000 ntdll!_RtlUserThreadStart+0x1b

    STACK_COMMAND: .cxr 0x0 ; kb

    SYMBOL_STACK_INDEX: 1

    SYMBOL_NAME: msi!CApiConvertString::operator unsigned short const *+1b1d

    FOLLOWUP_NAME: MachineOwner

    MODULE_NAME: msi

    IMAGE_NAME: msi.dll

    DEBUG_FLR_IMAGE_TIMESTAMP: 5450468f

    FAILURE_BUCKET_ID: INVALID_POINTER_READ_FILL_PATTERN_41414141_c0000005_msi.dll!CApiConvertString::operator_unsigned_short_const_*

    BUCKET_ID: APPLICATION_FAULT_INVALID_POINTER_READ_FILL_PATTERN_41414141_msi!CApiConvertString::operator_unsigned_short_const_*+1b1d

    ANALYSIS_SOURCE: UM

    FAILURE_ID_HASH_STRING: um:invalid_pointer_read_fill_pattern_41414141_c0000005_msi.dll!capiconvertstring::operator_unsigned_short_const_*

    FAILURE_ID_HASH: {11693fba-32c4-0880-2440-574cbd780159}

    Followup: MachineOwner
    ---------

    To fix the issue, msiopendb() should perform whitelist validation of the persist value to confirm that it is a valid MSIDBOPEN_* constant. A proposed patch is attached.

    @JohnLeitch JohnLeitch mannequin added stdlib Python modules in the Lib dir type-security A security issue labels Jul 8, 2015
    @JohnLeitch
    Copy link
    Mannequin Author

    JohnLeitch mannequin commented Jul 8, 2015

    Attaching repro file.

    @BreamoreBoy BreamoreBoy mannequin added the OS-windows label Jul 9, 2015
    @tiran
    Copy link
    Member

    tiran commented Sep 9, 2016

    Steve, please have a look.

    @tiran tiran added the 3.7 (EOL) end of life label Sep 9, 2016
    @zooba
    Copy link
    Member

    zooba commented Sep 9, 2016

    I'm applying the patch, with one small change to pass through persist rather than assuming the variable exists. It'll be 2.7, 3.5 and default.

    @zooba zooba removed the 3.7 (EOL) end of life label Sep 9, 2016
    @python-dev
    Copy link
    Mannequin

    python-dev mannequin commented Sep 9, 2016

    New changeset e524d5dc8767 by Steve Dower in branch '2.7':
    Issue bpo-24594: Validates persist parameter when opening MSI database
    https://hg.python.org/cpython/rev/e524d5dc8767

    New changeset fa89e107f43d by Steve Dower in branch '3.5':
    Issue bpo-24594: Validates persist parameter when opening MSI database
    https://hg.python.org/cpython/rev/fa89e107f43d

    @zooba zooba closed this as completed Sep 9, 2016
    @ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
    Labels
    OS-windows stdlib Python modules in the Lib dir type-security A security issue
    Projects
    None yet
    Development

    No branches or pull requests

    2 participants