FoxMail 本地密碼破解(提取) ,逆向分析與實現

cwg2552298發表於2019-02-02

    Foxmail是一款用來收發郵件的軟體,如果忘記了儲存的密碼,或者訪問口令,就需要

用逆向的方法,找到Foxmail儲存密碼和訪問口令的方法,並設法提取。

    一般來說軟體儲存密碼不是放檔案裡,就是存登錄檔。啟動ProcMon,過濾Foxmail的

檔案操作,然後建立一個新的賬戶,設定好使用者名稱和密碼後,點選確定。從檔案過濾中

發現可疑的檔案讀寫操作:

\Accounts\Account.cfg
\Accounts\Account.rec0

    猜測就是儲存使用者名稱和密碼的檔案。

PEID掃描Foxmail發現是Delphi寫的,從視窗函式入手會更快一些。直接GetWindowTextA/W

下條件斷點,輸入密碼“666666”,就斷下了,然後資料密碼設定硬體訪問斷點,跟蹤一會兒就

可以找到加密函式了。分析發現就是和一個固定字串做異或加密,然後在前面新增字串

“password”作為標記。 知道了這些就可以輕鬆提取密碼了。

   下面給出異或加密的演算法:

char * EncAlg(char * src,bool encrypt)
{
	unsigned char data[]=
	{
		0x7E, 0x46, 0x40, 0x37, 0x25, 0x6D, 0x24, 0x7E
	};
	int x=0;
	for(int i=0;i<sizeof(data);i++)
	{
		x+=data[i];
	}
	x %=255;		//計算固定值

	char *ret = (char*)VirtualAlloc(0,strlen(src)/2,MEM_COMMIT,PAGE_READWRITE);
	//char * ret=(char*)malloc(strlen(src)/2);

	memset(ret,0,strlen(src));
	char t0 [3]={0};
	memcpy(t0,src,2);
	int p1= IntFromHexStr(t0);

#ifdef DEBUG 
	printf("p1= %d \n",p1);
#endif 
	int v35 = p1 ^ x;
	int v36=0;
	int index=2;		//從0開始算,第二個字元開始解密
	int i=0;
	do{
		if(v36 >= sizeof(data))
			v36 = 1;
		else
			++v36;
		memcpy(t0,src+index,2);
#ifdef DEBUG
		printf("dec = %02X \n",IntFromHexStr(t0));
#endif
		ret[i]= IntFromHexStr(t0) ^ data[v36-1];
#ifdef DEBUG
		printf("char =  %02X \n",ret[i]);
#endif
		int tmp=ret[i]&0xff;
		if(tmp > v35)
			tmp-=v35;
		else
			tmp=tmp+0xff-v35;
		ret[i]=(unsigned char)tmp;
		index+=2;
		v35=IntFromHexStr(t0);
		++i;
	}while(strlen(src) > index);
#ifdef DEBUG
	printf("dec = %s\n",ret);
#endif
	return ret;
}

     搜尋“幻數”,提取加密後的密碼:


char * SearchHead(File * file, char * magic)
{
	//char magic[]="Password";
	char *p=file->dat;
	int cur=0;
	char * ret =0;
	while(cur < (file->fSizeLow-sizeof(magic)))
	{
		if(!memcmp(magic, p + cur,sizeof(magic)))		//找到幻數
		{
#ifdef DEBUG 

			getchar();
			printf("%08X\n",p+cur + sizeof(magic) + 4);
#endif
			int len = *(int*)(p+cur + strlen(magic) + 4);		//獲取字串長度 

			
#ifdef DEBUG
			printf("key len = %d\n",len);
#endif
			ret = (char*)VirtualAlloc(NULL,len+1,MEM_COMMIT,PAGE_READWRITE);
			if(GetLastError() != ERROR_SUCCESS)
				return 0;
			//ret= (char*)malloc(len+1);
			memset(ret,0,len+1);
			memcpy(ret,p+cur+strlen(magic)+8,len);
			return ret;
		}
		cur++;
	}
	return ret;

}

void AnaFile(TCHAR * fileName)
{
	File * file=new File(fileName,false);
	if(!file->success)
	{
		printf("can not open file : %s\n",fileName);
		return ;
	}

	char NameMagic[] = "Account";
	char *name = SearchHead(file,NameMagic);
	if(name !=NULL )
	{
		printf("Account Name : %s\n",name);
	}

	char AccountMagic[]="Password";

	char * accountPwd = SearchHead(file,AccountMagic);
	if(accountPwd != NULL)
	{
#ifdef DEBUG 
		printf("user password is %s\n",accountPwd);
#endif
		printf("password is : %s\n",EncAlg(accountPwd,FALSE));
	}

	char AccessMagic[] ="NodePass";
	char * accessPwd = SearchHead(file,AccessMagic);
	if(accessPwd != NULL)
	{
#ifdef DEBUG 
		printf("Access password is %s\n",accessPwd);
#endif
		printf("access password is : %s\n",EncAlg(accessPwd,FALSE));
	}

}

    寫在末尾,事後我在網上搜了下,早已經有人寫出提取工具了,不過如果不放心別人

寫的工具,可以自己實現,不是更“安全”嗎?

 

相關文章