怎样从PowerShell内存转储中提取运行脚本的内容 | 申博官网
登录
  • 欢迎进入申博官网!
  • 如果您觉得申博官网对你有帮助,那么赶紧使用Ctrl+D 收藏申博官网并分享出去吧
  • 这里是申博官方网!
  • 申博官网是菲律宾sunbet官网品牌平台!
  • 申博开户专业品牌平台!

怎样从PowerShell内存转储中提取运行脚本的内容

申博_安全防护 申博 202次浏览 已收录 0个评论

媒介

在我们剖析了怎样从PowerShell历程转储中提取运动历史记录后,又产生了一个有意思的后续题目:“是不是可以或许提取已实行的剧本内容(来自磁盘),纵然这些文件未被捕捉?”

谜底是一定的,但这一历程也异常复杂。为了细致解说这一要领,我们将从侦察最先起步。在我们的研讨历程当中,许多处所都须要WinDbg辅佐完成自动化操纵,因而我们的第一步就是装置WinDbg模块。

要布置我们的试验情况,我们编写了这个简朴的剧本,并将其生存在类似于C:\temp的地位:

怎样从PowerShell内存转储中提取运行脚本的内容

翻开PowerShell会话,运转剧本,然后建立转储文件。

怎样从PowerShell内存转储中提取运行脚本的内容

如今,运用WinDbg模块连接到转储文件:

Connect-DbgSession -ArgumentList '-z "C:\Users\lee\AppData\Local\Temp\powershell.DMP"'

最先观察

在观察刚刚最先的阶段,我们须要投身于一个异常普遍的收集当中。我们现在晓得,须要提取的是代表在该会话中运转的剧本的对象(若是存在)。然则,我们怎样能找到呢?

起首,我们运用SOS的“Dump Object”(转储对象)敕令,来转储历程中每一个对象的一切内容。因而,我们将从!DumpHeap敕令最先查找一切对象实例(我们以至没有运用Type过滤器)。现实上,我们有更优的要领可以或许完成,但这一步调和下一步调将须要很长的时候,以是我们可以或许在睡觉之前举行这项事情。

$allReferences = dbg !dumpheap –short

一旦我们取得了悉数对象援用,就可以或许运用!do(转储对象)敕令,让SOS将它们悉数可视化。转储对象的输出不包括被转储对象的地点,因而我们也将运用Add-Member来跟踪它。

$allObjects = $allReferences | Foreach-Object { $object = dbg "!do $_"; Add-Member -InputObject $object Address $_ -PassThru -Force }

(转天)我们发明,这确实是一个壮大的对象。在我的体系上,SOS获取了该历程例程的约莫1000000个对象。那末,个中的任何一个对象的GUID都能被SOS以可视化的体式格局展示出来吗?我们来详细看看。

怎样从PowerShell内存转储中提取运行脚本的内容

看起来,我们很荣幸,在这百万级的对象中,我们想法将其缩小到PowerShell内存中的7个System.String对象,这些对象以某种体式格局援用了GUID。若是我们以为信息一直在System.String中,我们可以或许运用$allReferences = dbg !dumpheap –type System.String –short,以使我们的初始“$allObjects”查询更快。然则,我们怎样弄清楚这些GUID对应的是甚么呢?

为了找到谜底,我们要运用SOS的!gcroot敕令。该敕令一般用于诊断托管内存走漏,比方:“我做了甚么终究致使CLR生存此字符串的1000万个实例?”关于任何指定的对象,!gcroot敕令会给出哪一个对象援用了它,以此类推,直至对象树的根。

怎样从PowerShell内存转储中提取运行脚本的内容

如上图所示,末了一个(数组中的第6项)现实上并没有走到根。它不再被援用,因而很快就会被渣滓收集器清算清洁。

第5项以一个对象数组(System.Object[])作为根,个中一个元素是ConcurrentDictionary,个中有一个ScriptBlock,包罗CompiledScriptBlockData,卖力在PowerShell AST中生存节点,并在CommandAst AST中抵达末尾,援用了这一GUID。

看起来不错,那其他项呢?我们来看看实例中的第4项:

————————————-

申博网络安全巴士站

申博-网络安全巴士站是一个专注于网络安全、系统安全、互联网安全、信息安全,全新视界的互联网安全新媒体。

————————————-

怎样从PowerShell内存转储中提取运行脚本的内容

这异常风趣!它的开首是雷同的根对象数组(0000026e101e9a40)、雷同的ConcurrentDictionary(0000026e003bc440),但末了是一个包罗我们的字符串和另一个字符串的元组(Tuple,两项的简朴配对)。接下来,我们深切相识一下这个元组,以及其包罗的字符串。

怎样从PowerShell内存转储中提取运行脚本的内容

剖析PowerShell中响应数据结构

因而,这个元组共包罗两个元素。第一个元素看起来像是实行剧本的途径,第二个元素看起来像是该剧本中的内容。接下来,我们看看PowerShell源代码中的响应数据结构。我们搜刮ConcurrentDictionary,以检察我能找到的内容。在第三页,找到以下内容:

怎样从PowerShell内存转储中提取运行脚本的内容

有一个名为CompiledScriptBlock的类,它包罗一个名为s_cachedScripts的静态(历程局限)缓存。这是一个将一对字符串映照到ScriptBlock实例的字典。我们在浏览源代码后,就可以或许确实地看到元组的内容,剧本途径到ScriptBlock缓存时所包罗内容的映照:

怎样从PowerShell内存转储中提取运行脚本的内容

这个数据结构是我们终究议论的内容。出于机能斟酌,PowerShell保护一个内部剧本块缓存,这样一来每次看到剧本时都不须要再从新编纂剧本块。该缓存是途径和剧本内容的症结。存储在缓存中的内容,是ScriptBlock类的一个实例,它包罗编译的剧本的AST。

因而,我们晓得它的存在,我们可以或许优化自动化顺序,并特地提取这些内容。我们如今编写的是真正有用的剧本,详细步调以下:

1、运用!dumpheap查找此元组类的实例。Dumpheap敕令会实行子字符串搜刮,因而我们会运用正则表达式举行一些后续处置惩罚。

2、我们取得现实想要研讨的元组类MT。

3、再次运用该MT作为过滤器运转!dumpheap。

怎样从PowerShell内存转储中提取运行脚本的内容

如今,我们可以或许探究个中的一个节点。它有一个m_key,我们可以或许深切研讨。

怎样从PowerShell内存转储中提取运行脚本的内容

我们从效果中提掏出两项,然后就可以或许获得一个圆满的PowerShell对象:

怎样从PowerShell内存转储中提取运行脚本的内容

这是一段冗长的路程。我们举行一下回忆,起首我们剖析了一个假定,然后从这个假定最先,层层递进,终究可以或许从PowerShell历程内存中规复一切剧本的内容,纵然已没法再接见相干文件。

源代码

下面是将一切内容打包成函数的剧本:

function Get-ScriptBlockCache
{
    $nodeType = dbg !dumpheap -type ConcurrentDictionary |
        Select-String 'ConcurrentDictionary.*Node.*Tuple.*String.*String.*\]\]$'
    $nodeMT = $nodeType | ConvertFrom-String | Foreach-Object P1
    $nodeAddresses = dbg !dumpheap -mt $nodeMT -short
    $keys = $nodeAddresses | % { dbg !do $_ } | Select-String m_key
    $keyAddresses = $keys | ConvertFrom-String | Foreach-Object P7
 
    foreach($keyAddress in $keyAddresses) {
        $keyObject = dbg !do $keyAddress
 
        $item1 = $keyObject | Select-String m_Item1 | ConvertFrom-String | % P7
        $string1 = dbg !do $item1 | Select-String 'String:\s+(.*)' | % { $_.Matches.Groups[1].Value }
 
        $item2 = $keyObject | Select-String m_Item2 | ConvertFrom-String | % P7
        $string2 = dbg !do $item2 | Select-String 'String:\s+(.*)' | % { $_.Matches.Groups[1].Value }
 
        [PSCustomObject] @{ Path = $string1; Content = $string2 }
    }
}

申博|网络安全巴士站声明:该文看法仅代表作者自己,与本平台无关。版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权
转载请注明怎样从PowerShell内存转储中提取运行脚本的内容
喜欢 (0)
[]
分享 (0)
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址