แก้ไข GHOST บั๊กร้ายแรงบนระบบลินุกซ์

มีรายงานว่า พบบั๊กร้ายแรงในไลบรารี glibc โดยบริษัท Qualys ผู้ค้นพบให้ชื่อช่องโหว่นี้ว่า GHOST กระทบลินุกซ์

  • RHEL (Red Hat Enterprise Linux) version 5.x, 6.x and 7.x
  • CentOS Linux version 5.x, 6.x & 7.x
  • Ubuntu Linux version 10.04, 12.04 LTS
  • Debian Linux version 7.x
  • Linux Mint version 13.0
  • Fedora Linux version 19 or older
  • SUSE Linux Enterprise 11 and older (also OpenSuse Linux 11 or older versions).
  • Arch Linux glibc version <= 2.18-1

ซึ่งผู้โจมตีอาจใช้ช่องโหว่นี้ในการโจมตีผ่านทางฟังก์ชั่น gethostbyname และ gethostbyname2 ของ glibc

ซึ่งฟังก์ชั่น gethostbyname เป็นฟังก์ชั่นที่ใช้ในการแปลงชื่อ hostname ให้กลายเป็น IP Address ส่วนใหญ่แอพพลิเคชั่นที่ใช้การ initial network จะใช้ฟังก์ชั่นนี้เช่น sshd, exim เป็นต้น

โดยตัวอย่างการโจมตี เช่น ใส่ชื่อ hostname เข้าไปยาวๆ และมี “.” 3 จุดข้างในเช่น

12123132131.32423123234.12133123123.32412312313

ฟังก์ชั่นก็จะไปทำการเช็ค A record แบบ recursive เพื่อให้ได้ IP ออกมา ซึ่งบริษัท Quaylys ผู้พบปัญหานี้ได้ทำการใช้ช่องโหว่นี้ผ่านทางโปรแกรม Exim (mail) จนสามารถรันคำสั่งภายใต้ daemon ที่รันโปรแกรม Exim ได้

การเช็คเบื้องต้นว่ามีความเสี่ยงหรือไม่
สามารถคอมไพล์และรันโค้ดนี้ได้เลยครับ

[c]
/* ghosttest.c: GHOST vulnerability tester */
/* Credit: http://www.openwall.com/lists/oss-security/2015/01/27/9 */
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>

#define CANARY "in_the_coal_mine"

struct {
  char buffer[1024];
  char canary[sizeof(CANARY)];
} temp = { "buffer", CANARY };

int main(void) {
  struct hostent resbuf;
  struct hostent *result;
  int herrno;
  int retval;

  /*** strlen (name) = size_needed – sizeof (*host_addr) –     sizeof (*h_addr_ptrs) – 1; ***/
  size_t len = sizeof(temp.buffer) – 16*sizeof(unsigned char) – 2*sizeof(char *) – 1;
  char name[sizeof(temp.buffer)];
  memset(name, ‘0’, len);
  name[len] = ‘\0’;

  retval = gethostbyname_r(name, &resbuf, temp.buffer, sizeof(temp.buffer), &result, &herrno);

  if (strcmp(temp.canary, CANARY) != 0) {
    puts("vulnerable");
    exit(EXIT_SUCCESS);
  }
  if (retval == ERANGE) {
    puts("not vulnerable");
    exit(EXIT_SUCCESS);
  }
  puts("should not happen");
  exit(EXIT_FAILURE);
}

[/c]

จากนั้นคอมไพล์และรันด้วยคำสั่ง

[shell]

$ gcc ghosttest.c -o ghosttest
$ ./ghosttest

[/shell]

ถ้าระบบไม่มีความเสี่ยงจะได้ผลออกมาว่า

not vulnerable

ถ้าระบบที่มีความเสี่ยงจะได้ผลออกมาว่า

vulnerable

ให้เรารีบทำการ update patch แก้ไขโดยด่วน

วิธีหาว่าแอพพลิเคชั่นที่ทำงานอยู่บนเครื่องตัวไหนใช้งาน glibc บ้าง

ให้พิมพ์คำสั่ง

[shell]

lsof | grep libc | awk ‘{print $1}’ | sort | uniq

[/shell]

อย่างเช่นเครื่องผมเองก็จะเห็นแอพพลิเคชั่นที่ใช้ glibc

[shell]

root@vagrant-ubuntu-trusty-64:~# lsof | grep libc | awk ‘{print $1}’ | sort | uniq
acpid
apache2
atd
automount
awk
bash
control
cpuhotplu
cron
dbus-daem
dhclient
docker.io
getty
grep
in:imklog
in:imuxso
init
lsof
memballoo
puppet
rpcbind
rpc.idmap
rpc.statd
rs:main
rsyslogd
ruby
sort
sshd
su
sudo
systemd-l
systemd-u
timesync
uniq
upstart-f
upstart-s
upstart-u
VBoxServi
vminfo
vmstats

[/shell]

การแก้ไขบน RHEL/CentOS

[shell]

sudo yum clean all

sudo yum update

[/shell]

สุดท้ายก็หาเวลาที่เหมาะสมแล้ว reboot ซะ

[shell]

sudo reboot

[/shell]

การแก้ไขบน Debian/Ubuntu

[shell]
sudo apt-get clean

sudo apt-get update

sudo apt-get dist-upgrade

[/shell]

สุดท้ายก็หาเวลาที่เหมาะสมแล้ว reboot ซะ

[shell]
sudo reboot
[/shell]

ball Written by:

Teerapat Khunpech Live, Tech, Beers, Bike, Cafe Racer, Docker, Devops, Eco-System