宽带连接用户名称和密码恢复原理.docx

上传人:b****8 文档编号:28537350 上传时间:2023-07-18 格式:DOCX 页数:16 大小:30.32KB
下载 相关 举报
宽带连接用户名称和密码恢复原理.docx_第1页
第1页 / 共16页
宽带连接用户名称和密码恢复原理.docx_第2页
第2页 / 共16页
宽带连接用户名称和密码恢复原理.docx_第3页
第3页 / 共16页
宽带连接用户名称和密码恢复原理.docx_第4页
第4页 / 共16页
宽带连接用户名称和密码恢复原理.docx_第5页
第5页 / 共16页
点击查看更多>>
下载资源
资源描述

宽带连接用户名称和密码恢复原理.docx

《宽带连接用户名称和密码恢复原理.docx》由会员分享,可在线阅读,更多相关《宽带连接用户名称和密码恢复原理.docx(16页珍藏版)》请在冰豆网上搜索。

宽带连接用户名称和密码恢复原理.docx

宽带连接用户名称和密码恢复原理

宽带连接用户名称和密码恢复原理

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\n",argv[0]);

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

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > IT计算机 > 电脑基础知识

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1