หน้าเว็บ

วันอังคารที่ 18 พฤศจิกายน พ.ศ. 2557

In-Depth Analysis: MyBB 1.8.1 <= SQL Injection


          หลังจากที่เขียนบทความวิเคราะห์ช่องโหว่ SQL Injection ของ IP.Board ออกมาไม่นานนักทาง Exploit-DB ได้มีประกาศช่องโหว่ SQL Injection และ Cross-site Scripting ของเว็บบอร์ดสำเร็จรูปชื่อดังอย่าง MyBB หรือ MyBulletinBoard ที่มีผู้ใช้งานเยอะไม่แพ้ IP.Board สำหรับเวอร์ชั่นที่มีช่องโหว่ดังกล่าวคือเวอร์ชั่น 1.8.1 หรือต่ำกว่าครับ
          สำหรับช่องโหว่ระดับรุนแรงคือช่องโหว่ SQL Injection ที่เป็นแบบ Error Based มีคนเขียนโค้ดสำหรับเจาะช่องโหว่นี้เหมือนเอาโค้ดจากช่องโหว่ IP.Board มาดัดแปลงเล็กน้อยเลย สำหรับไฟล์ที่มีช่องโหว่คือไฟล์ member.php ตัวแปร question_id ที่จะเกิดขึ้นตอนสมัครสมาชิกครับ
 if($mybb->settings['securityquestion'])
 {
  $question_id = $mybb->get_input('question_id');
  $answer = $db->escape_string($mybb->get_input('answer'));

  $query = $db->query("
   SELECT q.*, s.sid
   FROM ".TABLE_PREFIX."questionsessions s
   LEFT JOIN ".TABLE_PREFIX."questions q ON (q.qid=s.qid)
   WHERE q.active='1' AND s.sid='{$question_id}'
  ");

          จากโค้ดจะเห็นว่ามีการรับค่า $_GET มาใส่ในตัวแปร question_id ผ่านฟังก์ชั่น get_input จากนั้นจึงนำเข้ามารวมกับคิวรี่ SQL ทดสอบการการโจมตีโดย SELECT COUNT(*) FROM mybb_users โดยอ้างอิงโค้ดจาก exploit


          ทำให้ Hacker สามารถใช้ Regular Expression ตัดคำที่ต้องการออกมาจาก Error ที่เห็นได้ เมื่อตามไปดูโค้ดของฟังก์ชั่นที่ครอบ input ไว้นั่นคือฟังก์ชั่น get_input ที่อยู่ในไฟล์ /inc/class_core.php ครับ
 /**
  * Checks the input data type before usage.
  *
  * @param string $name Variable name ($mybb->input)
  * @param int $type The type of the variable to get. Should be one of MyBB::INPUT_INT, MyBB::INPUT_ARRAY or MyBB::INPUT_STRING.
  *
  * @return mixed Checked data
  */
 function get_input($name, $type = MyBB::INPUT_STRING)
 {
  switch($type)
  {
   case MyBB::INPUT_ARRAY:
    if(!isset($this->input[$name]) || !is_array($this->input[$name]))
    {
     return array();
    }
    return $this->input[$name];
   case MyBB::INPUT_INT:
    if(!isset($this->input[$name]) || !is_numeric($this->input[$name]))
    {
     return 0;
    }
    return (int)$this->input[$name];
   case MyBB::INPUT_FLOAT:
    if(!isset($this->input[$name]) || !is_numeric($this->input[$name]))
    {
     return 0.0;
    }
    return (float)$this->input[$name];
   case MyBB::INPUT_BOOL:
    if(!isset($this->input[$name]) || !is_scalar($this->input[$name]))
    {
     return false;
    }
    return (bool)$this->input[$name];
   default:
    if(!isset($this->input[$name]) || !is_scalar($this->input[$name]))
    {
     return '';
    }
    return $this->input[$name];
  }
 }

          การส่งค่าได้ส่งมาเป็น String และไม่มีการกรองค่าที่รับมาทำให้เกิดช่องโหว่ SQL Injection ได้ครับ ตอนนี้แพตช์เวอร์ชั่น 1.8.2 สำหรับแก้ไขช่องโหว่ SQL Injection และ Cross-site Scripting ได้ออกมาตั้งแต่วันที่ 13 พ.ย. ที่ผ่านมา โดยแก้ช่องโหว่ SQL Injection โดยใช้ฟังก์ชั่น escape_string ครอบเข้าไป
$question_id = $db->escape_string($mybb->get_input('question_id'));

          ตามไปดูฟังก์ชั่น escape_string
 function escape_string($string)
 {
  if($this->db_encoding == 'utf8')
  {
   $string = validate_utf8_string($string, false);
  }
  elseif($this->db_encoding == 'utf8mb4')
  {
   $string = validate_utf8_string($string);
  }

  if(function_exists("mysqli_real_escape_string") && $this->read_link)
  {
   $string = mysqli_real_escape_string($this->read_link, $string);
  }
  else
  {
   $string = addslashes($string);
  }
  return $string;
 }

          มีการครอบ mysqli_real_escape_string เข้าไปแล้ว สำหรับใครที่ใช้ MyBB อยู่ก็อัพเดทกันด้วยนะครับ :)

Ref: MyBB 1.8.X <= 1.8.1 Error based SQL Injection
Ref: MyBB 1.8.X - Multiple Vulnerabilities
Ref: MyBB 1.8.2 Released – Security Release

ไม่มีความคิดเห็น:

แสดงความคิดเห็น