pear.php.net gehackt - was nun?

Posted by jonas on Wednesday, January 23, 2019

Ein Hinweis von dictvm auf einen Blogpost bei The Hacker News hat uns aufhorchen lassen:

Beware! If you have downloaded PHP PEAR package manager from its official website in past 6 months, we are sorry to say that your server might have been compromised.

tl;dr: Der auf pear.php.net bereitgestellte Installer go-pear.phar ist seit rund 6 Monaten kompromittiert. Wenn du den von uns bereitgestellten PEAR-Paketmanager verwendet hast, gibt es - nach derzeitigem Kenntnisstand - insofern keinen Anlass zur Sorge. Solltest du in den letzten 6 Monaten PEAR selbst über go-pear.phar installiert haben, hast du vermutlich eine kompromittierte Version erwischt und solltest jene dringend gegen eine neue, saubere Version austauschen.

Nun ist die Faktenlage zum derzeitigen Zeitpunkt noch recht dünn, denn pear.php.net ist derzeit down und enthält lediglich eine Hinweisseite auf den Einbruch. Allerdings wurde nach derzeitigem Kenntnisstand nur eine einzige Datei kompromittiert, nämlich der in Form eines PHP-Archivs (phar) bereitgestellte PEAR-Installer. Den benötigt man nur, wenn man noch gar kein PEAR hat (sollte schon eine PEAR-Version vorhanden sein, kann man neuere Versionen mit PEAR selbst installieren). So besagt die Meldung:

If you have downloaded this go-pear.phar in the past six months, you should get a new copy of the same release version from GitHub (pear/pearweb_phars) and compare file hashes. If different, you may have the infected file.

Davon ausgehend, dass keine weiteren Dateien kompromittiert wurden, haben wir insofern untersucht, ob uns dieses Problem betrifft.

Uberspace 6 (U6)

Für U6-Hosts kompilieren wir PHP selbst, direkt aus den offiziellen Sourcen. Die beinhalten kein PEAR - aber dennoch hat man am Ende neben PHP selbst auch einen funktionierenden PEAR-Paketmanager. Wie kommt das?

Nun, das Makefile aus dem PHP-Source hat als eines seiner Install-Targets install-pear, also schauen wir mal, was das tut:

        @echo "Installing PEAR environment:      $(INSTALL_ROOT)$(peardir)/"
        @if test ! -f pear/install-pear-nozlib.phar; then \
                if test -f /home/builduser/php-7.2.14/pear/install-pear-nozlib.phar; then \
                        cp /home/builduser/php-7.2.14/pear/install-pear-nozlib.phar pear/install-pear-nozlib.phar; \
                else \
                        if test ! -z "$(WGET)" && test -x "$(WGET)"; then \
                                "$(WGET)" "${PEAR_INSTALLER_URL}" -nd -P pear/; \
                        elif test ! -z "$(FETCH)" && test -x "$(FETCH)"; then \
                                "$(FETCH)" -o pear/ "${PEAR_INSTALLER_URL}"; \
                        else \
                                $(top_builddir)/sapi/cli/php -n /home/builduser/php-7.2.14/pear/fetch.php "${PEAR_INSTALLER_URL}" pear/install-pear-nozlib.phar; \
                        fi \
                fi \
        fi
        @if test -f pear/install-pear-nozlib.phar && $(mkinstalldirs) $(INSTALL_ROOT)$(peardir); then \
                $(MAKE) -s install-pear-installer; \
        else \
                cat /home/builduser/php-7.2.14/pear/install-pear.txt; \
        fi

Aha: Wenn es die Datei install-pear-nozlib.phar nicht im Source-Tree vorfindet, dann lädt es sie automatisch herunter, und zwar… tja, von pear.php.net, denn etwas weiter oben ist definiert, wo man’s herbekommt:

PEAR_INSTALLER_URL = https://pear.php.net/install-pear-nozlib.phar

Das ist insofern schlecht, weil die Datei von einem Host gezogen wird, der als kompromittiert bekannt ist. Wenn sich allerdings, wovon wir nach aktuellem Stand der Dinge ausgehen müssen, die Kompromittierung wirklich nur auf die go-pear.phar bezieht: Dann ist hier an dieser Stelle dankenswerterweise nichts passiert.

Uberspace 7 (U7)

Auf U7 setzen wir die PHP-Software-Collection-Pakete von Remi’s RPM repository ein, also galt es, zu prüfen, wie dessen PEAR-Paket entstanden ist.

Remi ist im März 2017 von GitHub weggezogen und hostet die Git-Repos, in denen unter anderem die Specfiles für seine RPM-Pakete liegen, nun selbst. Dazu gehört auch das Specfile für PEAR. Hier ist vor allem der Blick auf die Sourcen und Patches interessant:

Source0: http://download.pear.php.net/package/PEAR-%{version}%{?pearprever}.tgz
# wget https://raw.githubusercontent.com/pear/pear-core/stable/install-pear.php
Source1: install-pear.php
Source3: cleanup.php
Source10: pear.sh
Source11: pecl.sh
Source12: peardev.sh
Source13: macros.pear
Source14: macros-f24.pear
Source21: http://pear.php.net/get/Archive_Tar-%{arctarver}.tgz
Source22: http://pear.php.net/get/Console_Getopt-%{getoptver}.tgz
Source23: http://pear.php.net/get/Structures_Graph-%{structver}.tgz
Source24: http://pear.php.net/get/XML_Util-%{xmlutil}.tgz
Source25: http://pear.php.net/get/PEAR_Manpages-%{manpages}.tgz

Patch0:   https://patch-diff.githubusercontent.com/raw/pear/pear-core/pull/83.patch

PEAR selbst sowie einige zwingend benötigte PEAR-Module werden von pear.php.net bezogen; auch hier wird allerdings nicht der Installer go-pear.phar verwendet, sondern vielmehr der PEAR-Tarball selbst heruntergeladen und mittels der install-pear.php installiert.

Eigene Installationen

Wenn du dir auf eigene Faust innerhalb der letzten 6 Monate PEAR installiert hast, in dem du der offiziellen Anleitung gefolgt bist und go-pear.phar verwendet hast, solltest du der Empfehlung des PEAR-Teams folgen und dir eine frische Version der go-pear.phar vom GitHub-Account von PEAR ziehen.

Ausblick

Du solltest in jedem Fall - genau wie wir - https://pear.php.net/ aufmerksam beobachten; ein Blogpost mit mehr Informationen ist dort angekündigt, aber noch nicht verfügbar. Der Blogpost, den du gerade liest, stützt sich auf die zum Zeitpunkt seiner Veröffentlichung (23.01.2019) veröffentlichen Informationen.