3

茫茫内存,我该如何用 windbg 找到你 ?

 3 years ago
source link: https://www.cnblogs.com/huangxincheng/p/14651659.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

1. 讲故事

前天wx上有个朋友丢给我一个dump,让我帮忙鉴定一下某些敏感信息在内存中是否也是加密的,现在数据安全很重要,不仅数据库中的信息要加密,灌到内存后数据同样也需密文存储,随用随解密,争取安全最大化😄,此为背景,接下来就是我艹,这咋让我鉴定呀?😂😂😂

二:如何鉴定

我艹几秒后,冷静下来想想还是有一定解决办法的,我先把问题化简一下。

  • 判断内存中是否有字符串为 张三 or 李四 or 王五 的明文字符。

  • 判断内存中是否存在各自明文的 md5。

上面两点检索一下,基本就能确定那些敏感信息是否加密了。

像 C# 这种托管语言有一个好处,就是所有的托管对象都是存放在 托管堆 上,言外之意就是字符串也在 托管堆 上,所以接下来的问题是如何在堆上检索 string=张三 的字符串。

问题来了,很多时候 托管堆 上的 string 是海量的,我见过最高有几千万个,string茫茫,何时才能找到我最靓的崽呀 😤😤😤 ,理论时间结束,接下来开始打怪。

2. 案例演示

为了能够继续聊下去,我用一个简单的例子演示一下如何通过人肉搜索 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

从输出中可以看出,当前size范围内有 1168 个 string,还发现这个 size 不是特别准,先不管了,string 虽然有点多,但还是可以人肉的,用 !do xxx 逐个查看。


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  <<

看到没有,上面的 String: 张三 就是我要的结果,明文存储 实锤。

文章到此是不是可以结束啦 🙃🙃🙃, 那就太没有实战经验了,刚才说了,很多时候筛选后的 string 也可能高达几万几十万,再用人肉那是不可能的。。。

那有没有代替人肉的脚本呢?😜😜😜, 嘿嘿,还真有。。。

三:使用自动化脚本

现在的 windbg preview 支持 javacript 作为脚本扩展,接下来我准备把刚才的 人肉步骤 写入脚本,貌似专业名字叫 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");
    }
}

脚本的逻辑还是非常简单的,就是模拟刚才的人肉,最后在输出内容中判断是否有 张三 的字符串,如果有,连同 address 地址一起打印出来,脚本保存好之后,用 dx 命令来执行 RunCommands() 函数。


0:000> dx Debugger.State.Scripts.RunCommands.Contents.RunCommands()
String:      张三  026f2354
Debugger.State.Scripts.RunCommands.Contents.RunCommands()

看到没有, 明文 张三 显示出来了,不信的话,我截一张图,证明我没有骗你 🤭🤭🤭。

在这个案例中最后使用了 js 脚本轻松搞定,可以看出,脚本给了 windbg 无限的挖掘可能, 真的是太强大了,有兴趣的话可参考 MSDN: https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/javascript-debugger-scripting

更多高质量干货:参见我的 GitHub: dotnetfly

图片名称

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK