1. 在项目管理界面发现漏洞

父目录..和目录修改 - 图1

  • 这里直接把页面源码给你了,可以看到page参数是必不可少的

父目录..和目录修改 - 图2

  • 第二段代码是重点

父目录..和目录修改 - 图3

这段代码的功能是通过POST方法上传文件,用户需要制定文件内容与文件名,系统分别接受这两个参数,对文件名后缀进行正则匹配,会将文件上传到./uploaded/backup/这个目录中

重点是这个正则表,**/.+\.ph(p[3457]?|t|tml)$/i** , 这个过滤机制看上去是比较严格的 , 但是因为采用黑名单过滤 , 很大程度上存在被绕过的可能

并且想要执行上面这段代码 , 需要有一个名为**admin**的session , 这个session怎么获得现在还不知道

不过可以猜到 , 利用这个文件上传功能可以上传WebShell.

  • 第三段代码展示了如何获得admin这个session

父目录..和目录修改 - 图4

从URL中获取一个id参数,这个id参数要满足不为’1’,且最后一位为’9’。当通过这个判断后,将其带入数据库操作,如果返回的结果不为空,那么将会设置

**$_SESSION['admin'] = True** .

这里利用了数据库操作,第一反应就是SQL注入,但是代码中使用了mysql_real_escap_string()函数,该函数用于转义SQL语句中使用的字符串中的特殊字符,防御SQL注入,虽然key利用宽字节注入绕过这个防御机制,但是要求目标站点使用GBK编码,但是这些细节信息我都不知,所以想要注入还是比较难的。

再看看代码,发现只要有返回信息就能到session,那么是否可以不采用sql注入,让数据库完成一次有返回值的查询就可以了呢?

代码中哪个floatval()其实给了足够的提示,floatval()函数用获取变量中的浮点值,并且与’1’进行比较,注意这里比较采用的是!==,PHP若类型比较(松散比较)出国很多安全问题,这样使用严格比较,严格比较会比较两者的数据类型,所以这里flatval($——GET[id])!==’1’是恒成立的,请看下图

父目录..和目录修改 - 图5

并且floatval()在碰到特殊字符时,会剪短后面的部分(比如空格),比如这里输入1 2,flaotval()只会返回float(1)

父目录..和目录修改 - 图6

2. 获得$_SESSION[‘admin’]=True

前面已经找到了如何绕过判断,为了满足要求,这里构造id字段为’1 9’,并且空格在带入数据库时会被截断,所以成功返回id=1的用户信息,有因为存在返回信息,所以成功获得session

  • Payload : **?page=flag.php&id=1%209**

父目录..和目录修改 - 图7

3. 上传webshell

拿到了Session,下面就可以上传文件了

文件最终被传到/uploaded/backup/,这个目录是可以直接访问的。

为什么会传到这个目录呢?

上传路径原本在根目录下的/backup/目录下面,由于加了个chdir()函数,因此将根目录后面加上了/uploaded/目录,然后在跟/backup/目录。

父目录..和目录修改 - 图8

那么如何访问上传的文件已经不再是问题,需要做的仅仅是突破这个正则过滤,正则对文件后缀进限制,所以关键点还是在文件名后缀上

入伙突破文件名后缀的限制?主要思路有如下三种

  • 一种是Web中间件的解析漏洞,因为已经知道了中间件是Apache2,使用的是php,所以无非就是Apache解析漏洞或者PHP CGI解析漏洞
  • 一种是上传.htaccess文件,该文件是Apache的一大特殊,其中一个功能便是修改不同的MIME类型文件使用的解析器,但是使用该功能需要Apache在配置文件中设置 AllowOverrideAll,并且开启Rewrite模块,经过测试发现上传的.htaccess无法生效
  1. # 举个例子 : 上传 .htaccess 文件 , 其中写入如下内容
  2. <FilesMatch "shell.jpg">
  3. SetHandler application/x-httpd-php
  4. </FilesMatch>
  5. # 此时 , shell.jpg 会被解析为PHP文件
  6. # 但是经过测试这里 .htaccess 功能被禁用了
  • 罕见文件后缀,想要解析PHP文件,并非后缀要是*.php,如果查看mime.types,会发现很多文件后缀名都使用了application/x-httpd-php这个解析器

父目录..和目录修改 - 图9

其中Phps和php3p都是源代码文件,无法被执行,而上下的所有的后缀名都被正则表过滤,所以这种方式也无法成功上传可执行文件

所以最后还是回到了中间件解析漏洞上,但是经过测试发现这并不是一个常规的解析漏洞,而是利用了一个Linux的目录u结构特性,请看下面代码

父目录..和目录修改 - 图10

创建了一个目录为1.php,在1.php下创建了一个子目录为2.php,Linux下每创建一个新目录都会再其中自动创建两个隐藏文件

父目录..和目录修改 - 图11

其中.. :代表的是目录的父目录

. :代表的是当前目录。

**./1.php/2.php/..** 代表访问 **2.php** 的父目录 , 也就是访问 **1.php** . 这个点我以前都没有注意过

因此在这里构造数据包时,可以构造如下POST数据

Payload : **con=<?php @eval($_POST[cmd]);?>&file=test.php/1.php/..**

将一句话木马写入**test.php** , 而上传的文件名也成功绕过正则表的限制

父目录..和目录修改 - 图12

父目录..和目录修改 - 图13

4. 成功上传webshell

父目录..和目录修改 - 图14

4.另一种绕过方式

正则的话是判断.之后的字符,因此我们可以利用‘/.’的方式绕过,这个方式的意思是在文件名目录下在加个空目录,相当于没加,因此达到绕过正则的目的。

5.总结

这题其实也不算难 , 思路还算清晰 . 我在如何构造文件名绕过正则表过滤上花费了很长时间 , 因为一直想着利用解析漏洞等 … 这种访问子目录的父目录的方式真的学到了!