nginx 0day exploit for nginx + fastcgi PHP

Igor Sysoev igor at sysoev.ru
Sat May 22 11:54:08 MSD 2010


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>/.*$|$)


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



More information about the nginx mailing list