Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Manually patching for Ghost vulnerability on legacy server

I have a legacy Redhat ES 3.x server (that I cannot put a later distro on due to limitations in an ancient, unsupported application) and I am trying to manually patch glibc on it for the Ghost vulnerability.

Based on the analysis by Qualys (http://www.openwall.com/lists/oss-security/2015/01/27/9), it appears that it should be easy to modify the glib source to handle the stack/heap overflow issue. But I would like to have a few more eyes on my procedure to see if I missed something, etc.

Here is what I have done. First I built & prepped the glib source tree from the SRPM:

rpm -ivh glibc-2.3.2-95.50.src.rpm
rpmbuild -bp /usr/src/redhat/SPECS/glibc.spec 
cd /usr/src/redhat/BUILD
cp -av glibc-2.3.2-200309260658 glibc-org
cd glibc-2.3.2-200309260658

Next, I edited nss/digits_dots.c mainly based on this paragraph from the Qalys article above:

Lines 121-125 prepare pointers to store four (4) distinct entities in buffer: host_addr, h_addr_ptrs, h_alias_ptr, and hostname. The sizeof (*h_alias_ptr) -- the size of a char pointer -- is missing from the computation of size_needed.

vi nss/digits_dots.c

I edited these two statements:
  105:  size_needed = (sizeof (*host_addr)
                   + sizeof (*h_addr_ptrs) + strlen (name) + 1);

  277:  size_needed = (sizeof (*host_addr)
                   + sizeof (*h_addr_ptrs) + strlen (name) + 1);

to this:
  105:  size_needed = (sizeof (*host_addr)
                   + sizeof (*h_addr_ptrs) + strlen (name)
                   + sizeof (*h_alias_ptr) + 1);

  277:  size_needed = (sizeof (*host_addr)
                       + sizeof (*h_addr_ptrs) + strlen (name)
                       + sizeof (*h_alias_ptr) + 1);                     

Next, I created a patch file + updated the spec file to include my patch + built binaries:

cd /usr/src/redhat/BUILD
diff -Npru glibc-org glibc-2.3.2-200309260658 > glibc-digit_dots-ghost.patch
cp glibc-digit_dots-ghost.patch ../SOURCES/

cd /usr/src/redhat/SPECS
vi glibc.spec
rpmbuild -ba glibc.spec

Lastly, I updated glibc using the new binaries (RPM):

cd /usr/src/redhat/RPMS/i386
rpm -Uvh --nodeps glibc-2.3.2-95.51.i386.rpm glibc-devel-2.3.2-95.51.i386.rpm glibc-profile-2.3.2-95.51.i386.rpm glibc-utils-2.3.2-95.51.i386.rpm glibc-common-2.3.2-95.51.i386.rpm glibc-headers-2.3.2-95.51.i386.rpm 

After restarting the server, I re-ran the ghost tester (https://webshare.uchicago.edu/orgs/ITServices/itsec/Downloads/GHOST.c).

This time I got "should not happen" instead of "vulnerable", which I guess is good. But I had expected to get "not vulnerable" Did I miss something, or is it just that my fix is different from the official fix in the supported distros?

like image 403
Jim Balo Avatar asked Oct 19 '22 18:10

Jim Balo


1 Answers

I've been searching for similar patch for old Fedora release... I found this Q&A over at ServerFault which is about patching older Debian Lenny:

https://serverfault.com/questions/662971/how-to-patch-cve-2015-0235-ghost-on-debian-lenny-and-squeeze

In one of the answers, they link to official glibc patch which the diff shows a few additional edits other than yours. It's probably the missing *status = NSS_STATUS_NOTFOUND; that is getting into the "should not happen" state.

Hope that helps! (sorry don't have enough Rep points to upvote your question...)

like image 196
jason_uruguru Avatar answered Oct 24 '22 03:10

jason_uruguru