nginx缓存带来的临时文件
关于文件上传
来自于ctfshow技术分享
PHP
PHP临时文件机制
全局变量
在PHP中可以使用POST方法或者PUT方法进行文本和二进制文件的上传。上传的文件信息会保存在全局变量$_FILES里。
$_FILES超级全局变量很特殊,他是预定义超级全局数组中唯一的二维数组。其作用是存储各种与上传文件有关的信息,这些信息对于通过PHP脚本上传到服务器的文件至关重要。
1 | $_FILES['userfile']['name'] 客户端文件的原名称。 |
在临时文件包含漏洞中$_FILES['userfile']['name']
这个变量值的获取很重要,因为临时文件的名字都是由随机函数生成的,只有知道文件的名字才能正确的去包含它。
储存目录
临时目录由php.ini的upload_tmp_dir
属性指定。假如upload_tmp_dir
的路径不可写,PHP会上传到系统默认的临时目录中。
1 | Linux: |
命名规则
Linux临时文件主要存储在/tmp/
目录下,格式通常是(/tmp/php[6个随机字符]
)
Windows临时文件主要存储在C:/Windows/
目录下,格式通常是(C:/Windows/php[4个随机字符].tmp
)
nginx缓存
body_buffer
官方文档:http://nginx.org/en/docs/http/ngx_http_core_module.html#client_body_buffer_size
client_body_buffer_size
这个参数,也就是nginx关于上传的配置处
设置读取客户端请求正文的缓冲区大小。 如果请求正文大于缓冲区,则将整个正文或仅其部分写入临时文件。 默认情况下,缓冲区大小等于两个内存页。 这是 x86、其他 32 位平台和 x86-64 上的 8K。 在其他 64 位平台上通常为 16K。
也就是说当body中数据的大于16k的时候就会有临时文件写入。
client_body_in_file_only
,默认是关闭
确定 nginx 是否应将整个客户端请求正文保存到文件中。 该指令可以在调试期间使用,或者在使用 $request_body_file 变量或模块 ngx_http_perl_module 的 $r->request_body_file 方法时使用。
当设置为 on 时,临时文件在请求处理后不会被删除。
值 clean 将导致请求处理后留下的临时文件被删除。
client_body_temp_path
,关于临时文件的存放目录
定义一个目录,用于存储保存客户端请求正文的临时文件。 指定目录下最多可以使用三级子目录层次结构。 例如,在以下配置中
1 | client_body_temp_path /spool/nginx/client_temp 1 2; |
临时文件的目录就会像下面这样
1 | /spool/nginx/client_temp/7/45/00000123457 |
因此当我们的请求body大于16k的时候,他就会生成缓存到上面这个目录,但是马上又删除了,但是他删除以后,又继续进行了修改和访问
就可以通过/proc/PID/fd/{}来访问到这个临时文件
利用思路
如果我们的so文件临时膨胀到16k以上,也就是在so文件之后加入垃圾字节,就能够让so文件被存入到临时文件中去。
例:ctfshow web818
直接学习羽师傅脚本即可,他这里是用socket库来进行网络请求的。
关键点是31行的恶意字节填充,让hack.so的文件内容写入nginx产生的临时文件
接着用bruter函数对proc目录进行一个爆破即可,这里的pid题目中会给到,所以只用爆破后面的fd即可
羽师傅的脚本真的清晰,学习了
1 | # coding: utf-8 |
fastcgi_buffer
http://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_buffering
fastcgi_buffers
当启用来自 FastCGI 服务器的响应缓冲时,限制在响应尚未完全读取时可能正忙于向客户端发送响应的缓冲区的总大小。 同时,其余缓冲区可用于读取响应,并在需要时将部分响应缓冲到临时文件。 默认情况下,大小受 fastcgi_buffer_size 和 fastcgi_buffers 指令设置的两个缓冲区的大小限制。
fastcgi_temp_path
a temporary file might look like this:
1 /spool/nginx/fastcgi_temp/7/45/00000123457
同样对于fastcgi缓存的利用也和上面的body_buffer利用思路一样,只是临时文件保存的目录变了