Moodle
  1. Moodle
  2. MDL-22388

Reporter says input not properly verified on various form scripts

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Minor 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
    • Rank:
      1300

      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).

        Activity

        Hide
        Helen Foster added a comment -

        Adding VIP watchers.

        Show
        Helen Foster added a comment - Adding VIP watchers.
        Hide
        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
        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
        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
        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
        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
        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
        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
        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
        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
        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
        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
        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
        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
        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
        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
        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
        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
        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
        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
        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
        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
        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
        Penny Leach added a comment -

        I agree with everything Eloy says

        Show
        Penny Leach added a comment - I agree with everything Eloy says
        Hide
        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
        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
        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
        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
        Helen Foster added a comment -

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

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

        Resolving as fixed and guessing the fix version of 1.9.9.

        Show
        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: