nginx 0day exploit for nginx + fastcgi PHP

Ian M. Evans ianevans at digitalhit.com
Sat May 22 13:43:11 MSD 2010


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



More information about the nginx mailing list