我該如何用 windbg 找到你?這個(gè)技能學(xué)到了!
一:背景
1. 講故事
前天wx上有個(gè)朋友丟給我一個(gè)dump,讓我?guī)兔﹁b定一下某些敏感信息在內(nèi)存中是否也是加密的,現(xiàn)在數(shù)據(jù)安全很重要,不僅數(shù)據(jù)庫(kù)中的信息要加密,灌到內(nèi)存后數(shù)據(jù)同樣也需密文存儲(chǔ),隨用隨解密,爭(zhēng)取安全最大化??,此為背景,接下來就是我艸,這咋讓我鑒定呀???????
二:如何鑒定
1. 思考
我艸幾秒后,冷靜下來想想還是有一定解決辦法的,我先把問題化簡(jiǎn)一下。
判斷內(nèi)存中是否有字符串為
張三 or 李四 or 王五的明文字符。判斷內(nèi)存中是否存在各自明文對(duì)應(yīng)的密文。
上面兩點(diǎn)檢索一下,基本就能確定那些敏感信息是否加密了。
像 C# 這種托管語言有一個(gè)好處,就是所有的托管對(duì)象都是存放在 托管堆 上,言外之意就是字符串也在 托管堆 上,所以接下來的問題是如何在堆上檢索 string=張三 的字符串。
問題來了,很多時(shí)候 托管堆 上的 string 是海量的,我見過最高有幾千萬個(gè),string茫茫,何時(shí)才能找到我最靚的崽呀 ?????? ,理論時(shí)間結(jié)束,接下來開始打怪。
2. 案例演示
為了能夠繼續(xù)聊下去,我用一個(gè)簡(jiǎn)單的例子演示一下如何通過人肉搜索 string=張三, 先看代碼。
class Program
{
static List<string> strList = new List<string>();
static void Main(string[] args)
{
strList.Add("fake");
strList.Add("張三");
Console.ReadLine();
}
}
接下來祭出 windbg。
用 !dumpheap -type System.String -min 8 -max 15找到所有10-15byte范圍的字符串。
0:000> !dumpheap -type System.String -min 8 -max 15
Address MT Size
026f1228 652224e4 14
026f164c 652224e4 16
026f230c 65222d74 12
...
Statistics:
MT Count TotalSize Class Name
65225468 1 12 System.Collections.Generic.GenericEqualityComparer`1[[System.String, mscorlib]]
65222d74 10 156 System.String[]
652224e4 65 1168 System.String
Total 76 objects
從輸出中可以看出,當(dāng)前size范圍內(nèi)有 1168 個(gè) string,還發(fā)現(xiàn)這個(gè) size 不是特別準(zhǔn),先不管了,string 雖然有點(diǎn)多,但還是可以人肉的,用 !do xxx 逐個(gè)查看。
0:000> !do 026f2354
Name: System.String
MethodTable: 652224e4
EEClass: 65327690
Size: 18(0x12) bytes
File: C:\Windows\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll
String: 張三
Fields:
MT Field Offset Type VT Attr Value Name
652242a8 4000283 4 System.Int32 1 instance 2 m_stringLength
65222c9c 4000284 8 System.Char 1 instance 5f20 m_firstChar
652224e4 4000288 70 System.String 0 shared static Empty
>> Domain:Value 00a22530:NotInit <<
看到?jīng)]有,上面的 String: 張三 就是我要的結(jié)果,明文存儲(chǔ) 實(shí)錘。
文章到此是不是可以結(jié)束啦 ??????, 那就太沒有實(shí)戰(zhàn)經(jīng)驗(yàn)了,剛才說了,很多時(shí)候篩選后的 string 也可能高達(dá)幾萬幾十萬,再用人肉那是不可能的。。。
那有沒有代替人肉的腳本呢???????, 嘿嘿,還真有。。。
三:使用自動(dòng)化腳本
現(xiàn)在的 windbg preview 支持 javacript 作為腳本擴(kuò)展,接下來我準(zhǔn)備把剛才的 人肉步驟 寫入腳本,貌似專業(yè)名字叫 playbook,蹩腳腳本如下:
"use strict";
function RunCommands() {
var ctl = host.namespace.Debugger.Utility.Control;
var str_address_list = ctl.ExecuteCommand("!dumpheap -type System.String -min 8 -max 15 -short");
for (var str_address of str_address_list) {
var str_dump = ctl.ExecuteCommand("!do -nofields " + str_address);
var str = str_dump.Last();
var isContains = str.indexOf("張三") > 0;
if(isContains) host.diagnostics.debugLog(str+" "+str_address +"\n");
}
}
腳本的邏輯還是非常簡(jiǎn)單的,就是模擬剛才的人肉,最后在輸出內(nèi)容中判斷是否有 張三 的字符串,如果有,連同 address 地址一起打印出來,腳本保存好之后,用 dx 命令來執(zhí)行 RunCommands() 函數(shù)。
0:000> dx Debugger.State.Scripts.RunCommands.Contents.RunCommands()
String: 張三 026f2354
Debugger.State.Scripts.RunCommands.Contents.RunCommands()
看到?jīng)]有, 明文 張三 顯示出來了,不信的話,我截一張圖,證明我沒有騙你 ??????。

四:總結(jié)
在這個(gè)案例中最后使用了 js 腳本輕松搞定,可以看出,腳本給了 windbg 無限的挖掘可能, 真的是太強(qiáng)大了,有興趣的話可參考 MSDN:https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/javascript-debugger-scripting


再見Vip,免費(fèi)看網(wǎng)飛影視大片!
