0x333-lockdexvul.txt

2003-07-29T00:00:00
ID PACKETSTORM:31467
Type packetstorm
Reporter nic
Modified 2003-07-29T00:00:00

Description

                                        
                                            ` - 0x333 OUTSIDERS SECURITY LABS -  
- www.0x333.org -  
  
lockdev in redhat 7.3 ,8.0 ,9.0 possible all linux os has Segmentation fault  
  
~~~ contents ~~~  
  
[0x0] Info  
[0x1] Description  
[0x2] Vulnerable code  
[0x3] Debug session  
[0x4] Exploit  
  
  
[0x0] Info  
Author : nic  
Email : nic0x333@hotmail.com  
Date : 28 July 2003  
Advisory : outsiders-004.txt  
Vender URL : http://www.hklpg.org/RPM/rawhide/1.0/ia64/RedHat/RPMS/lockdev-1.0.0-21.ia64.html  
Category : vul bug   
OS affected : redhat 7.3 8.0 possible 9.0 --> all redhat   
  
[0x1] Description  
  
lockdev is defaultly installed in all redhat os, or other linux os. our team find a bug.  
  
it is affected by a vul bug. it is +s lock group. The exploit will spawn a shell with   
  
gid=xx(lock).  
  
  
  
[0x2] Vulnerable code  
  
In setup.c we found :  
  
/*  
* local function list_setups  
*/  
  
/* exported by the interface file lockdev.h */  
  
main()  
  
case 'u':  
i = dev_unlock( dev, 0);  
break;  
.............................  
  
  
  
/* exported by the interface file lockdev.h */  
pid_t  
dev_unlock( devname, pid)  
const char * devname;  
const pid_t pid;  
{  
const char * p;  
char device[MAXPATHLEN+1];  
char lock0[MAXPATHLEN+1];  
char lock1[MAXPATHLEN+1];  
char lock2[MAXPATHLEN+1];  
struct stat statbuf;  
pid_t wpid;  
  
#if DEBUG  
if ( env_var_debug == -1 ) {  
char *value;  
if ( value=getenv( _env_var ) )  
env_var_debug = liblockdev_debug = atoi( value);  
signal( SIGUSR1, _dl_sig_handler);  
signal( SIGUSR2, _dl_sig_handler);  
}  
#endif /* DEBUG */  
_debug( 3, "dev_unlock(%s, %d)\n", devname, (int)pid);  
if (oldmask == -1 )  
oldmask = umask( 0); /* give full permissions to files created */  
if ( ! (p=_dl_check_devname( devname)) )  
close_n_return( -1);  
strcpy( device, DEV_PATH);  
strcat( device, p); /* now device has a copy of the pathname */  
_debug( 2, "dev_unlock() device = %s\n", device);  
  
/* check the device name for existence and retrieve the major  
* and minor numbersn  
if ( stat( device, &statbuf) == -1 ) {  
close_n_return( -1);  
}  
  
/* first remove the FSSTND-1.2 lock, get the pid of the  
* owner of the lock and test for its existence; in case,  
* return the pid of the owner of the lock.  
*/  
/* lockfile of type /var/lock/LCK..ttyS2 */  
_dl_filename_2( lock2, p);  
wpid = _dl_check_lock( lock2);  
if ( pid && wpid && pid != wpid )  
close_n_return( wpid); /* error or locked by someone else */  
  
/* lockfile of type /var/lock/LCK.004.064 */  
_dl_filename_1( lock1, &statbuf);  
wpid = _dl_check_lock( lock1);  
if ( pid && wpid && pid != wpid )  
close_n_return( wpid); /* error or locked by someone else */  
  
_dl_filename_0( lock0, wpid);  
if ( wpid == _dl_check_lock( lock0))  
unlink( lock0);  
  
/* anyway now we remove the files, in the reversed order than  
* they have been built.  
*/  
unlink( lock2);  
unlink( lock1);  
_debug( 2, "dev_unlock() unlocked\n");  
close_n_return( 0); /* successfully unlocked */  
}  
  
..........................................................................  
  
  
_dl_check_devname( devname)  
const char * devname;  
{  
int l;  
const char * p;  
char *m;  
  
/* devname can be absolute, relative to PWD or a single  
* filename, in any case we assume that the file is in /dev;  
* maybe we should check it and do something if not?  
*/  
p = devname; /* only a filename */  
while ( (m=strrchr( p, '/')) != 0 ) { ....................pointer  
p = m+1; /* was pointing to the slash */  
.....................................................................................  
[0x3] Debug session  
  
bash-2.05a$ gdb ./lockdev  
GNU gdb Red Hat Linux (5.1.90CVS-5)  
Copyright 2002 Free Software Foundation, Inc.  
GDB is free software, covered by the GNU General Public License, and you are  
welcome to change it and/or distribute copies of it under certain conditions.  
Type "show copying" to see the conditions.  
There is absolutely no warranty for GDB. Type "show warranty" for details.  
This GDB was configured as "i386-redhat-linux"...  
(no debugging symbols found)...  
(gdb) r -u  
Starting program: /usr/sbin/lockdev -u  
(no debugging symbols found)...(no debugging symbols found)...  
Program received signal SIGSEGV, Segmentation fault.  
0x42080f33 in strrchr () from /lib/i686/libc.so.6  
(gdb) disas dev_unlock  
Dump of assembler code for function dev_unlock:  
0x8049b80 <dev_unlock>: push %ebp  
0x8049b81 <dev_unlock+1>: mov %esp,%ebp  
0x8049b83 <dev_unlock+3>: push %edi  
0x8049b84 <dev_unlock+4>: push %esi  
0x8049b85 <dev_unlock+5>: push %ebx  
0x8049b86 <dev_unlock+6>: sub $0x407c,%esp  
0x8049b8c <dev_unlock+12>: call 0x8048d10 <main+528>  
0x8049b91 <dev_unlock+17>: add $0x56f,%ebx  
0x8049b97 <dev_unlock+23>: cmpl $0xffffffff,0xffffff1c(%ebx)  
0x8049b9e <dev_unlock+30>: jne 0x8049bb3 <dev_unlock+51>  
0x8049ba0 <dev_unlock+32>: sub $0xc,%esp  
0x8049ba3 <dev_unlock+35>: push $0x2  
0x8049ba5 <dev_unlock+37>: call 0x804882c <umask>  
0x8049baa <dev_unlock+42>: mov %eax,0xffffff1c(%ebx)  
0x8049bb0 <dev_unlock+48>: add $0x10,%esp  
0x8049bb3 <dev_unlock+51>: mov 0x8(%ebp),%eax  
0x8049bb6 <dev_unlock+54>: sub $0xc,%esp  
0x8049bb9 <dev_unlock+57>: push %eax  
0x8049bba <dev_unlock+58>: call 0x8049110 <_dl_check_devname>  
0x8049bbf <dev_unlock+63>: mov %eax,%edi  
0x8049bc1 <dev_unlock+65>: add $0x10,%esp  
0x8049bc4 <dev_unlock+68>: test %edi,%edi  
---Type <return> to continue, or q <return> to quit---q  
Quit  
(gdb) b *0x8049bba  
Breakpoint 1 at 0x8049bba  
(gdb) r -u  
The program being debugged has been started already.  
Start it from the beginning? (y or n) y  
Starting program: /usr/sbin/lockdev -u  
(no debugging symbols found)...(no debugging symbols found)...  
Breakpoint 1, 0x08049bba in dev_unlock ()  
(gdb) b *0x8049bbf  
Breakpoint 2 at 0x8049bbf  
(gdb) r  
The program being debugged has been started already.  
Start it from the beginning? (y or n) y  
Starting program: /usr/sbin/lockdev -u  
(no debugging symbols found)...(no debugging symbols found)...  
Breakpoint 1, 0x08049bba in dev_unlock ()  
(gdb) c  
Continuing.  
  
Program received signal SIGSEGV, Segmentation fault.  
0x42080f33 in strrchr () from /lib/i686/libc.so.6  
(gdb)  
  
so i can deside bug is in <0x8049bbf <dev_unlock+63>: mov %eax,%edi>  
(gdb) disas strrchr  
Dump of assembler code for function strrchr:  
0x42080e90 <strrchr>: push %edi  
0x42080e91 <strrchr+1>: push %esi  
0x42080e92 <strrchr+2>: xor %eax,%eax  
0x42080e94 <strrchr+4>: mov 0xc(%esp,1),%esi  
0x42080e98 <strrchr+8>: mov 0x10(%esp,1),%ecx  
0x42080e9c <strrchr+12>: mov %cl,%ch  
0x42080e9e <strrchr+14>: mov %ecx,%edx  
0x42080ea0 <strrchr+16>: shl $0x10,%ecx  
0x42080ea3 <strrchr+19>: mov %dx,%cx  
0x42080ea6 <strrchr+22>: test $0x3,%esi  
0x42080eac <strrchr+28>: je 0x42080f33 <strrchr+163>  
0x42080eb2 <strrchr+34>: mov (%esi),%dl  
0x42080eb4 <strrchr+36>: cmp %dl,%cl  
0x42080eb6 <strrchr+38>: jne 0x42080eba <strrchr+42>  
0x42080eb8 <strrchr+40>: mov %esi,%eax  
0x42080eba <strrchr+42>: or %dl,%dl  
0x42080ebc <strrchr+44>: je 0x42081046 <strrchr+438>  
0x42080ec2 <strrchr+50>: inc %esi  
0x42080ec3 <strrchr+51>: test $0x3,%esi  
0x42080ec9 <strrchr+57>: je 0x42080f33 <strrchr+163>  
0x42080ecb <strrchr+59>: mov (%esi),%dl  
0x42080ecd <strrchr+61>: cmp %dl,%cl  
---Type <return> to continue, or q <return> to quit---  
0x42080ecf <strrchr+63>: jne 0x42080ed3 <strrchr+67>  
0x42080ed1 <strrchr+65>: mov %esi,%eax  
0x42080ed3 <strrchr+67>: or %dl,%dl  
0x42080ed5 <strrchr+69>: je 0x42081046 <strrchr+438>  
0x42080edb <strrchr+75>: inc %esi  
0x42080edc <strrchr+76>: test $0x3,%esi  
0x42080ee2 <strrchr+82>: je 0x42080f33 <strrchr+163>  
0x42080ee4 <strrchr+84>: mov (%esi),%dl  
0x42080ee6 <strrchr+86>: cmp %dl,%cl  
0x42080ee8 <strrchr+88>: jne 0x42080eec <strrchr+92>  
0x42080eea <strrchr+90>: mov %esi,%eax  
0x42080eec <strrchr+92>: or %dl,%dl  
0x42080eee <strrchr+94>: je 0x42081046 <strrchr+438>  
0x42080ef4 <strrchr+100>: inc %esi  
0x42080ef5 <strrchr+101>: jmp 0x42080f33 <strrchr+163>  
0x42080ef7 <strrchr+103>: add %al,(%eax)  
0x42080ef9 <strrchr+105>: add %al,0xee8304ee(%ebx)  
0x42080eff <strrchr+111>: add $0x83,%al  
0x42080f01 <strrchr+113>: out %al,(%dx)  
0x42080f02 <strrchr+114>: add $0xf7,%al  
0x42080f04 <strrchr+116>: ret $0x0  
0x42080f07 <strrchr+119>: add %bh,%bh  
0x42080f09 <strrchr+121>: jne 0x42080f19 <strrchr+137>  
---Type <return> to continue, or q <return> to quit---  
0x42080f0b <strrchr+123>: lea 0xf(%esi),%eax  
0x42080f0e <strrchr+126>: jmp 0x42080f30 <strrchr+160>  
0x42080f10 <strrchr+128>: sub $0x4,%esi  
0x42080f13 <strrchr+131>: sub $0x4,%esi  
0x42080f16 <strrchr+134>: sub $0x4,%esi  
0x42080f19 <strrchr+137>: test $0xff0000,%edx  
0x42080f1f <strrchr+143>: jne 0x42080f26 <strrchr+150>  
0x42080f21 <strrchr+145>: lea 0xe(%esi),%eax  
0x42080f24 <strrchr+148>: jmp 0x42080f30 <strrchr+160>  
0x42080f26 <strrchr+150>: lea 0xc(%esi),%eax  
0x42080f29 <strrchr+153>: test %dh,%dh  
0x42080f2b <strrchr+155>: jne 0x42080f30 <strrchr+160>  
0x42080f2d <strrchr+157>: lea 0xd(%esi),%eax  
0x42080f30 <strrchr+160>: add $0x10,%esi  
0x42080f33 <strrchr+163>: mov (%esi),%edx  
(gdb)  
  
  
.......................................  
  
  
[0x4] Exploit  
....  
  
EOF  
`