| |
|
|
- Seite 1 - |
|
| Hallo Profaner..
Hat mal jemand Lust zu testen, ob [...] unter XP generell gefixt ist?
- Einen Service zu programieren ist dafür nicht unbedingt nötig, normales Programm mit RUN AS (auch mit PrivAktivate möglich) als Admin starten und das Angreiferprogramm in einem Account mit eingeschränkten Rechten ausführen. - In das Hauptprogramm einen Timer einfügen (muß natürlich ein Fenster haben). - Im Angreiferprogramm eine Prozedur schreiben, die eine Messagebox ausgibt, die Proc aber nicht ausführen lassen. - Mit ProcAddr die Adresse der Prozedur ermitteln. - Mit PostMessage (oder vielleicht SendMessage) WM_TIMER mit der Adresse der Prozedur vom Angreiferprogramm an das Hauptprogramm senden.
Klapp das???
|
|
|
| |
|
|
|
| |
|
- Seite 2 - |
|
| Warum das nicht ging, ist mir glaube ich jetzt klar: [quote:16fcb7769f=Frank Abbing]Hallo,
die Adresse kann eigentlich keine virtuelle Adresse sein, weil sie direkt angesprungen werden kann. Ich kann die Prozedure auch direkt in meinen Code setzten und starten. [/quote:16fcb7769f] Im eigenen Prozess kein Problem - aber im fremden? Der Code, den man ausführen will, befindet sich ja im eigenen Prozessbereich und jeder Prozess verfügt über seinen eigenen virtuellen Speicherbereich...
[quote:16fcb7769f=Frank Abbing] Ich vermute eher, dass Windows testet, ob der Speicher, der ausgeführt werden soll, zum Programm gehört. Also von Programm belegt wurde. [/quote:16fcb7769f] Ich will hoffen, daß wir nicht aneinander vorbeireden: Da ein Prozessor ja zur Zeit auch nur immer einen Prozess ausführen kann, könnte ich mir sogar vorstellen, daß der sich der auszuführende Code physikalisch zu der Zeit, an der er eigentlich dem Prozessor als Programmcode zum Ausführen zur Verfügung stehen sollte, in RAM-Gefilden befindet, in dener er als auszuführender Code gar nichts nutzt. Man muß also den auszuführenden Code erst einmal in den Speicherbereich des anzugreifenden Prozesses bringen. Und jetzt kommt der Debugger ins Spiel - gemeint sind hier APIs zum Debuggen von Programmen die eine DLL in den Speicherbereich eines fremden Prozesses injizieren können, nicht ein Programm. Zum injizieren einer DLL gibt es mehrere Möglichkeiten - der Autor scheint hier eine Möglichkeit gefunden zu haben, die nur unzureichend über Privilegien und Zugriffsrechte abgesichert ist. Ich bin mir im Augenblick aber ziemlich sicher, das zumindestens der anzugreifende Prozess über bestimmte Sicherheitsmängel verfügen muß, die das injizieren zulassen.
[quote:16fcb7769f=Frank Abbing] Es gibt wohl eine Vielzahl an Möglichkeiten, anderen Task eine Adresse mitzuteilen. [/quote:16fcb7769f] Ja, unter anderem Subclassing. |
|
|
| |
|
|
|
| So - ich glaube, mir ist klar geworden, wie er das gemacht hat. Werde das im nächsten Jahr mal testen... |
|
|
| |
|
|
|
| Das eigentliche Problem ist, daß jeder Prozess seinen eigenen virtuellen Speicherbereich hat. Will ich also, das ein fremder Prozess meinen Quelltext ausführt, muß dieser Quelltext sich im Speicher des Prozesses befinden, der ihn ausführen soll. Aber wie bekomme ich Quelltext in einen fremden Prozess? Das ist eigentlich das kleinere Problem: Jedes Control, bei dem ich irgendwie Ihnhalte mittels einer Message senden kann, bietet eigentlich diese Möglichkeit - am einfachsten geht das mit einem Multiedit (das natürlich vorher schon im Prozess vorhanden sein muß). Mittels WM_SETTEXT läßt sich an ein Multiedit ja Text senden, der dann im Edit sichtbar und editierbar ist - aber warum nur Text, warum keine DLL mit Quelltext? Sende ich eine DLL (natürlich nicht von der Festplatte, sondern aus dem Speicher meines Prozesses heraus) an das Multiedit des fremden Prozesses, befindet sich die DLL dann im Speicherbereich des femden Prozesses und kann nun auch mittels WM_TIMER angesprochen werden (bislang nur Trockenschwimmen, da ich kein MASM kann, müßte aber klappen). Mittels EM_GETHANDLE läßt sich dann das Handle des Textes (der DLL) im Edit ermitteln - und nun kommt das eigentliche Problem, ich brauche nicht das Handle, sondern die Adresse. Mittels folgendem Quelltext wollen wir uns jetzt mal etwas näher um die Adresse kümmern - unter 2000/XP natürlich: KompilierenMarkierenSeparierenWindowstyle 31
Windowtitle "Multiedit"
Window 0,0-640,440
Def @GlobalSize(1) !"KERNEL32","GlobalSize"
Def @GlobalLock(1) !"KERNEL32","GlobalLock"
DEF @CopyMemory(3) !"kernel32","RtlMoveMemory"
Def @GlobalReAlloc(3) !"KERNEL32","GlobalReAlloc"
Def @SetParent(2) !"USER32","SetParent"
Declare edit&,Text$,ADDR&,Handle&,Text#
Dim Text#,256
LET EDIT&=@Createmultiedit(%HWND,"Test ",20,130,200,200)
LET Text$="ABCD"
LET Handle&=@sendmessage(edit&,$BD,0,0)
Print "Handle des Edits: "+@str$(Edit&)
Settext Edit&,@STR$(Handle&)
Let Addr&=@val(@Input$("Adresse des Edits:","Addresse",""))
Let Addr&=@GlobalLock(Handle&)
@CopyMemory(Addr&,@ADDR(Text$),32)
@CopyMemory(text#,Addr&,32)
Print "Adresse: "+@str$(Addr&)
Print "Breichshandle: "+@str$(Handle&)
Print "Kopierter Text: "+@String$(Text#,0)
PrINT "Bereichgröße: "+@str$(@GlobalSize(Handle&))+" Bytes"
Dispose text#
While 0=0
Waitinput
wend
Da Profan etwas verschwenderisch mit Heaps umgeht, sollte man den Quelltext mit Profan2Cpp compilieren. Beim mir sieht das ganze dann in etwa so aus:
BILD 1
Im Edit steht hier das Handle des Textes. Nun starten wir [...] , wählen den Testprozess mit dem Multiedit aus und lassen uns dessen Heaps listen.
BILD 2
Nun tun wir mal so als wäre das Handle des Textes (bei mir 44630028) eine Adresse und lassen uns das Doubleword an dieses Adresse von [...] einmal auslesen.
BILD 3
BILD 4
Heraus kommt bei mir: X1=38184920 Jetzt tun wir wiederum so, als wäre 38184920 und schauen unter den Heaps nach, ob wir irgendwo diese Adresse finden und lassen uns den Inhalt des Heapblocks als String darstellen:
BILD 5
Wie man sieht, haben wir die Adresse des Textes im Edit gefunden! Diese Adresse kann als Offset für die Funktion genommen werden, die wir mittels WM_TIMER später im fremden Prozess ansprechen wollen. Dazu muß die Adresse der auszuführenden Funktion ab dem Nullpunkt der DLL addiert werden - das zeigt [...] (Hoffentlich) ganz gut an => fertig ist die Adresse für WM_TIMER!
Als Administrator alles kein Problem - aber zum Auslesen von Prozesspeicher benötige ich PROCESS_VM_READ und PROCESS_VM_OPERATION - und als User mit eingeschränkten Rechten habe ich diese Rechte definitiv nicht! ...aber unter welchen Voraussetzungen ändert sich die Adresse überhaupt??? Mal schaun: Ich starte den Prozess erneut => gleiche Adresse! Die Adresse scheint also die nächste freiliegende Adresse zu sein und wird nicht zufällig gewählt. Ich gebe mehr als 32 Zeichen in das Edit ein => neue Adresse - ist ja klar, wenn mehr zusammenhängender Speicher gebraucht wird und dieser an dieser Stelle nicht zur Verfügung steht, muß sich auch die Adresse ändern. Aber auch alles was vorher in den Heap geschrieben wird (und sich ändert) kann diese Adresse beeinflussen. In unserem Fall liegt die Adresse im ersten Heap, dem Standardheap des Prozesses. Schauen wir mal nach, was sonst noch alles vor dieser Adresse steht. Hier mal ein paar Auszüge:
G : W I N N T S y s t e m 3 2 W I N M M . D L L => Name von vom Prozess geladener DLL F:EIGENESTasks and TokenMultiedit_cppMultiedit.exe => Gestarteter Prozess mit Parametern E G I S T R Y U S E R S - 1 - 5 - 2 1 - 8 6 1 5 6 7 5 0 1 - 1 0 6 0 2 8 4 2 9 8 - 1 9 5 7 9 9 4 4 8 8 - 1 0 0 0 => User String-SID
Auch Umgebungsvariablen eines Prozesses habe ich schon in Heaps gefunden. Wie man hier bereits erkennt, ist die Adresse also Systemabhängig, damit ist es also nicht möglich, eine vernünftige Anwendung zu schreiben, die aus einem normalen Useraccount jeden Rechner ohne weiteres knackt ohne ihn vorher zig(tausend)male zum Absturz zu bringen. Das dürfte der Grund sein, warum Microsoft auf den Artikel, der Ausgangspunkt dieser Postings war, nicht großartig reagiert hat - die Grundaussage dieses Artikels war aber eine andere, nämlich daß es insgesammt ein Sicherheitsrisiko ist, Messages ungefragt an andere Programme senden zu dürfen; und dem stimme ich jetzt mal ganz heftig zu...
Und wer sich jetzt fragt, warum ich hier so viel blödsinn hingeschrieben habe: Ich habe hier eben mal nebenbei eine Möglichkeit zur DLL-Injektion aufgezeigt, die natürlich auch mit anderen Controls als einem Multiedit funktioniert . |
|
|
| |
|
|
|
| Ich muß das, was ich hier im letzten Posting von mir gegeben habe, wohl etwas revidieren. Folgende Überlegung: Der Text des Edits landet immer im ersten Heap. Die Startadresse des ersten Heaps (auch hier quasi das Handle), dürfte auf dem gleichen Betriebsystem (und das auch auf unterschiedlichen Rechnern) immer an der gleichen Stelle liegen. Ich habe bei mir unter Windows2000 mal mit WM_TIMER etwas herumexperimentiert... Zeigt Parameter vier auf einen nicht auslesbaren Bereich, entsteht selbstverständlich eine Zugriffsverletzung. Zeigt Parameter vier aber auf auslesbare Bereiche die keinen ausführbaren Quelltext enthalten, passiert scheinbar kein schwerwiegender Fehler. Theorethisch müßte es also möglich sein, die Startadresse (das Handle) des ersten Heaps als Ausgangspunkt zu nehmen und so lange beim Senden der Message ein Byte dazuzurechnen, bis WM_TIMER den Quelltext ausführt.. Die Startadresse des Heaps könnte man von einem anderen Rechner beziehen, auf dem die gleiche Anwendung läuft. Selbst mit XProfan dürfte das noch in annehmbarer Geschwindigkeit zu regeln sein. Ich bin zur Zeit an anderen Sachen dran und konnte dies leider noch nicht weiter testen, da ich hier aber genug lauffähigen Quelltext habe, werde ich die Chatter Attack in nächster Zeit mal nachbauen. Es wird nichts großartig spektakuläres werden und die DLL die ausgeführt wird, wird die Test-DLL mit der Messagebox sein, die mir Frank damals freundlicherweise programmiert hat - ich möchjte trotzdem aber mal nachfragen, ob ich so ein Programm hier überhaupt posten darf? |
|
|
| |
|
|
|
Frank Abbing | Na, die Frage geht wohl eher an iF. Mich jedenfalls würde dein Test interessieren. |
|
|
| |
|
|
|
| |
|
| |
|
|
|
| Mmmh - nach einiger Euphorie verliere ich im Augenblick mal wieder das Vertrauen in den Warheitsgehalt der Aussagen des Artikels. Die kleinste Hürde (- die ich im Augenblick noch nicht überwunden habe - ), wäre das Einfügen von Nullbytes in ein Edit ohne das Recht PROCESS_VM_WRITE zu haben; da steht aber noch wesentlich mehr im Wege...
Einmal an Frank: Wie groß sind die Chancen, daß man mit dieser Methode wirklich einen aktuellen Rechner knacken kann? Schau dir dazu mal die Prozesse mit TNT an, die auf deinem Rechner im System-Account laufen - denn um die geht es hier. Siehst du irgendwo einen solchen Service, der ein Edit oder ein Multiedit besitzt??? Wenn du dir meine anderen Artikel einmal aufmerksam durchliest und selbst mit TNT etwas herumexperimentierst, wirst du wohl sehr schnell feststellen, daß alle anderen Fenster für solche Aktionen nicht zu gebrauchen sind (bin also kein Böser Bube ). Was mich an diesem Artikel interessiert, ist die Möglichkeit der DLL-Injektion als Administrator in einen Prozess, der kein Service ist - aber selbst da sehe ich im Augenblick Probleme,, für die es noch keine Lösung gibt... |
|
|
| |
|
|
|
| [quote:91bd3aedf7=Frank Abbing]Na, die Frage geht wohl eher an iF. Mich jedenfalls würde dein Test interessieren.[/quote:91bd3aedf7] Mmh... - Quelltext werde ich vorerst zu DLL-Injektionen noch nicht aus der Hand geben. Zumindestens das, was TNT macht dürfte für euch beide aber auch ohne Probleme ohne Quelltext nachzuvollziehen sein, direkte Fragen an meine Mailadresse beantworte ich ebenfalls gerne.
Gruß
AH |
|
|
| |
|
|
|
| Zum Abschluß als Demonstration was da wirklich so alles möglich gewesen ist, nochmals was zu diesem Thema. Da ich die kleine Anwendung, die ich diesbezüglich geschrieben habe, nicht so gerne unter die Leute bringen möchte, also in Form einer Animation: |
|
|
| |
|
|
|
| Drum ist ja zum Glück auch ein altes Windows ;) |
|
|
| |
|
|
|
| Fakt ist, das es über Jahre hinweg (auch unter XP) möglich gewesen ist, für einen normalen Mitarbeiter jeden Firmenrechner auszuhebeln (und das unter XP noch besser als unter Windows2000). Fakt ist auch, das sich am Grundprinzip von Windows nichts geändert hat. Ob noch irgendwo im OS weitere undokumentierte Messages mit gleichem Potential verborgen sind, ist ebenfalls nicht sicher. EM_SETWORDBREAKPROC und andere Messages wurden meines Wissens nach noch nicht einmal gefixt. Fakt ist auch, das auf vielen, (auch kommerziell genutzten) Rechnern noch veraltete Servicepacks laufen - siehe meinen Test im Internetcaffee.
Shatter ist also eine Geschichte, die man sehr genau im Auge behalten sollte - gerade wenn es um neuere Betriebsysteme geht. Besonders brisant finde ich die Geschichte, das es nicht einmal nötig ist Quelltext in fremde Anwendungen über eine Message einzuschleuse - die Möglichkeit Quelltext anzuspringen reicht immer aus! |
|
|
| |
|
|
| |
|
- Seite 3 - |
|
|
| Ich hab da sogar noch was vergessen .
Dazu kommt noch, das ja evtl. nicht nur das Starten fremder Quelltexte gefährlich sein kann - es ist z.B. auch möglich, ohne irgendwelche Rechte über Messages den Speicher fremder Prozesse auszulesen. |
|
|
| |
|
|