Category: security

Hooking mit uallCollection

20.02.2010 yahe code legacy security windows

Ich habe die letzten Tage an einem Projekt gearbeitet, für das ich systemweit API-Aufrufe hooken können musste. Leider ist dieses Unterfangen nicht so einfach. Im Internet finden sich einige Lösungen für dieses Problem: Angefangen beim Schreiben von Systemtreibern, bis hin zum Injizieren von Threads in bereits laufende Prozesse.

Besonders gut scheint das Paket madHookCode zu sein, das leider weder günstig noch einfach zu beschaffen ist. Glücklicherweise gibt es die uallCollection, welche die gleiche Methode wie das Paket madHookCode zu benutzen scheint. Auch sonst scheinen die beiden Projekte eng miteinander verknüpft zu sein. Für den Programmierer, der sich zwischen den beiden Paketen entscheiden muss, ist das jedenfalls ein Vorteil, da die uallCollection komplett kostenfrei ist. Lediglich das Injizieren neu gestarteter Prozesse beherrscht die uallCollection nicht. Mit ein paar Zeilen Code kann man diese Funktion jedoch recht leicht selbst bauen:

unit ProcessU;

interface

procedure HookProcess;
procedure UnhookProcess;

implementation

uses
  Windows,
  uallHook,
  MainU;

var
  VProcessLib : HMODULE = 0;

  VNewCreateProcessA : function (lpApplicationName: PChar; lpCommandLine: PChar;
                         lpProcessAttributes, lpThreadAttributes: PSecurityAttributes;
                         bInheritHandles: BOOL; dwCreationFlags: DWORD; lpEnvironment: Pointer;
                         lpCurrentDirectory: PChar; const lpStartupInfo: TStartupInfo;
                         var lpProcessInformation: TProcessInformation): BOOL; stdcall;
  VOldCreateProcessA : function (lpApplicationName: PChar; lpCommandLine: PChar;
                         lpProcessAttributes, lpThreadAttributes: PSecurityAttributes;
                         bInheritHandles: BOOL; dwCreationFlags: DWORD; lpEnvironment: Pointer;
                         lpCurrentDirectory: PChar; const lpStartupInfo: TStartupInfo;
                         var lpProcessInformation: TProcessInformation): BOOL; stdcall;
  VNewCreateProcessW : function (lpApplicationName: PWideChar; lpCommandLine: PWideChar;
                         lpProcessAttributes, lpThreadAttributes: PSecurityAttributes;
                         bInheritHandles: BOOL; dwCreationFlags: DWORD; lpEnvironment: Pointer;
                         lpCurrentDirectory: PWideChar; const lpStartupInfo: TStartupInfo;
                         var lpProcessInformation: TProcessInformation): BOOL; stdcall;
  VOldCreateProcessW : function (lpApplicationName: PWideChar; lpCommandLine: PWideChar;
                         lpProcessAttributes, lpThreadAttributes: PSecurityAttributes;
                         bInheritHandles: BOOL; dwCreationFlags: DWORD; lpEnvironment: Pointer;
                         lpCurrentDirectory: PWideChar; const lpStartupInfo: TStartupInfo;
                         var lpProcessInformation: TProcessInformation): BOOL; stdcall;

function CatchCreateProcessA(lpApplicationName: PChar; lpCommandLine: PChar;
  lpProcessAttributes, lpThreadAttributes: PSecurityAttributes;
  bInheritHandles: BOOL; dwCreationFlags: DWORD; lpEnvironment: Pointer;
  lpCurrentDirectory: PChar; const lpStartupInfo: TStartupInfo;
  var lpProcessInformation: TProcessInformation): BOOL; stdcall; forward;
function CatchCreateProcessW(lpApplicationName: PWideChar; lpCommandLine: PWideChar;
  lpProcessAttributes, lpThreadAttributes: PSecurityAttributes;
  bInheritHandles: BOOL; dwCreationFlags: DWORD; lpEnvironment: Pointer;
  lpCurrentDirectory: PWideChar; const lpStartupInfo: TStartupInfo;
  var lpProcessInformation: TProcessInformation): BOOL; stdcall; forward;

function CatchCreateProcessA(lpApplicationName: PChar; lpCommandLine: PChar;
  lpProcessAttributes, lpThreadAttributes: PSecurityAttributes;
  bInheritHandles: BOOL; dwCreationFlags: DWORD; lpEnvironment: Pointer;
  lpCurrentDirectory: PChar; const lpStartupInfo: TStartupInfo;
  var lpProcessInformation: TProcessInformation): BOOL; stdcall;
begin
  Result := VNewCreateProcessA(lpApplicationName, lpCommandLine, lpProcessAttributes,
                               lpThreadAttributes, bInheritHandles, dwCreationFlags,
                               lpEnvironment, lpCurrentDirectory, lpStartupInfo,
                               lpProcessInformation);

  if Result then
    InjectLibrary(lpProcessInformation.dwProcessId, PAnsiChar(GetDLLFileName));
end;
function CatchCreateProcessW(lpApplicationName: PWideChar; lpCommandLine: PWideChar;
  lpProcessAttributes, lpThreadAttributes: PSecurityAttributes;
  bInheritHandles: BOOL; dwCreationFlags: DWORD; lpEnvironment: Pointer;
  lpCurrentDirectory: PWideChar; const lpStartupInfo: TStartupInfo;
  var lpProcessInformation: TProcessInformation): BOOL; stdcall;
begin
  Result := VNewCreateProcessW(lpApplicationName, lpCommandLine, lpProcessAttributes,
                               lpThreadAttributes, bInheritHandles, dwCreationFlags,
                               lpEnvironment, lpCurrentDirectory, lpStartupInfo,
                               lpProcessInformation);

  if Result then
    InjectLibrary(lpProcessInformation.dwProcessId, PAnsiChar(GetDLLFileName));
end;

procedure HookProcess;
begin
  VProcessLib := GetModuleHandle(KERNEL32);
  if (VProcessLib <> 0) then
  begin
    @VOldCreateProcessA := GetProcAddress(VProcessLib, 'CreateProcessA');
    @VOldCreateProcessW := GetProcAddress(VProcessLib, 'CreateProcessW');

    HookCode(@VOldCreateProcessA, @CatchCreateProcessA, @VNewCreateProcessA);
    HookCode(@VOldCreateProcessW, @CatchCreateProcessW, @VNewCreateProcessW);
  end;
end;

procedure UnhookProcess;
begin
  if (VProcessLib <> 0) then
  begin
    VProcessLib := 0;

    UnhookCode(@VNewCreateProcessA);
    UnhookCode(@VNewCreateProcessW);
  end;
end;

end.

Der EIGENE lokale DNS-Server: BINDcnf

16.05.2009 Yahe administration code legacy security windows

Die Idee, einen alternativen DNS-Server zu verwenden, um der geplanten, staatlichen Internetzensur zu entgehen, ist nicht neu. Anleitungen, wie man die entsprechenden Einstellungen im System vornimmt, gibt es zur Genüge im Internet. Jedoch hat sich bisher immer die Frage gestellt, welchen DNS-Server man denn als Alternative nutzen soll, denn es gibt einige zur Auswahl und bei den meisten hat man keine Ahnung, wer diese betreibt und aus welchem Grund. Bei der Umgehung der Netzsperre sollten jedoch genau diese Informationen im Vordergrund stehen, um die eigene Sicherheit nicht zu gefährden.

Die Frage, die sich mir stellte war, weshalb man nicht einfach selbst einen lokalen DNS-Server betreibt und diesen nutzt, anstatt auf die Server von anderen zurück zu greifen. Die Antwort bekam ich bei meiner Recherche promt geliefert. Ein durchschnittlicher User hätte arge Probleme mit der Konfiguration des Servers.

Nachdem ich selbst eine halbwegs ordentliche Konfiguration erstellt hatte, habe ich mich deshalb dazu entschlossen, ein Programm zu schreiben, das diese Konfiguration automatisch erzeugt, sodass jeder Benutzer diese Möglichkeit des Selbstschutzes einsetzen kann. Das Ergebnis nennt sich BINDcnf!

Als Basis dient der frei verfügbare DNS-Server BIND, der wohl mit Abstand weitverbreitetste DNS-Server im Internet. Dieser muss im ersten Schritt installiert werden.

BIND-Installation

Nach der Installation des DNS-Servers muss BINDcnf ausgeführt werden, dass die benötigte Konfiguration generiert und entsprechende Abhängigkeiten (z.B. die Adressen der Root-DNS-Server) aus dem Internet herunterlädt.

BINDcnf : Configuration succeeded

Nach Abschluss der automatischen Konfiguration muss nur noch der Server gestartet und die eigene, lokale IP "127.0.0.1" als bevorzugter DNS-Server im System konfiguriert werden.

Bevorzugter DNS-Server

BINDcnf bietet über den Parameter "help" eine kleine Hilfe, die kurz und knapp die verfügbaren Optionen erklärt. Zudem wird eine Datei namens "BINDcnf.bat" mitgeliefert, die das Programm "BINDcnf.exe" mit den am häufigsten genutzten Parametern aufruft.

BINDcnf Hilfe


Shared Hosting: Angriff auf Sessions möglich

08.05.2009 Yahe administration legacy linux security

Heute gibt es einen schon lange geplanten Artikel zu einem größeren Sicherheitsproblem. Meiner Erkenntnis nach könnte diese Lücke alle Shared Hosting Kunden betreffen, auch solche bei Reselling-Anbietern. Das Problem bei dieser Art des Webhostings ist, dass alle Webseiten von verschiedenen Kunden auf ein und demselben Server liegen und nur durch entsprechend gesetzte Zugriffsrechte voneinander getrennt sind. Das Problem hierbei ist, dass diese Zugriffsrechte nur mit viel Aufwand ganzheitlich durchsetzbar sind.

Mir ist z.B. aufgefallen, dass man zwar bei üblichen Angeboten auf FTP-Ebene und PHP-Ebene durch "SafeMode On" in dem eigenen Kundenverzeichnis "gefangen" ist, man jedoch unter Verwendung von CGI aus dem eigenen Verzeichnis ausbrechen kann. Danach ist es möglich, mithilfe von einfachen Befehlen z.B. alle Dateien und Ordner anderer Kunden suchen zu lassen, bei denen man selbst Schreibzugriff hat. Durch Zugriff auf den HTTP-Ordner eines anderen Kunden (z.B. "public_html", "public_http" oder "htdocs") ist es dann möglich, durch Anlegen einer einzigen Datei (".htaccess" bei Apache Webservern) die gesamte Domain zu hijacken.

Kunden können sich dagegen nur durch das korrekte Setzen der Ordner-Zugriffsrechte schützen.

Das war jedoch nur ein Szenario. Ein anderes ist viel gravierender, das sogenannte Session Hijacking. Bei Shared-Hosting Angeboten ist auch das möglich. Der Grund dafür ist, dass alle Kunden auf derselben Maschine die gleiche PHP-Instanz nutzen. Um die Verwaltung der Sessions zu erleichtern, werden diese meistens in einem gemeinsamen Verzeichnis für alle Kunden gespeichert. An sich ist das auch kein Problem, denn die Session-IDs sollten sowieso möglichst zufällig gewählt sein und in den Ordner, in dem die Sessiondateien liegen, kann ja eh keiner reingucken. Durch das weiter oben beschriebene CGI-Problem ändert sich diese Einschränkung jedoch. Dadurch wird es potentiell möglich, dass andere Kunden die eigenen Sessiondateien auslesen können. Direkten Zugriff per CGI hat man zwar meistens nicht, wenn die Zugriffsrechte ordentlich gesetzt sind, aber durch die gemeinsame PHP-Instanz erhält man auch Zugriff auf den gemeinsamen Sessionordner!

Je nach Webanwendung reicht diese Lücke vom Auslesen und Modifizieren des Einkaufskorbs bis zur Erlangung von Administratorrechten. Alles, was die Webanwendung in der Session speichert, können Kunden, die auf dem gleichen Shared-Server gehostet werden, lesen, modifizieren oder aber auch löschen (z.B. regelmäßig alle Sessions eines Webshops schließen, um den Shop unbrauchbar zu machen). Anhand von einfachem Ausprobieren (die Domainadressen der Mitgehostenen kriegt man dank der Ordnerstruktur des Servers manchmal sogar frei Haus geliefert), kann man die Sessionstrukturen meist den einzelnen Domains zuordnen. Und schon weiß man anhand der Daten in einer Session, dass da gerade jemand auf der Domain example.com etwas bestellen will.

Glücklicherweise können sich die Kunden dagegen schützen, indem sie den Session-SavePath von PHP manuell anpassen!

Das PHP Security Consortium hat zu diesem Problem ebenfalls einen Artikel veröffentlicht, empfiehlt jedoch alternativ, die Session-Informationen in einer Datenbank zu speichern.


Search

Links

RSS feed

Categories

administration (40)
arduino (12)
calcpw (2)
code (33)
hardware (16)
java (2)
legacy (113)
linux (27)
publicity (6)
review (2)
security (58)
thoughts (21)
windows (17)
wordpress (19)