nginx 0day exploit for nginx + fastcgi PHP

Igor Sysoev igor at sysoev.ru
Sat May 22 14:07:08 MSD 2010


On Sat, May 22, 2010 at 05:43:11AM -0400, Ian M. Evans wrote:

> On 5/22/2010 3:54 AM, Igor Sysoev wrote:
> > On Sat, May 22, 2010 at 02:56:02AM -0400, Ian Evans wrote:
> >
> >>
> >> On Sat, May 22, 2010 1:27 am, Igor Sysoev wrote:
> >>> On Sat, May 22, 2010 at 01:24:02AM -0400, Ian M. Evans wrote:
> >>>
> >>>> On 5/21/2010 5:17 PM, Igor Sysoev wrote:
> >>>>> On Fri, May 21, 2010 at 04:50:26PM -0400, Ian Evans wrote:
> >>>>>
> >>>>>>
> >>>>>> On Fri, May 21, 2010 4:39 pm, Igor Sysoev wrote:
> >>>>>>> On Fri, May 21, 2010 at 03:04:18PM -0400, Ian M. Evans wrote:
> >>>>>>>
> >>>>>>>> On 5/21/2010 2:36 PM, Igor Sysoev wrote:
> >>>>>>>>> On Fri, May 21, 2010 at 02:26:31PM -0400, Ian Evans wrote:
> >>>>>>>>>
> >>>>>>>>>> Is this situation only pertaining to sites that allow uploads
> >>>> from
> >>>>>>>> forms?
> >>>>>>>>>>
> >>>>>>>>>> Going way back to this thread
> >>>>>>>>>> (http://www.ruby-forum.com/topic/145358#645652) in '08, I needed
> >>>>>>>>>> cgi.fix-pathinfo=1 to fix problems with paths and specific
> >>>>>>>> extensionless
> >>>>>>>>>> files I needed run as php.
> >>>>>>>>>>
> >>>>>>>>>> Changing cgi.fix-pathinfo=1 to 0 broke a lot of stuff.
> >>>>>>>>>
> >>>>>>>>> Could you show again how URIs should be mapped to SCRIPT_FILENAME
> >>>>>>>>> and PATH_INFO ? Modern nginx versions support named captures in
> >>>> regex.
> >>>>>>>>>
> >>>>>>>>>
> >>>>>>>>
> >>>>>>>> This is what you came up with in the thread back in '08:
> >>>>>>>>
> >>>>>>>>           location ~
> >>>> ^/(cr|news|poll|posters|photos|profile|review)(/|$) {
> >>>>>>>> 		root /usr/local/apache/htdocs;
> >>>>>>>> 		 set  $script_name  $uri;
> >>>>>>>> 		 set  $path_info    "";
> >>>>>>>>
> >>>>>>>> 		 if ($uri ~ ^(/[^/]+)(/.*)) {
> >>>>>>>> 		 set  $script_name  $1;
> >>>>>>>> 		 set  $path_info    $2;
> >>>>>>>> 		 fastcgi_pass 127.0.0.1:10004;
> >>>>>>>> 			 }
> >>>>>>>>           ...
> >>>>>>>>           fastcgi_param  SCRIPT_FILENAME
> >>>> $document_root$script_name;
> >>>>>>>>           fastcgi_param  PATH_INFO        $path_info;
> >>>>>>>>                  }
> >>>>>>>>           location ~
> >>>> /(cr|news|poll|posters|photos|profile|review)(/|$) {
> >>>>>>>>           root /usr/local/apache/htdocs;
> >>>>>>>>           set  $script_name  $uri;
> >>>>>>>>           set  $path_info    "";
> >>>>>>>>           if ($uri ~
> >>>>>>>> ^(.*/(?:cr|news|poll|posters|photos|profile|review))(/.*)) {
> >>>>>>>>           set  $script_name  $1;
> >>>>>>>>           set  $path_info    $2;
> >>>>>>>>           fastcgi_pass 127.0.0.1:10004;
> >>>>>>>>           }
> >>>>>>>>           ...
> >>>>>>>> fastcgi_param SCRIPT_FILENAME    $document_root$script_name;
> >>>>>>>> fastcgi_param  PATH_INFO        $path_info;
> >>>>>>>> fastcgi_pass 127.0.0.1:10004;
> >>>>>>>>           }
> >>>>>>>>
> >>>>>>>> The two variations were needed to handle when the extensionless php
> >>>>>>>> script file was in the root (example.com/NEWS/2006/1/24) or several
> >>>>>>>> subdirs down (example.com/tiff/2007/1/PHOTOS/16)
> >>>>>>>
> >>>>>>> location ~
> >>>>>>> ^/(?<SN>cr|news|poll|posters|photos|profile|review)(?<PI>/.*$|$) {
> >>>>>>>       root /usr/local/apache/htdocs;
> >>>>>>>       fastcgi_pass   127.0.0.1:10004;
> >>>>>>>       fastcgi_param  SCRIPT_FILENAME  $document_root/$SN;
> >>>>>>>       fastcgi_param  PATH_INFO        $PI;
> >>>>>>> }
> >>>>>>>
> >>>>>>> location ~
> >>>>>>> ^(?<SN>.*/(cr|news|poll|posters|photos|profile|review)(?<PI>/.*$|$)
> >>>> {
> >>>>>>>       root /usr/local/apache/htdocs;
> >>>>>>>       fastcgi_pass   127.0.0.1:10004;
> >>>>>>>       fastcgi_param  SCRIPT_FILENAME  $document_root$SN;
> >>>>>>>       fastcgi_param  PATH_INFO        $PI;
> >>>>>>> }
> >>>>>>>
> >>>>>>
> >>>>>> And this will work with cgi.fix-pathinfo=0? Just want to confirm
> >>>> since I
> >>>>>> only have my production server to test on. Guess I really need to dig
> >>>> out
> >>>>>> an old computer one day and just set it up as a local test server.
> >>>>>
> >>>>> It should work in 0.8.32+.  What nginx version do you use ?
> >>>>> You may create similar locations
> >>>>>
> >>>>> location ~ ^/(?<SN>CR|NEWS|...)(?<PI>/.*$|$) {
> >>>>>
> >>>>> to test.
> >>>>>
> >>>>>
> >>>>
> >>>> Igor, I upgrade to the latest 0.8.x. But when I ran
> >>>> /usr/local/nginx/sbin/nginx -t  on the location changes you suggested I
> >>>> rec'd this error:
> >>>>
> >>>> [emerg]: pcre_compile() failed: unrecognized character after (?<  in
> >>>> "^/(?<SN>cr|news|poll|posters|photos|profile|review)(?<PI>/.*$|$)" at
> >>>> "SN>cr|news|poll|posters|photos|profile|review)(?<PI>/.*$|$)"
> >>>
> >>> If nginx fails to start and displays the error message:
> >>>
> >>>      pcre_compile() failed: unrecognized character after (?<  in ...
> >>>
> >>> this means that the PCRE library is old and you should try the
> >>> syntax ?P<name>.
> >>
> >> That's now tossing a "pcre_compile() failed: missing )"
> >>
> >> Your second location suggestion for me was:
> >>
> >> location ~
> >> ^(?P<SN>.*/(cr|news|poll|posters|photos|profile|review)(?P<PI>/.*$|$)
> >>
> >> Looking at that line I do see three '(' and only two ')'. I suck at regex,
> >> so I don't know where the  third ')' needs to go. :-)
> >
> > - ^(?P<SN>.*/(cr|news|poll|posters|photos|profile|review)(?P<PI>/.*$|$)
> > + ^(?P<SN>.*/(cr|news|poll|posters|photos|profile|review))(?P<PI>/.*$|$)
> >
> 
> Man, oh, man. Having one of those nights. The correction fixes the last 
> problem but I'm now getting an [emerg]: unknown "sn" variable

Did you not forget "~"

   location ~ ^(...

?


-- 
Igor Sysoev
http://sysoev.ru/en/



More information about the nginx mailing list