หน้าเว็บ

วันพฤหัสบดีที่ 8 สิงหาคม พ.ศ. 2556

In-Depth Analysis: Wordpress Timthumb.php




          สวัสดีครับ วันนี้เนื่องจากว่างหรือเปล่าไม่รู้เลยหาบัคเก่าๆหาอ่านเล่นๆ ไปเจอบัคในตำนานของ Wordpress นั่นคือ TimThumb.php ที่สามารถทำ Remote Code Execution ได้ครับ
          อย่ากระนั้นเลย เกิดความสงสัยว่าทำไมถึงได้มีช่องโหว่ RCE ได้ที่เห็นตามเว็บว่าเจ้า TimThumb.php นี้เจอเยอะใน Plugin/Theme ต่างๆของ Wordpress ผมจึงตามหาไฟล์ที่บัคเพื่อดูและวิเคราะห์โค้ดอย่างละเอียดจึงได้คำตอบมาเขียนได้อีก Topic หนึ่ง ._.
          เริ่มกันเลยดีกว่า TimThumb เป็น Plugin ในการย่อขยายรูปภาพอัตโนมัติ โดยที่ว่าเมื่อ User ทำการ Request ไปที่ Path includes/timthumb.php?src=[path ของรูปภาพ] แล้ว timthumb.php จะทำการสร้างรูปใหม่และไฟล์ cache ไว้ที่ cache/externel_[md5 ของลิงค์ src].php จากที่ดูตอนนี้น่าจะแก้หมดแล้ว ซึ่งบรรทัดที่ทำการรับค่า GET src มาก็คือบรรทัดที่ 40 เก็บไว้ในตัวแปร $src ครับ

$src = get_request ('src', '');

ตัวแปรที่เก็บชื่อไฟล์ที่ถูกสร้างใน cache อยู่ที่บรรทัด 602

$filename = 'external_' . md5 ($src);

ตัวแปรที่เก็บค่าไฟล์และที่อยู่ของไฟล์อยู่ที่บรรทัด 603

$local_filepath = DIRECTORY_CACHE . '/' . $filename . '.' . strtolower ($fileDetails['extension']);

          ส่วนโค้ดที่ใช้เขียนไฟล์ลง cache อยู่ที่บรรทัด 647 เป็นต้นไปครับ โดยมีการเช็คว่ามีฟังก์ชั่น curl_init ทำงานอยู่หรือเปล่าถ้ามีให้ทำงานตั้งแต่ 647 - 673

if (function_exists ('curl_init')) {

 global $fh;

 $fh = fopen ($local_filepath, 'w');
 $ch = curl_init ($src);

 curl_setopt ($ch, CURLOPT_TIMEOUT, CURL_TIMEOUT);
 curl_setopt ($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.5) Gecko/20041107 Firefox/1.0');
 curl_setopt ($ch, CURLOPT_URL, $src);
 curl_setopt ($ch, CURLOPT_RETURNTRANSFER, TRUE);
 curl_setopt ($ch, CURLOPT_HEADER, 0);
 curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
 curl_setopt ($ch, CURLOPT_FILE, $fh);
 curl_setopt ($ch, CURLOPT_WRITEFUNCTION, 'curl_write');

 // error so die
 if (curl_exec ($ch) === FALSE) {
  unlink ($local_filepath);
  touch ($local_filepath);
  display_error ('error reading file ' . $src . ' from remote host: ' . curl_error ($ch));
  }

 curl_close ($ch);
 fclose ($fh);
}

จากบรรทัดที่ 651 มีการเปิดไฟล์ cache ที่จะเขียนด้วยฟังก์ชั่น fopen

$fh = fopen ($local_filepath, 'w');

แล้วใช้ curl ในการ Request ไปหาเว็บเป้าหมายที่มีโค้ดของ php shell ฝังอยู่

curl_setopt ($ch, CURLOPT_URL, $src);

จากนั้นถูกระบุไฟล์ที่จะถูกเขียนตัวแปร $local_filepath ด้วย CURLOPT_FILE ซึ่งเป็น Option ของ cURL นั่นเอง

curl_setopt ($ch, CURLOPT_FILE, $fh);
//The file that the transfer should be written to. The default is STDOUT (the browser window).

บรรทัดต่อมาส่งข้อมูลที่จะเขียนลงไปในฟังก์ชั่น curl_write ที่ทำหน้าที่เขียนไฟล์ดังกล่าวด้วย CURLOPT_WRITEFUNCTION ครับ

curl_setopt ($ch, CURLOPT_WRITEFUNCTION, 'curl_write');
//The internal CURLOPT_WRITEFUNCTION will write the data to the FILE * given with this option, or to stdout if this option hasn't been set.

มาดูฟังก์ชั่น curl_write กันครับ :)

function curl_write ($handle, $data) {

 global $external_data_string, $fh;

 fwrite ($fh, $data);
 $external_data_string .= $data;

 if (strlen ($external_data_string) > MAX_FILE_SIZE) {
  return 0;
 } else {
  return strlen ($data);
 }

}

จะเห็นว่ามีการใช้ fwrite ซึ่งเป็นฟังก์ชั่นเขียนไฟล์ของ php ครับ

fwrite ($fh, $data);

          แต่ถ้าออกนอกเงื่อนไขซึ่งไม่มี curl_init จะทำคำสั่งด้านหลัง else คือเขียนไฟล์ด้วยฟังก์ชั่น file_put_contents

} else {

 if (!$img = file_get_contents ($src)) {
  display_error ('remote file for ' . $src . ' can not be accessed. It is likely that the file permissions are restricted');
 }

 if (file_put_contents ($local_filepath, $img) == FALSE) {
  display_error ('error writing temporary file');
 }

}

          ซึ่งจากโค้ดคือการอ่านไฟล์จาก URL ในตัวแปร $src มาเก็บไว้ในตัวแปร $img แล้วทำการเขียนลงใน Path ที่อยู่ในตัวแปร $local_filepath ด้วยฟังก์ชั่น file_put_contents ครับ
          แต่ช่องโหว่นี้ต้อง GET Request ลิงค์ที่มี malicious code ฝังอยู่แต่เนื้อหาด้านในต้องเป็นรูปภาพเพราะ Timthumb เป็น Plugin ที่ใช้ย่อขนาดของรูปภาพ จบการชำแหละครับ ส่วนวิธีการป้องกันก็ Update ให้เป็น Version ใหม่ครับ,, ICheer_No0M

Ref : timthumb.php 1.27
Ref : Multiple Wordpress Plugin timthumb.php Vulnerabilites
Ref : TimThumb Demo: Part 2 – Images on External Websites

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

โพสต์ความคิดเห็น