本文由红日安全成员: DYBOY 编写,如有不当,还望斧正。

前言

大家好,我们是红日安全-代码审计小组。最近我们小组正在做一个PHP代码审计的项目,供大家学习交流,我们给这个项目起了一个名字叫 PHP-Audit-Labs 。现在大家所看到的系列文章,属于项目 第一阶段 的内容,本阶段的内容题目均来自 PHP SECURITY CALENDAR 2017 。对于每一道题目,我们均给出对应的分析,并结合实际CMS进行解说。在文章的最后,我们还会留一道CTF题目,供大家练习,希望大家喜欢。下面是 第15篇 代码审计文章:

Day 1 Sleigh Ride

题目叫做滑雪橇,代码如下:

漏洞解析 :

这一关主要考察的是$_SERVER['PHP_SELF'] 引发的一个任意网址跳转漏洞

首先,分析一下程序的运行

如果有$_GET['redirect'] 参数,那么就 New 一个 Redirect 对象,同时调用 Redirect 对象的startRedirect 成员函数

startRedirect函数接受一个 GET 类型的 params 参数,然后在 explode('/', $_SERVER['PHP_SELF']) 函数中,将 $_SERVER['PHP_SELF'] 得到的值,通过/来生成一个$parts数组。

$baseFile 的值为 $parts数组的最后一个值

$url的值为$baseFile?http_build_query($params),其中的 http_build_query()函数就是一个将参数进行URL编码的一个操作,比如 $params='test=123'

然后调用 setHeaders 函数,首先解码$url 参数,然后 header() 函数直接跳转 $url

$_SERVER['PHP']存在的问题:

初看这个程序没什么问题,但是PHP自带的$_SERVER['PHP_SELF'] 参数是可以控制的。其中PHP_SELF指当前的页面绝对地址,比如我们的网站:http://www.test.com/redict/index.php,那么PHP_SELF就是/redict/index.php。但有个小问题很多人没有注意到,当URL是PATH_INFO的时候,比如:http://www.test.com/redict/index.php/admin,那么PHP_SELF就是/redict/index.php/admin

也就是说,其实PHP_SELF有一部分是我们可以控制的。

双编码问题:

URL本来是被浏览器编码过一次,服务器接收到来自浏览器URL请求的时候,会将URL解码一次,由于在程序中我们看到有urldecode()函数存在,它会再次解码一次URL,此时双编码URL就可以利用,用于绕过某些关键词检测。比如将/编码为:%252f

漏洞利用:

比如我们要跳转到我的博客:blog.dyboy.cn,那么就可以构造Payload:http://www.test.com/index.php/http:%252f%252fblog.dyboy.cn?redirect=test¶ms=test123,访问即可重定向跳转到http://blog.dyboy.cn网址

如下图所示,发生了302跳转:

实例分析

其实关于这个漏洞的利用是有很多src,但是都是黑盒测试不是很清楚后台的代码怎么设计的,这里可以提及到一个关于360webscan的防护脚本一个历史漏洞,正是由于$_SERVER['PHP_SELF'] 这个参数导致可以绕过360webscan防护脚本的防护,脚本的防护效果失效,现在此防护脚本更新了

其结构为:

因为这只是一个防护的辅助脚本任何的程序都可以安装使用,这里就以Emlog5.3.1博客程序为例子,程序不重要,这个脚本可以安装接入到任何的程序中。

安装的方法:解压得到360safe文件夹,上后上传到我们的网站根目录中,同时在任意的全局文件中加入如下代码即可安装成功:

在按照上述安装方法安装后,测试访问:http://www.test.com/index.php?test=

XSS拦截显示:

比如GET类型存在SQL注入关键词的等都会被拦截

虽然本脚本的正则过滤规则很好了,但是通过这一个$_SERVER['PHP_SELF'],可以通过白名单规则绕过攻击防护

在存在绕过漏洞的360webscan历史版本中,在194行至219行的的代码(拦截目录白名单检测):

在上图的第五行,我们看到$url_path的值是直接取的$_server['PHP_SELF']的值,同时没有做任何的验证或过滤

那么我们只要在请求的URL(提交的参数中)存在白名单目录,那么就可以绕过安全检测

因为在webscan_cache.php中的默认的白名单目录存在admin

然后我们访问:http://www.test.com/index.php/admin?test=%3Cscript%3Ealert(1)%3C/script%3E

此处虽然返回的状态码是404,但是,我们发现已经不再拦截了,如果再配合某些CMS或者PHP系统的伪静态特殊性,那么就可以成功的绕过防护

修复建议

本次审计的其实不是漏洞,主要是一个$_SERVER['PHP_SELF']的问题,再遇上某系伪静态规则配合下,就会导致各种由此形成的各种漏洞

因此,这里推荐使用$_SERVER['SCRIPT_NAME']代替即可,同时,我们可以看到在最新的360webscan中已经更新了这个问题,并且使用了$_SERVER['SCRIPT_NAME']

结语

看完了上述分析,不知道大家是否对 $_SERVER['PHP_SELF'] 函数有了更加深入的理解,文中用到的emlog可以从 百度网盘 (密码: hkb4) 下载,当然文中若有不当之处,还望各位斧正。如果你对我们的项目感兴趣,欢迎发送邮件到 hongrisec@gmail.com 联系我们。

Day15的分析文章就到这里,我们最后留了一道CTF题目给大家练手,题目如下:

index.php 文件:

require('./waf.php');

$conn = mysql_connect('localhost', 'root', 'root') or die('bad!');

mysql_select_db('sql_inject', $conn) OR die("连接数据库失败,未找到您填写的数据库");

//执行sql语句

Measurement_url()

$id = isset($_GET['id']) ? $_GET['id'] : 1;

$sql = "SELECT user FROM sql_inject1 WHERE id='$id'";

$result = mysql_query($sql, $conn) or die(mysql_error());

?>

sql_inject

if(isset($_GET['file']))

{

if(is_file($_GET['file']))

die("Do you want to touzou my code?!");

else{

if(stripos($_GET['file'],'index'))

die("you can only read waf.php!");

else { readfile($_GET['file']);

exit();

}

}

}

$row = mysql_fetch_array($result, MYSQL_ASSOC);

echo "

{$row['user']}

\n";

mysql_free_result($result);

?>

waf.php文件:

error_reporting(0);

$_GET=Add_S($_GET);

$_POST=Add_S($_POST);

$_COOKIE=Add_S($_COOKIE);

$_REQUEST=Add_S($_REQUEST);

function Add_S($array)

{

foreach($array as $key=>$value){

if(!is_array($value)){

$check= preg_match('/regexp|and|like|\"|%|insert|update|delete|union|into|load_file|outfile|\/\*/i', $value);

if($check)

{

exit("Hacker!");

}

}else{

$array[$key]=Add_S($array[$key]);

}

}

return $array;

}

function Measurement_url()

{

$url=parse_url($_SERVER['REQUEST_URI']);

parse_str($url['query'],$query);

$Keyword=array("from","select","like","or");

foreach($query as $key)

{

foreach($Keyword as $value)

{

if(preg_match("/".$value."/",strtolower($key)))

{

die("fuck u!");

}

}

}

}

?>

sql.sql数据文件(MYSQL):

CREATE TABLE IF NOT EXISTS `sql_inject1`(

`id` int auto_increment not null,

`user` varchar(20) not null,

`password` varchar(40) not null,

primary key(`id`)

)ENGINE=InnoDB DEFAULT CHARSET=utf8;

insert into sql_inject1(user,password) values('ur10ser','injectmeifucan');

insert into sql_inject1(user,password) values('admin','injectmeifucan');

insert into sql_inject1(user,password) values('Chabug','66666666666');

insert into sql_inject1(user,password) values('flag','flag{Parse_ur1_iz_not_safe2333333!}');

题解我们会阶段性放出,如果大家有什么好的解法,可以在文章底下留言,祝大家玩的愉快!

相关文章

%3c?php else:?%3e,[红日安全]代码审计Day15 - $_SERVER['PHP_SELF']导致的防御失效问题相关推荐

  1. PHP ctf addslashes,[红日安全]代码审计Day13 - 特定场合下addslashes函数的绕过

    本文由红日安全成员: l1nk3r 编写,如有不当,还望斧正. 前言 大家好,我们是红日安全-代码审计小组.最近我们小组正在做一个PHP代码审计的项目,供大家学习交流,我们给这个项目起了一个名字叫 P ...

  2. %3c php foreach%3e,PHP 数组函数-数组排序

    php数组排序函数 sort  (  &$arr   [,fruits] )  对数组进行从低到高排序 ,并赋予新的键名 返回bool rsort  ( &$arr   [,fruit ...

  3. %3c燕子专列%3e语言文字表达,人教版小学三年级下册语文练习题

    [导语]语文是语言和文化的综合科.语言和文章.语言知识和文化知识的简约式统称等都离不开它.它是听.说.读.写.译.编等语言文字能力和知识,文化知识的统称.也可以说,语文是口头和书面的语言和言语的合称, ...

  4. self php语法,PHP代码审计之关于PHP_SELF的简单利用

    这两天突然看到 https://blog.ripstech.com/2020/sql-injection-impresscms/,想着复现一下,记录一下学习过程. 漏洞分析 漏洞复现 首先我们先下载安 ...

  5. mysql %3c%3e sql优化_SQL注入技术和跨站脚本攻击的检测(2)

    2.3 典型的 SQL 注入攻击的正则表达式 /\w*((\%27)|(\'))((\%6F)|o|(\%4F))((\%72)|r|(\%52))/ix 解释: \w* - 零个或多个字符或者下划线 ...

  6. php中%3c w() %3e,DedeCMS V5.7 SP2后台存在代码执行漏洞

    原标题:DedeCMS V5.7 SP2后台存在代码执行漏洞 *本文原创作者:风炫520,本文属FreeBuf原创奖励计划,未经许可禁止转载 简介 织梦内容管理系统(DedeCms)是一款PHP开源网 ...

  7. %3chtml%3e%3c html,在JEditorPane中显示HTML的问题java

    不知道为什么setText不起作用.但是,这是一个解决方法. 试试这个URL. (在URL中的整个文件)(这是当你在它的setText Android的WebView中所说的) data:text/h ...

  8. body%3e %3c html%3e,index.html

    上流人粉丝实时查看 @font-face { font-family: 'number'; src:url('clock-number.ttf'); } html, body { padding: 0 ...

  9. 红日代码审计(day15-day24)

    day-15:Sleigh Ride <?php class Redirect {private $websiteHost = 'www.example.com';private functio ...

最新文章

  1. Linux内核 题目,《Linux内核完全注释》部分习题答案
  2. android展示gif循环,android:GIF动画循环完成听众
  3. 用python监控磁盘_使用python怎么对服务器cpu和磁盘空间进行监控
  4. CTFshow php特性 web141
  5. Android插件化原理解析——广播的管理
  6. LintCode-第k大元素
  7. 【若依(ruoyi)】获取mainContent的宽高
  8. gan学到的是什么_GAN推动生物学研究
  9. python 数组合并排重_并排深度学习:Julia vs Python
  10. docker mysql 操作_[Docker] Docker 快速搭建本地MySQL开发环境
  11. QT学习笔记(一):VS2013 +QT 5.8 运行、编译问题解决
  12. MySQL存储过程事务处理
  13. C++各个算数类型占用的字节数
  14. 一个cmake的简单例子:来自github
  15. django orm 数据查询详解
  16. Windows 11 配置JDK 环境变量
  17. Java项目:SSM会议室预约系统
  18. 【MMD动作+镜头】Bo Peep Bo Peep
  19. 星期、月份英文缩写对照表
  20. 沃尔什矩阵与哈达玛矩阵的简单理解与程序式快速生成

热门文章

  1. C++算法学习(力扣:面试题 16.04. 井字游戏)
  2. 安卓蓝牙键盘切换输入法_Windows10添加中文美式键盘,传统语言栏,采用ctrl+shift切换输入法...
  3. TypeScript算法专题 - blog9 - 单链表统计 : 返回指定值在单链表结点中的出现次数
  4. java app的强制更新吗_java – Spring JPA / Hibernate事务强制插入而不是更新
  5. AcWing 905. 区间选点(贪心)
  6. html table 充满div,HTML,使用div+css实现自适应table布局
  7. CDH6.2.1安装Kafka出现的问题
  8. 第三章Python快速入门
  9. [spring]用IEDA创建spring boot项目
  10. 关于搭建wiki镜像和数据库的一些东西