Auf heise.de habe ich am Tag nach dem Bemerken des Einbruchs (Bemerkt am: 01.12.2010) gelesen, das die offiziellen ProFTPD FTP Quellen seit dem 28.11.2010 mit einem Backdoor verseucht seien. Laut heise online soll die Infektion des Quellcodes über eine ungepatchte Sicherheitslücke Lücke im SQL-Modul in ProFTPD selbst verseucht worden seien. Was für eine Ironie. 🙂

Ich wusste mein Server ist nicht infiziert da ich mein System aus den Debian Paketquellen pflege und in darin niemals derart aktuelle Pakete enthalten sind. Dennoch wollte ich mehr darüber wissen. Auf der ProFTPD Projektseite fand ich eine News Meldung.

The ProFTPD Project team is sorry to announce that the Project’s main FTP server, as well as all of the mirror servers, have carried compromised versions of the ProFTPD 1.3.3c source code, from the November 28 2010 to December 2 2010. All users who run versions of ProFTPD which have been downloaded and compiled in this time window are strongly advised to check their systems for security compromises and install unmodified versions of ProFTPD.

To verify the integrity of your source files, use the PGP signatures which can be found here as well as on the FTP servers.

The source code in CVS was not affected.

CVS Benutzer müssen sich laut ProFTPD Team eigenen Angaben keine Sorgen machen. Anwender die die FTP Quellen benutzt haben sollten prüfen ob deine heruntergeladene Versionen des ProFTPD Quellcodes gültige PGP Signaturen aufweisen. (ProFTPD PGP Signaturen)

ProFTPD sollte normalerweise nicht als Prozess des Benuters root laufen. In wie weit das für den root Zugang über den Backdoor eine Rolle spielt weiß ich nicht. In kombination mit einem verwundbaren Kernel durch das „privilege escalation“ Exploit der selben Gruppe wäre dies kein Hindernis. Mehr dazu hier.

Um das Aufspüren von infizierten Servern zu erleichtern habe ich ein Scanner Script „verfasst“. Wie du an der Shebang und der Syntax erkennst handelt es sich um ein Ruby Script.

#! /usr/bin/ruby -w
 
require 'net/ftp'
require 'timeout'
 
##
## Validate and split IP address 
##
def explodeip(ip)	
	if 5 == len = (ip = ip.match('^(d{1,3}).(d{1,3}).(d{1,3}).(d{1,3})$').to_a).length
		i = 1		
		4.times do
			ip[i] = ip[i].to_i()
			i = i + 1
		end
		return ip
	else
		return false
	end
end
 
##
## Check FTP host for infection
##
def checkinfect(ip)
	begin
		timeout(3) do
     		ftp = Net::FTP.new(ip)
			puts ip+': connected'
			begin
				ftp.sendcmd('help ACIDBITCHEZ')				
				puts ip+': infected'
			rescue Net::FTPPermError
				puts ip+': clean'
			ensure
				ftp.close()
			end
		end		
	rescue Timeout::Error
		puts ip+': timeout'
	rescue Errno::ECONNREFUSED
		puts ip+': connection refused'
	rescue Errno::EHOSTUNREACH
		## Maybe you wan't to google?
	end	
end
 
##
## Script info
##
if !ARGV[0].is_a?(String)
	puts '# ACIDBITCHEZ ProFTPD backdoor scanner'
	puts '# Usage: ./ACIDBITCHEZ_ftpscanner <ip adress> || <start ip> <end ip>'
	puts '# More: http://www.monkey-business.biz/1211/proftpd-acidbitchez-backdoor-scanner/'	
	Process.exit()
end
 
if ip1 = explodeip(ARGV[0])
	if ARGV[1].is_a?(String)
 
		##
		## Cycle trough IP's
		##
		if ip2 = explodeip(ARGV[1])
			while ip1[1] <= ip2[1]
				while ip1[2] <= ip2[2]								
					while ip1[3] <= ip2[3]					
						while ip1[4] <= ip2[4]							
							checkinfect(ip1[1].to_s()+'.'+ip1[2].to_s()+'.'+ip1[3].to_s()+'.'+ip1[4].to_s())
							ip1[4] = ip1[4] + 1
						end
						ip1[4] = 0
						ip1[3] = ip1[3] + 1							
					end
					ip1[3] = 0
					ip1[2] = ip1[2] + 1
				end
				ip1[2] = 0
				ip1[1] = ip1[1] + 1
			end
		else			
			puts '# Second IP adress not valid'
		end
 
	##
	## Check single IP
	##
	else
		checkinfect(ip1[0])	
	end
else
	puts '# IP adress not valid'
end

Das Script läuft nicht ansynchron / in Threads. Zusätzlich wird auch versucht IP Adressen zu scannen die nicht existieren können. Dadurch ist das Script sehr ineffizient. Das liegt daran das du damit nicht das ganze Internet scannen sollst. 😉

Mehr zum Thema:

Keine Kommentare »
 

Dinge die jeder an den Linux Distributionen liebt. Man benötig ein Programm und wie soll es auch anders sein, es funktioniert ohne Gebastel nicht. Der Installationsversuch des Frostwire Paketes von frostwire.com bringt folgendes zu tage:

dpkg: Fehler beim Bearbeiten von frostwire-4.21.1.i586.deb (--install):
Paket-Architektur (i386) passt nicht zum System (amd64)

Was für ein Glück das ich Java schon installiert hatte. 🙂
Das deb Paket auf der Webseite ist leider nicht für AMD64 „verpackt“. Die Prozessor Architektur spielt jedoch keine Rolle da Frostwire ein Java Programm ist. Die kurze Zeile

dpkg -i --force-architecture <PAKETNAME>.i586.deb

sollte das Problem lösen und den P2P Client installieren.

Keine Kommentare »
 

Das Beenden bzw. killen von Prozessen unter Linux / Unixoiden Systemen erfolgt in der Regel über das kill-Kommando in der Konsole. Bevor dieses Kommando zum „killen“ des Prozessen benutzbar ist muss jedoch die Prozess ID ermittelt werden. Für das ermitteln der Prozess ID empfehle ich die Konsolen-Kommando Kombination:

ps aux | grep <PROZESSNAME>

<PROZESSNAME> ist mit dem Prozess Name zu ersetzen. Beispielsweise „apache“. Das „apache“ Beispiel beschert mir auf einem Server diese Ausgabe:

www-data 18148  0.0  0.1 232000  8664 ?        S    Nov18   0:00 /usr/sbin/apache2 -k start
www-data 18158  0.0  0.1 232000  8688 ?        S    Nov18   0:00 /usr/sbin/apache2 -k start

Es ist auch möglich, sofern der genaue Prozessename bekannt ist, das Kommando „pidof“ zu nutzen.

pidof <PROZESSNAME>

Der Output zu diesem Befehl enthält die Prozess ID’s oder die Prozess ID je nach Anzahl der laufenden Prozesse mit dem selben Namen.

8664 8688

Der zweite Schritt ist das eigentliche Beenden des Prozesses mit Hilfe des Kommandos kill.

kill <PROZESSID> <PROZESSID>

Prozess ID’s können mit einem Leerzeichen separiert angegeben werden. Sollte sich auf diesem Wege ein Prozess nicht beenden lassen kann mit der Option „-9“ des Befehls kill entgegen gewirkt werden.

kill -9 <PROZESSID>

In diesem Fall wird der Prozess „hart“ beendet. Es können ebenfalls mehrere ID’s mit einem Leerzeichen separiert werden.
Eine andere Art mehrere Prozesse auf einen Streich zu terminieren stellt der Befehl killall da.

killall -i <PROZESSNAME>

Der Parameter „-i“ sorgt dafür das vor dem Beenden jedes Prozesses nochmals nachgefragt wird ob man ihn wirklich beenden möchte. Weitere wichtige Optionen sind die Befehle:

  • -u <UNIXUSERID> beendet die Prozesse des gewählen UNIX Benutzers
  • -g <PROZESSGRUPPENID> beendet die Prozesse der gewählten Prozessgruppe

Die Möglichkeit mehrere Prozesse mit einem Befehl zu beenden hat mir persönlich oft weitergeholfen als Server Dienste am spinnen waren. Schönes Wochenende. 😉

EDIT: Beachte das du zum killen einiger Prozesse als root angemeldet sein musst.

Keine Kommentare »
 

Nach langer Blog Abstinenz werde ich ein weniger technisches Thema Ansprechen, das genutzt werden kann um seine Privatsphäre zu schützen. Das unterdrücken der eigenen Rufnummer mit Hilfe einer Vorwahl und die Möglichkeit über den Anbieter Fonic Prepaid Sim Karten einfach und schnell unter anderem Namen zu registrieren um anonyme Telefonate zu ermöglichen.

Überwachung ist in der heutigen Zeit an all gegenwärtiges Thema. Jedes Telefonat, jeder Schritt eines Menschen kann verfolgt werden. Bei Anrufen wird oft auch ungewollt die eigene Telefonnummer hinterlassen. Ärgerlich ist es, wenn es sich dabei um eine Nummer handelt auf der man nicht erreichbar sein möchte.

Viele Telefone bieten die Möglichkeit die Rufnummer zu unterdrücken. Auf alle Telefone trifft das leider nicht zu. Solltest du mal in die Lage versetzt sein einen Anruf ohne Weitergabe der Telefonnummer zu tätigen reicht es vor die gewünschte Nummer ein #31# zu setzen. Diese kurze Vorwahl erlaubt es die Telefonnummer zu unterdrücken. Das heißt für den Angerufenen ist es nicht möglich die Nummer des Anrufers ohne Hilfe des Providers zu ermitteln.

Auch wirklich anonymes telefonieren ist möglich. Hierzu ist eine Fonic Prepaid Sim Karte sehr gut geeignet. Zu kaufen gibt es diese bei verschiedenen Handelspartnern. Freischalten kann man sich die Karte online. Die Freischaltung der Karte sollte man vom Bar bezahlten Internetkaffee aus oder über einen entsprechenden Anonymisierungsdienst wie Tor erledigen. Während des Freischaltungsprozesses kann eine beliebige Anschrift für den Kartenbesitzer gewählt werden. Die Adresse sollte exisiteren. Eine weitere Rückprüfung findet jedoch nicht statt. Nach Abschluss des Vorgangs verfügt man über eine Sim Karte die auf einen anderen Namen gemeldet ist. Im internen Bereich der Fonic Webseite ist es möglich das Speichern der Verbindungsdaten auf einen sehr kurzen Zeitraum zu beschränken. Paranoide Menschen sollten diese Option ebenfalls nutzen.

Es sollte nicht vergessen werden die Karte nicht wieder in das alte Handy einzulegen. Tut man dies doch, könnte eine Spur zum wirklichen Besitzer entstehen da jedes Handy ebenfalls über eine eindeutige Kennung verfügt die sich IMEI nennt. Es ist also ratsam sich auch ein neues Handy zuzulegen. Das Guthaben der auf einen anderen Namen freigeschalteten Prepaid Sim Karte sollte nicht über das eigene Bankkonto aufgeladen werden. Sondern immer mit Bargeld bei den Fonic Handelpartnern.

Kommt jetzt nicht auf dumme Ideen. Der Artikel soll niemandem eine Hilfestellung zu einer Straftat geben.

Keine Kommentare »
 

Nach längerer Blog Pause schreibe ich über die Implementierung eines Datei Upload mittels POST nach dem RFC1867. Das Vorgehen beim Datei Upload auf der Server Seite wird im Netz oft publiziert. Eine Beschreibung eines Upload Vorgang von der Client Seite aus findet jedoch wenig Verbreitung im Netz. Ich versuche meine Beschreibung möglichst allgemein zu halten. Desweiteren weiß ich das von der hier verwendeten Programmiersprache Ruby kaum Unterschiede zu Perl oder PHP bestehen. Alle genannten Sprachen bieten HTTP Client Funktionalitäten. Folgend ein Script und die Vorgehensweise nach RFC1867 im Detail.

#! /usr/bin/ruby
 
## HTTP Klasse einbinden
require 'net/http'
 
## Anfrageninstanz erstellen
http = Net::HTTP.new('example.com', 80)
 
## Das Timeout festlegen (So lange wartet das Script bis der Server nach einer Anfrage antwortet)
http.read_timeout = 100
 
## Eine zufällige Nummer die zum separieren des Anfragen Inhalts verwendet wird.
## Dieser String darf im Anfrage String vorkommen.
luckynumber = rand(9999999999).to_s();
 
## Die HTTP Header der Anfrage.
## Wichtig ist hierbei den Content-Type entsprechend zu setzen. (multipart/form-data; nicht www-urlencoded)
## luckynumber der Wert hinter boundary= ist hierbei die Variable die zur Trennung von Inhalten verwendet wird.
header = {
        'User-Agent' => 'Mozilla/5.0 (en-US) Gecko/20100303'
	'Content-Type' => 'multipart/form-data; boundary=luckynumber'+luckynumber
}
 
## Die Daten die an den Webserver gesendet werden.
## Der Platzhalter *Inhalt der Datei in dem nicht luckynumber123456789 vorkommt* muss durch deinen Datei Inhalt ersetzt werden.
## --luckynumber"+luckynumber wird als Seperator der Datei verwendet.
## Die Kopdaten der Datei, Dateiname und Dateicodierung, müssen mit zwei
## Umbrüchen (nn) vom Inhalt separiert werden.
data =
"--luckynumber"+luckynumber+"
Content-Disposition: form-data; name="Filedata"; filename="dateiname.txt"
Content-Type: text/plain
 
*Inhalt der Datei in dem nicht luckynumber123456789 vorkommt*
 
--luckynumber"+luckynumber+"--
" 
 
## Absenden der HTTP POST Dateiupload-Anfrage
resp = http.post('upload.php', data, header)
 
## Von der Anfrage erhalten wir die Angefragten Daten und
## einen Status Code. Ist der Status Code ungleich 200
## ist ein Fehler aufgetreten.
if resp.code != "200"
	puts '# An error has occurred...'
endif

Die Ruby interne Net/HTTP Klasse wird für die Socketarbeiten für das Script verwendet. Die Anfragen werden über diese Ruby standard Klasse versandt. Der im Kopf Bereich angegebene Separator (boundary=) darf nicht zufällig im String der Anfrage vorkommen.

Allgemein ist es wichtig die Anfrage multipart/form-data; Formatiert zu übertragen. Im Kopf Bereich der HTTP-Anfrage der gesandt wird ist dabei diese Zeichenkette ausschlaggebend:

Content-Type: multipart/form-data; boundary=luckynumber123456789

Bei den Daten in der Anfrage ist zu beachten das einzelne Werte mit Hilfe eines Strings separiert werden. Hier nochmals „luckynumber123456789“ als seperator.

--luckynumber123456789
Content-Disposition: form-data; name="Filedata"; filename="dateiname.txt"
Content-Type: text/plain
 
*Inhalt der Datei in dem nicht luckynumber123456789 vorkommt*
 
--luckynumber123456789--

Ein Plain-Text Beispiel für den Inhalt einer Anfrage-Zeichenkette. Die Content-Type Angabe übermittelt den Mime-Typ der Datei. Eine alphabetisch sorierte Liste der Mime-Typen findest du hier. Weitere HTTP Fehler Codes zum auswerten von HTTP-Response Codes findest du hinter diesem Link.

Viel Freude beim Dateien Uploaden nach RFC1867.

Keine Kommentare »
 

Chromium das Quelloffene Stück Entwicklung am Google Chrome. URLs für die Paketquellen von Ubuntu findest du hier. Die Installation erfolgt mit einem

sudo apt-get install chromium-browser

Noch sind nicht alle Freatures die im Chrome bereits zum Standard zählen implementiert. Auch das Plugin System muss zunächst aktiviert werden. Das aktivieren erfolgt über das Eintragen von

CHROMIUM_FLAGS="--enable-plugins"

in die Datei /etc/chromium-browser/default. Ein Symlink muss nun in /usr/lib/chromium-browser/plugins/libflashplayer.so erstellt werden der auf die Datei /usr/lib/flashplugin-nonfree/libflashplayer.so zeigt. Der Symlink wird mit dem Befehl

sudo ln -s /usr/lib/chromium-browser/plugins/libflashplayer.so /usr/lib/flashplugin-nonfree/libflashplayer.so

erstellt. Hierbei ist zu beachten das der Pfad zur .so Datei des Flash Players von Distribution zu Distribution in verschiedenen Verzeichnissen liegt (dieser Artikel ist für Ubuntu). Die Pfade im Befehl zum erstellen eines Symlinks müssen eventuell angepasst werden. Sollte die Datei nicht vorhanden sein kann sie mit dem Installieren des Flash Players installiert werden. Mit

sudo apt-get install flashplugin-nonfree

sollte Flash unter einem Ubuntu System installiert sein. Adobe Flash sollte nach dem Ausführen der oben genannten Schritte in deinem Chromium funktionieren. Falls dem nicht so sein sollte hinterlasse mir ein Kommentar woran es gelegen hat.

Keine Kommentare »