
Outlook 2019 ज़ीरो-क्लिक भेद्यता CVE-2020-1349 के लिए शोषण, जो MIME हेडर पार्सिंग बग्स का उपयोग करके हीप ओवरफ्लो और vftable ओवरराइट के माध्यम से EIP नियंत्रण प्राप्त करता है।
यह कमजोरी Outlook 2019 (16.0.12624.20424) में होती है जो कोरियाई Windows 10 1909 x64, codepage 949 पर स्थापित है।

मैं इस कमजोरी का उपयोग करके aslr को बायपास नहीं कर पाया हूँ, लेकिन मैंने एक outlook 2019 32bit एक्सप्लॉइट लिखा है जो बूट समय पर फिक्स्ड सिस्टम लाइब्रेरी के पते का उपयोग करके कैलकुलेटर खोलता है। और यह कमजोरी एक जीरो-क्लिक कमजोरी है। यदि "outlook.com" खाते के अलावा किसी अन्य मेल सेवा का खाता IMAP का उपयोग करके Outlook 2019 से लिंक किया गया है, तो यह केवल मेल प्राप्त करने पर ट्रिगर होता है।
v26 = IsDBCSLeadByte(*v13);
v12 = 0;
if ( v26 )
{
LODWORD(v5) = v5 - 1;
*v11++ = *v13++;
--v8;
}
LODWORD(v5) = v5 - 1;
*v11++ = *v13++;
--v8;
goto LABEL_51;
[OUTLMIME!CloseAllSockets+0x50804 स्यूडो कोड]
क्रैश होता है, और जहाँ कमजोरी मौजूद है वह भाग ऊपर दिया गया है। जब पार्स किए गए To हेडर या From हेडर का स्ट्रिंग मल्टीबाइट होता है, तो पार्स किए जाने वाले शेष स्ट्रिंग्स की गणना करने वाले वेरिएबल को 2 से घटाया जाता है, और जब वेरिएबल 1 होता है तो उसे 2 से घटाने पर इंटीजर अंडरफ्लो होता है।
if ( v23 != '=' )
{
if ( v23 == 34 )
v15 = 6;
goto LABEL_48;
}
v15 = 1;
}
if ( v15 )
goto LABEL_40;
[OUTLMIME!CloseAllSockets+0x50804 स्यूडो कोड]
LABEL_40:
v24 = v13[v14];
if ( v24 )
{
if ( v5 == v14 )
goto LABEL_52;
if ( v8 != v14 )
{
v25 = IsDBCSLeadByte(v24);
v12 = 0;
if ( v25 )
++v14;
++v14;
}
}
goto LABEL_51;
}
[OUTLMIME!CloseAllSockets+0x50804 स्यूडो कोड]
LABEL_51:
if ( v5 <= v14 )
goto EXIT_0;
}
[OUTLMIME!CloseAllSockets+0x50804 स्यूडो कोड]
if ( v15 )
{
if ( v15 == 1 )
{
v15 = 2;
v21 = v13[v14];
v22 = v14 + 1;
if ( v21 != '?' )
v22 = v14;
if ( v21 != '?' )
v15 = v12;
v14 = v22;
}
[OUTLMIME!CloseAllSockets+0x50804 स्यूडो कोड]
else if ( v15 > 1 )
{
if ( v15 <= 3 )
{
v18 = v13[v14];
v19 = v14 + 1;
if ( v18 != '?' )
v19 = v14;
v14 = v19;
v20 = v15 + 1;
if ( v18 != '?' )
v20 = v15;
v15 = v20;
}
[OUTLMIME!CloseAllSockets+0x50804 स्यूडो कोड]
if ( v15 == 4 )
{
if ( v13[v14] == '?' )
v15 = 5;
LABEL_40:
v24 = v13[v14];
if ( v24 )
{
if ( v5 == v14 )
goto LABEL_52;
if ( v8 != v14 )
{
v25 = IsDBCSLeadByte(v24);
v12 = 0;
if ( v25 )
++v14;
++v14;
}
}
goto LABEL_51;
}
[OUTLMIME!CloseAllSockets+0x50804 स्यूडो कोड]
if ( v15 == 5 )
{
v16 = v14;
v17 = v14 + 1;
v30 = v13[v16];
if ( v30 == '=' )
{
*v11++ = 34;
--v8;
}
memcpy(v11, v13, v17);
v13 += v17;
v11 += v17;
LODWORD(v5) = v5 - v17;
v8 -= v17;
if ( v30 == '=' )
{
*v11++ = 34;
--v8;
}
v12 = 0;
v14 = 0;
v15 = 0;
goto LABEL_51;
}
[OUTLMIME!CloseAllSockets+0x50804 स्यूडो कोड]
else
{
v23 = v13[v14];
if ( v23 != '=' )
{
if ( v23 == '"' )
v15 = 6;
goto LABEL_48;
}
v15 = 1;
}
if ( v15 )
goto LABEL_40;
[OUTLMIME!CloseAllSockets+0x50804 स्यूडो कोड]
LABEL_48:
v26 = IsDBCSLeadByte(*v13);
v12 = 0;
if ( v26 )
{
LODWORD(v5) = v5 - 1;
*v11++ = *v13++;
--v8;
}
LODWORD(v5) = v5 - 1;
*v11++ = *v13++;
--v8;
goto LABEL_51;
[OUTLMIME!CloseAllSockets+0x50804 स्यूडो कोड]
हालाँकि, उपरोक्त बग का उपयोग करके हीप ओवरफ्लो ट्रिगर करते समय, मैं फिर से लूप से बाहर निकलने की शर्त को पूरा नहीं कर सका, इसलिए मैं जितना चाहता था उतना आंशिक ओवरराइट नहीं कर सका। इसलिए मुझे एक ऐसा इनपुट खोजना पड़ा जो एक विशिष्ट शर्त को पूरा करता हो ताकि लूप से बाहर निकला जा सके। उपरोक्त ही कारण से, मैंने आसपास के कोड भाग का सख्ती से ऑडिट किया, और लूप से बचने वाला इनपुट मान खोजने के बजाय, एक विशेष स्ट्रिंग को प्रोसेस करते समय इंडेक्स या राइटिंग बढ़ाए बिना अनंत लूप में फंसने का बग मिला।

heap spray और heap feng shui करने के बाद, ऊपर दिए गए बग का उपयोग करके अनंत लूप में न फंसे दूसरे थ्रेड में चल रहे ऑब्जेक्ट के vftable को ओवरराइट करके eip hijack सफल हुआ।