Advertisement
Guest User

Untitled

a guest
Sep 2nd, 2011
668
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.84 KB | None | 0 0
  1. /*
  2. Posted to Reddit by JasonMaloney101.
  3. jason[at]masterjason[dot]com
  4.  
  5. Below is the response to the password puzzle.
  6. ------------------------------------
  7.  
  8. in general, nextplease forces dynamic debugging.  The win32 api call to CryptGenRandom() and subsequent calls are designed to fail.  When they fail, the value of GetLastError() is predictable and used to modify value of the locally allocated DWORD.  When the math happens after the api calls, it appears it's used to step into the array of b64'd data blobs.  In reality, x is now zero.  The divide operation throws an exception and -- in the exception handler -- all the real work occurs.
  9.  
  10. If you found the answer with static analysis, you're the man.  But you worked
  11. too hard.  Stepping through with a live debugger will be confusing without
  12. symbols or an understanding of exception handlers, but if you're paying
  13. attention the comparision of the input string to 'a' should be obvious.
  14.  
  15. Of course, you could just change the je at 0x00401279 to a jmp and
  16. ignore everything else.
  17.  
  18. here's the relevant source:
  19. */
  20.  __try
  21.    {
  22.        if( GetCurrentThreadId() > 0 )
  23.        {
  24.            DWORD    x = -88;
  25.  
  26.            if( !CryptGenRandom( NULL, sizeof dwIndex, (PBYTE)&dwIndex )) {
  27.                x += GetLastError();
  28.            }
  29.            else {
  30.                srand( rand() % GetTickCount() + (DWORD)time( (time_t)NULL ));
  31.                x = rand() + GetCurrentThreadId() % 8;
  32.            }
  33.  
  34.            DWORD y = dwIndex++ + x;
  35.  
  36.            if( y < 0 ) {
  37.                dwIndex += rand() % 3;
  38.            }
  39.  
  40.            DWORD z = GetTickCount();
  41.            if( GetTickCount() >= z ) {
  42.                z -= 10;
  43.            }
  44.            DWORD xxx = (DWORD)CreateFileA( "%windir%\\system32\\kernel32.dll.pdb.dbg", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL );
  45.            x -= xxx;
  46.  
  47.            // the whole point of the above nonsense is to get x to be zero without making it deadly obvious
  48.            // requires a bit of understanding of some basic win32 apis
  49.  
  50.            // now, attempt to divide by 0.  the idea is that the code doesn't flow (in IDA) from here to the
  51.            // exception handler, where all the real work happens
  52.  
  53.            z += y / x;
  54.  
  55.            z = z % 10;
  56.  
  57.            dwIndex = z;
  58.  
  59.            // static reversing (from a simplistic pov) will look as though this is the magic password
  60.            decode_base64( (PBYTE)pszDecryptedPassword, rgPasswords[dwIndex] );
  61.            return;
  62.        }
  63.        else
  64.        {
  65.            DWORD x = GetCurrentProcessId();
  66.            x <<= 2;
  67.            x += GetCurrentProcessId();
  68.            DWORD y = (DWORD)GetConsoleWindow();
  69.            DWORD z = y + x / 2 + (DWORD)CryptGenRandom;
  70.            dwIndex = z % 11;
  71.        }
  72.    }
  73.    __except( EXCEPTION_EXECUTE_HANDLER )
  74.    {
  75.        pszDecryptedPassword[0] = 'a';
  76.    }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement