Lucene search
K

fts.find.du.bsd.txt

🗓️ 17 Aug 1999 00:00:00Reported by Packet StormType 
packetstorm
 packetstorm
🔗 packetstormsecurity.com👁 35 Views

Potential bug in 'du' and 'find' may allow remote root exploit in FreeBSD and OpenBSD systems.

Code
`Date: Wed, 12 May 1999 14:32:42 +0400  
From: Stas Kisel <[email protected]>  
To: [email protected]  
Subject: fts, du, find  
  
Hi.  
  
I use FreeBSD-2.2.8 and FreeBSD-2.2.7 and I know that these versions are  
no longer supported, but:  
1. There are many people still using 2.2  
2. This bug probably applies to FreeBSD-3.1 and ever to OpenBSD and other.  
  
Approximately a month ago I've found a very strange behaviour of 'du'  
with long direstory structures. I left this alone due to lack of time,  
but some days ago I saw an article on bugtraq concerning similar  
behaviour of 'find'.  
  
There is a one bug in libc causing this behaviour. I have a patch, but  
I did not tested it much ;)  
  
Both 'find' and 'du' use 'fts' (fts_read,...) functions to traverse  
directory structure.  
fts uses realloc() to reallocate memory in quite complex lists.  
There is a bug in adjusting pointers after realloc().  
So when dealing with large directory structures (when realloc() needed),  
some pointers can point to free()-ed memory.  
  
I have no exploit and probably will no have a free time (I think  
3 days is more than enough) for doing it, but I beleive it is  
possible to exploit this bug using carefully designed directory  
tree to execute arbitrary commands as root during  
/etc/daily->/etc/security->find.  
REMOTE ROOT EXPLOIT (POSSIBLE).  
At least it is possible to hide setuid binary this way in home dir or in /tmp.  
  
The following patch is designed for FreeBSD-2.2.8-RELEASE libc.  
There was the following ID in the beginning of the source file.  
/* $OpenBSD: fts.c,v 1.9 1997/08/02 00:13:49 millert Exp $ */  
I've only tested this patch on one machine during one day, so  
it is probably buggy.  
If you'll apply this patch, please drop me a line if there was any side effect  
and I'll do a followup in the bugtraq, say, on the Friday.  
  
------------------ patch ----------------------------------------  
--- /usr/src/lib/libc/gen/fts.c.orig Tue May 11 13:37:49 1999  
+++ /usr/src/lib/libc/gen/fts.c Wed May 12 13:16:08 1999  
@@ -740,8 +740,26 @@  
* If had to realloc the path, adjust the addresses for the rest  
* of the tree.  
*/  
- if (adjaddr)  
+ if (adjaddr){  
fts_padjust(sp, adjaddr);  
+ /* Adjust the list, because we want to return it robust. */  
+/* fix p->fts_path and p->fts_accpath  
+ p->fts_accpath can be:  
+ either cur->fts_path (adjust, because cur is already adjusted)  
+ either p->fts_path (adjust)  
+ either p->fts_name (do not adjust)  
+ I'm also almost sure that in first case cur->fts_path=p->fts_path...  
+*/  
+#define ADJUST1(p) if((p)->fts_path != adjaddr){ \  
+ if((p)->fts_accpath != (p)->fts_name){ \  
+ (p)->fts_accpath = \  
+ (char *)adjaddr + ((p)->fts_accpath - (p)->fts_path);\  
+ } \  
+ (p)->fts_path = adjaddr; \  
+}  
+ for (p = head; p; p = p->fts_link)  
+ ADJUST1(p);  
+ }  
  
/*  
* If not changing directories, reset the path back to original  
@@ -974,18 +992,18 @@  
{  
FTSENT *p;  
  
-#define ADJUST(p) { \  
+#define ADJUST2(p) { \  
(p)->fts_accpath = \  
(char *)addr + ((p)->fts_accpath - (p)->fts_path); \  
(p)->fts_path = addr; \  
}  
/* Adjust the current set of children. */  
for (p = sp->fts_child; p; p = p->fts_link)  
- ADJUST(p);  
+ ADJUST2(p);  
  
/* Adjust the rest of the tree. */  
for (p = sp->fts_cur; p->fts_level >= FTS_ROOTLEVEL;) {  
- ADJUST(p);  
+ ADJUST2(p);  
p = p->fts_link ? p->fts_link : p->fts_parent;  
}  
}  
------------------ endpatch ----------------------------------------  
  
--  
Stas Kisel  
Open Tavrical College Sysadmin [email protected]  
Simferopol State University Web-designer [email protected]  
  
------------------------------------------------------------------------------------------  
  
Date: Fri, 14 May 1999 04:33:34 -0400  
From: Jordan Ritter <[email protected]>  
To: [email protected]  
Subject: Re: fts, du, find  
  
On Wed, 12 May 1999, Stas Kisel wrote:  
  
> 2. This bug probably applies to FreeBSD-3.1 and ever to OpenBSD and other.  
  
I found this back a few months ago when working on the wu-ftp stuff..  
OpenBSD definitely has the same problem. last thing I remember thinking  
was that it was dying because realloc() was failing (as the fts stuff  
realloc()'s memory as the path grows) ..  
  
  
  
Jordan Ritter  
Network Security Engineer  
Netect/Bindview Corp Boston, MA  
  
"Quis custodiet ipsos custodes?"  
  
------------------------------------------------------------------------------------------  
  
Date: Fri, 14 May 1999 14:37:03 +0400  
From: Stas Kisel <[email protected]>  
To: [email protected]  
Subject: Re: fts...(improved patch)  
  
> From: Jordan Ritter <[email protected]>  
> OpenBSD definitely has the same problem. last thing I remember thinking  
> was that it was dying because realloc() was failing (as the fts stuff  
> realloc()'s memory as the path grows) ..  
  
fts realloc (pathlen+~1000b) of memory only, so realloc succeds.  
The bug is in the adjusting pointers after realloc().  
  
Next day after sending patch I've found another circumstanses that  
triggered similar bug in fts.  
This time some pointers were adjusted which did not belong to realloc()-ed  
memory chunk.  
  
Improved patch is below. Sorry for inconvenience.  
Probably there are some similar bugs in fts code or patch. Please let me  
know if you'll see any.  
  
\bye  
Stas  
  
----------------------------- patch ----------------------------------  
--- /usr/src/lib/libc/gen/fts.c.orig Tue May 11 13:37:49 1999  
+++ /usr/src/lib/libc/gen/fts.c Fri May 14 14:02:58 1999  
@@ -740,8 +740,26 @@  
* If had to realloc the path, adjust the addresses for the rest  
* of the tree.  
*/  
- if (adjaddr)  
+ if (adjaddr){  
fts_padjust(sp, adjaddr);  
+ /* Adjust the list, because we want to return it robust. */  
+/* fix p->fts_path and p->fts_accpath  
+ p->fts_accpath can be:  
+ either cur->fts_path (adjust, because cur is already adjusted)  
+ either p->fts_path (adjust)  
+ either p->fts_name (do not adjust)  
+ I'm also almost sure that in first case cur->fts_path=p->fts_path...  
+*/  
+#define ADJUST1(p) if((p)->fts_path != adjaddr){ \  
+ if((p)->fts_accpath != (p)->fts_name){ \  
+ (p)->fts_accpath = \  
+ (char *)adjaddr + ((p)->fts_accpath - (p)->fts_path);\  
+ } \  
+ (p)->fts_path = adjaddr; \  
+}  
+ for (p = head; p; p = p->fts_link)  
+ ADJUST1(p);  
+ }  
  
/*  
* If not changing directories, reset the path back to original  
@@ -974,18 +992,20 @@  
{  
FTSENT *p;  
  
-#define ADJUST(p) { \  
- (p)->fts_accpath = \  
- (char *)addr + ((p)->fts_accpath - (p)->fts_path); \  
+#define ADJUST2(p) { \  
+ if((p)->fts_accpath != (p)->fts_name){ \  
+ (p)->fts_accpath = \  
+ (char *)addr + ((p)->fts_accpath - (p)->fts_path); \  
+ } \  
(p)->fts_path = addr; \  
}  
/* Adjust the current set of children. */  
for (p = sp->fts_child; p; p = p->fts_link)  
- ADJUST(p);  
+ ADJUST2(p);  
  
/* Adjust the rest of the tree. */  
for (p = sp->fts_cur; p->fts_level >= FTS_ROOTLEVEL;) {  
- ADJUST(p);  
+ ADJUST2(p);  
p = p->fts_link ? p->fts_link : p->fts_parent;  
}  
}  
----------------------------- /patch ----------------------------------  
  
------------------------------------------------------------------------------------------  
  
Date: Fri, 14 May 1999 19:14:02 +0200  
From: Przemyslaw Frasunek <[email protected]>  
Reply-To: [email protected]  
To: [email protected]  
Subject: Re: fts, du, find  
  
> 2. This bug probably applies to FreeBSD-3.1 and ever to OpenBSD and other.  
  
Yes, I've tested it on 3.1-STABLE.  
  
> I have no exploit and probably will no have a free time (I think  
> 3 days is more than enough) for doing it, but I beleive it is  
> possible to exploit this bug using carefully designed directory  
> tree to execute arbitrary commands as root during  
> /etc/daily->/etc/security->find.  
> REMOTE ROOT EXPLOIT (POSSIBLE).  
  
I think, that it will be hard to write an exploit. I've tested it on  
my 2.2.8-RELEASE at home.  
  
'Find' segfaults, when it tries to do:  
  
(void)puts(entry->fts_path);  
  
because of junk pointer to structure 'entry'. IMHO it _always_  
points to 0x200291d6, so it tries to execute (IMHO) _always_ the  
same commands:  
  
0x200291d6 <puts+34>: repnz scasb %es:(%edi),%al  
0x200291d7 <puts+35>: scasb %es:(%edi),%al  
0x200291d8 <puts+36>: movl %ecx,%eax  
0x200291d9 <puts+37>: enter $0xd0f7,$0x89  
0x200291da <puts+38>: notl %eax  
0x200291db <puts+39>: rorb 0x488de455(%ecx)  
0x200291dc <puts+40>: movl %edx,0xffffffe4(%ebp)  
0x200291dd <puts+41>: pushl %ebp  
0x200291de <puts+42>: inb $0x8d,%al  
0x200291df <puts+43>: leal 0xffffffff(%eax),%ecx  
0x200291e0 <puts+44>: decl %eax  
0x200291e1 <puts+45>: decl 0x938de84d(%ecx)  
0x200291e2 <puts+46>: movl %ecx,0xffffffe8(%ebp)  
0x200291e3 <puts+47>: decl %ebp  
0x200291e4 <puts+48>: call 0xc1532576 <end+2705991902>  
  
and here it segfaults.  
  
--  
* Fido: 2:480/124 ** WWW: lagoon.freebsd.org.pl/~venglin ** GSM:48-601-383657 *  
* Inet: [email protected] ** PGP:D48684904685DF43EA93AFA13BE170BF *  
  
`

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation