宽带连接用户名称和密码恢复原理.docx
- 文档编号:28537350
- 上传时间:2023-07-18
- 格式:DOCX
- 页数:16
- 大小:30.32KB
宽带连接用户名称和密码恢复原理.docx
《宽带连接用户名称和密码恢复原理.docx》由会员分享,可在线阅读,更多相关《宽带连接用户名称和密码恢复原理.docx(16页珍藏版)》请在冰豆网上搜索。
宽带连接用户名称和密码恢复原理
宽带连接用户名称和密码恢复原理
ADSL密码忘记了,但幸好还保存在拨号连接里面,到网上找了些星号密码显示工具,可惜不起作用。
后来找到一"获得宽带用户名称和密码"(xp)。
该工具并非非普通的星号密码显示工具,那它的原理是什么呢?
其实原理很简单,就是用rasapi32.dll里面的一些函数来获取拨号连接的一些信息(),再用ADVAPI32!
LsaRetrievePrivateData函数来获取密码,后来研究"LsaRetrievePrivateData"返回的数据。
其原理大致如下:
1)插入一线程到lsass.exe进程
2)打开LSAPolicydatabase
3)从注册表"HKLM\SECURITY\Policy\Secrets"中枚举子键
4)LsarOpenSecret
5)LsarQuerySecret
进一步研究后发现,其实ADVAPI32!
LsaRetrievePrivateData是通过NdrClientCall2发送RPC调用到lsass.exe进程,lsass.exe里面再调用LsarOpenSecret、LsarQuerySecret来完成获取拨号连接信息过程的。
(注:
LsarOpenSecret里面有权限判断,非ADMIN组用户是没有权限来调用ADVAPI32!
LsaRetrievePrivateData的)跟踪了一下LsarQuerySecret,发现它返回的数据其实是从注册表中读取。
保存拨号连接信息的注册表键值为:
HKLM\SECURITY\Policy\Secrets\RasDialParams!
SID#0\CurrVal。
SID对应的是用户的stringSID。
(“HKLM\SECURITY”这个键只有SYSTEM有权限读写,连admin都没有权限)LsarQuerySecret从注册表中读取出来数据后,接着调用LsapCrDecryptValue函数来解密,对于同一台机器来说,解密时用的KEY始终都是固定的,这个KEY在lsasrv.dll里面变量名为"_LsapDbSecretCipherKey"。
在windows2003里面,变量名不一样,对应的有两个,分别为"LsapDbSecretCipherKeyWrite"和"LsapDbSecretCipherKeyRead",但这两个变量里面的数据是一样的。
LsapCrDecryptValue用的似乎是标准DES算法,解密时主要流程如下:
lsasrv!
LsapCrDecryptValue
|_advapi32!
SystemFunction005
|_advapi32!
DecryptDataLength
|_advapi32!
SystemFunction002
|_advapi32!
DES_ECB_LM
|_advapi32!
des
解密后,在"<<"标示处还有一个判断:
.text:
785462F0call_LsapCrDecryptValue@12
.text:
785462F5testeax,eax
.text:
785462F7mov[ebp+var_8],eax
.text:
785462FAjlloc_785838E1
.text:
78546300
.text:
78546300loc_78546300:
.text:
78546300cmpbyteptr[esi+45h],0<<<<<<<<<<<<
.text:
78546304jzshortloc_7854632E
......
.text:
7854632Eloc_7854632E:
.text:
7854632Eleaeax,[ebp+var_10]
.text:
78546331pusheax
.text:
78546332push[ebp+arg_8]
.text:
78546335push[ebp+var_C]
.text:
78546338call_LsapCrEncryptValue@12
假如[esi+45h]为0的话(esi是LsarOpenSecret函数返回的HANDLE),它会把解密后的数据再进行一次加密,不管是Win2000还是Win2003,这时用的KEY始终都是固定为“SystemLibraryDTC”。
调用LsarOpenSecret得到的HANDLE,偏移0x45处值为1,所以LsarQuerySecret函数返回的就是解密后的数据了。
而在调用ADVAPI32!
LsaRetrievePrivateData时,LsarOpenSecret返回的HANDLE偏移0x45处值为0x0,所以LsarQuerySecret返回的是解密后又加密的数据,所以在ADVAPI32!
LsaRetrievePrivateData里面还有一个对应的解密过程。
相应的,LsapCrEncryptValue加密的主要流程如下:
lsasrv!
LsapCrEncryptValue
|_advapi32!
SystemFunction004
|_advapi32!
EncryptDataLength
|_advapi32!
SystemFunction001
|_advapi32!
DES_ECB_LM
|_advapi32!
des
那么这个_LsapDbSecretCipherKey是如何产生的?
流程如下:
(1)调用ntdll!
NtConnectPort打开L"\Security\WxApiPort"
(2)调用ntdll!
NtRequestWaitReplyPort得到一些数据ebp-40处为NtRequestWaitReplyPort返回的LPCMESSAGE
kd>ddebp-40
0006fcb80040002800000002000000dc000000d8
0006fcc800000024000000000000000000000000
0006fcd8000000010000001000000010fd317e3e
0006fce87e24e86dd12503d35f7d01a87665f528
kd>dbebp-14
0006fce43e7e31fd6de8247e-d30325d1a8017d5f
(3)将上述"ebp-14"处的0x10字节数据COPY到lsasrv.dll里面的"_LsapDbSysKey"变量。
"_LsapDbSysKey"在不同的机器上面(即使版本相同)都是不一样的。
跟踪系统启动过程,可知道"\Security\WxApiPort"是由winlogon.exe进程创建的,然后lsass进程通过这个LPCPORT从winlogon进程获取SYSKEY,随后winlogon进程会关闭这个LPCPORT。
所以在系统启动完成之后,用"ProcessExplorer"等工具是看不到这个LPCPORT存在的,而且在winlogon和LSASS进程空间都搜索不到上述SYSKEY。
(4)从注册表"HKLM\SECURITY\Policy\PolSecretEncryptionKey"中读取出来一段数据,
调用函数_LsapDbDecryptKeyWithSyskey,把它用"_LsapDbSysKey"来解密,"_LsapDbSecretCipherKey"就在解密完后的数据里面。
("LsapDbDecryptKeyWithSyskey"函数做的其实就是MD5和RC4运算)
了解原理后,我们就可以直接从注册表里面来获取拨号连接中的密码等数据了。
但有几个问题需要解决:
(1)原料。
Q:
"HKLM\SECURITY"键只有SYSTEM有权限读写?
A:
我们可以把代码插入到SYSTEM进程里面去运行,或者把这个键修改为ADMIN有权限读,或者提升本进程权限。
(2)催化剂:
)
Q:
如何获取"_LsapDbSysKey"?
解密用的函数_LsapDbDecryptKeyWithSyskey为非导出函数,怎么办?
A1:
用flashsky的代码来获取SYSKEY,利用公开的MD5和RC4库函数来解密。
A2:
直接从lsass.exe进程里面搜索"_LsapDbSecretCipherKey",它的结构如下,
typedefstruct_LSA_BLOB{
DWORDcbData;
DWORDcbMaxData;
BYTE*pbData;
}LSA_BLOB;
pbData指向存储KEY的地址,KEY长度固定为0x10字节,即cbData和cbMaxData都是固定为0x10。
所以从lsass进程的空间里面搜索"\x10\x00\x00\x00\x10\x00\x00\x00"即可找到正确的KEY。
结果可能会有多个,可以把所有搜索到的KEY都试一下,总有一个正确的。
(3)工具
Q:
解密函数LsapCrDecryptValue为非导出函数,怎么办?
A:
或许可以根据特征码来搜索,但总觉得不太可靠。
幸好,LsapCrDecryptValue调用的advapi32!
SystemFunction005是导出函数:
)。
或者直接利用公开的DES库函数,自己来运算。
-=-=-=-=-=-=-=-=-=-=x_dialupass2.cpp-=-=-=-=-=-=-=-=-=-=
/*
演示还原NT平台拨号连接密码
原理:
直接从注册表中读取加密后的数据,解密之。
可运行于windows2000/xp/2003平台,必须有权限读取注册表"HKLM\SECURITY"。
eyasatxfocus.org
2004-10-01
*/
#include
#include
#include
#pragmacomment(lib,"Advapi32.lib")
#pragmacomment(lib,"psapi.lib")
//抄袭tombkeeper的代码:
)
#defineFCHK(a)if(!
(a)){printf(#a"failed%d\n",GetLastError());return
0;}
typedefstruct_LSA_BLOB{
DWORDcbData;
DWORDcbMaxData;
BYTE*pbData;
}LSA_BLOB;
typedefint(WINAPI*PSystemFunction005)(
LSA_BLOB*pDataIn,
LSA_BLOB*pDataKey,
LSA_BLOB*pDataOut
);
PSystemFunction005SystemFunction005;
DWORDdwFlag=0;
//来自lsadump2中的dumplsa.c
intmyisprint(intch)
{
return((ch>='')&&(ch<='~'));
}
//来自lsadump2中的dumplsa.c
void
dump_bytes(unsignedchar*p,size_tsz)
{
charszDumpBuff[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){
charbuf[17];
inti=0;
intj=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);
}
}
DWORDsearch_LsapDbSecretCipherKey(BYTE**ppKey,DWORDpid)
{
HANDLEhLsass,hLsasrv;
DWORDdwRead,i,dwAddr;
BYTE*pImage=NULL;
MODULEINFOmod;
BOOLbRet=FALSE;
DWORDdwCount=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 { 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++; } } }//endoffor } __except(EXCEPTION_EXECUTE_HANDLER) { returndwCount; } returndwCount; } intmain(intargc,char**argv) { intret,i,j; HMODULEhAdvApi32; HKEYhKeySecrets; HKEYhKey; DWORDdwType; charData[0x500]={0}; BYTE*pKey; DWORDdwSize; LSA_BLOBLSADataIn; LSA_BLOBLSADataOut; LSA_BLOBLSADataKey; charszSecret[500]; charszSubKey[0x500]; DWORDdwErr,dwCount=0; if(argc! =2) { printf("Usage: %s return0; } 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 { printf("LsapDbSecretCipherKey[%d]\n",j); dump_bytes(&pKey[j*0x10],0x10); LSADataKey.cbData=LSADataKey.cbMaxData=0x10; LSADataKey.pbData=&pKey[j*0x10]; //searchourtarget for(i=0;TRUE;i++) { dwErr=RegEnumKeyA(hKeySecrets,i,szSecret,sizeof(szSecret)); if(dwErr! =ERROR_SUCCESS) // //NoMoreSecrets // break; printf("\n%s\n",szSecret); //openit _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); }//endoffor printf("Pressanykeytousenext\"LsapDbSecretCipherKey\",orCtrl+C toexit.\n"); getchar(); } if(pKey) free(pKey); r
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 宽带 连接 用户 名称 密码恢复 原理