Well, there's more that one way to skin a cat. Below is how I skinned it.
#! /bin/sh
EXE_DIRECTORIES="/bin /sbin /usr/bin /usr/local/bin"
SO_DIRECTORIES="/lib /lib64 /usr/local/lib"
FILES=
VULNERABLE=
echo "Generating file list..."
for d in $EXE_DIRECTORIES ; do
TEMP=`find "$d" -type f -executable -exec file -i '{}' \; | grep 'x-executable; charset=binary' | cut -f 1 -d:`
for t in "$TEMP" ; do
FILES="$FILES $t"
done
done
for d in $SO_DIRECTORIES ; do
TEMP=`find "$d" -type f -executable -exec file -i '{}' \; | grep 'x-executable; charset=binary' | cut -f 1 -d:`
for t in "$TEMP" ; do
FILES="$FILES $t"
done
done
echo "Testing executables..."
for f in $FILES ; do
COUNT=`nm -D "$f" 2>/dev/null | grep gethostbyname | grep -c -w U`
if [ "$COUNT" -ne 0 ]; then
VULNERABLE="$VULNERABLE $f"
fi
done
COUNT1=`echo "$FILES" | wc -l`
COUNT2=`echo "$VULNERABLE" | grep -o " " | wc -l`
if [ "$COUNT2" -ne 0 ]; then
COUNT2=$(( $COUNT2 + 1 ))
fi
echo "Examined components: $COUNT1"
echo "Vulnerable components: $COUNT2"
echo "*****************************"
for v in $VULNERABLE ; do
echo "$v"
done
On a typical Ubuntu 14 development system, here's what I am getting:
$ ./glibc-check.sh
Generating file list...
Testing executables...
Examined components: 961
Vulnerable components: 32
*****************************
/bin/ss
/bin/hostname
/bin/tar
/bin/cpio
/bin/netstat
/bin/ping
/bin/mt-gnu
/sbin/agetty
/sbin/route
/sbin/rarp
/sbin/ifconfig
/sbin/getty
/usr/bin/logger
/usr/bin/git-upload-pack
/usr/bin/aseqnet
/usr/bin/git
/usr/bin/telnet.netkit
/usr/bin/getent
/usr/bin/mtr
/usr/bin/mtools
/usr/bin/gethostip
/usr/bin/gdb
/usr/bin/tracepath
/usr/bin/python3.4m
/usr/bin/python2.7
/usr/bin/arping
/usr/bin/python3.4
/usr/bin/traceroute6.iputils
/usr/bin/openssl
/usr/bin/git-shell
/usr/bin/rsync
But its only a subset of the 19000+ packages that depend on libc6 (its only the installed packages; and its only components in well known locations):
$ apt-cache rdepends libc6 | wc -l
19125
1Almost all programs use
libc
, although they don't necessarily use the vulnerable functiongethostbyname()
. – Barmar – 2015-01-28T21:44:48.227@Barmar - yes, agreed. But I'm only interested in what is installed and vulnerable. – jww – 2015-01-28T22:33:43.397
So you want all the programs that use the vulnerable libc, or that use the broken function? – Barmar – 2015-01-28T22:45:56.233
1A program could be vulnerable indirectly. It might use some other library that in turn uses
gethostbyname
. What's the point of this exercise? – Barmar – 2015-01-28T22:46:40.560@Barmar - the point of the exercise is to evaluate the risk to a system. If no programs use the vulnerable functions, then there's no incumbent risk. If some programs use the vulnerable functions, then I need to know which ones so I can evaluate risk. If the risk is too great, then I might have to shut down forward facing services. If no forward facing services use the function, then I might be OK. – jww – 2015-01-28T22:49:03.523
1The vulnerable function is the one that translates hostnames to IP addresses, so most programs that deal with the network use it. But they're only really vulnerable if they get the hostnames from untrusted sources. This is not something that can be determined by scanning the system, you need to understand the nature of each application. – Barmar – 2015-01-28T23:01:25.740
@Barmar - thanks. "... you need to understand the nature of each application" - And how do I get the list of applications so I can evaluate them? – jww – 2015-01-28T23:07:28.397
Maybe you can use
nm
on every program that useslibc
, and see if it referencesgethostbyname
. But like I said, that won't find programs that use some other library that uses this function. – Barmar – 2015-01-28T23:09:25.590