PE Infektion

Loader

Hallo,

Viel simpler ist das verschieben/umbenennen der Ursprungs-EXE, und dafür einen eigenen "Loader" hinzustellen. Der Loader startet dann einfach die Original-exe und führt dann seinen Code aus.

Das habe ich nun nicht verstanden^^

Wie genau muss ich das jetzt machen?

Ausgangspunkt:

- Wirt.exe
- Anhang.exe

Ziel:

Beim Starten von Wirt.exe wird zuerst Anhang.exe ausgeführt

Und wie genau stelle ich das jetzt mit einem "Loader" an?

Grüße
Gapa
 
Bei dem Prinzip mit dem Loader würde die Wirt.exe mit der Anhang.exe ausgetauscht. Die Wirt.exe wird dann irgendwo versteckt gespeichert und dann von der Anhang.exe in einem neuen Thread gestartet.
 
ALso mal grundsätzlich:

Wenn man Code injectet wird der Hashwert der EXE geändert. AUssenstehende Programme erkennen die Veränderung sofern die Ziel EXE überwacht wird.

Daher kann man auch eine ganz andere EXE (die einfach ähnlich uassieht/Infos bereitstellt) an Stelle der Original EXE hinstellen.


Nehmen wir an, du hast Programm "Original.exe" auf einem PC installiert.

Nun kommt dein "replacer" Programm, und benennt "Original.exe" nach "Originalxyz.exe" um. Nun Kopiert sich dein Programm selber an den Ort von Original.exe, und nennt sich auch so.

Dann exisiteren also zwei exen;
Original.exe ;Dein Programm, was sich als Original-exe ausgibt
Originalxyz.exe ;Das echte Programm

Wenn nun "Original.exe" aufgerufen wird, somit also dein Programm, startet dein Programm als erstes das Echte -> "Originalxyz.exe" und führt nachher seinen Code aus.-> so läuft also das gewünschte Programm, aber deines auch.

lg
 
HalloWelt injizieren

Hallöle!

There and back again... :D

Alle Vorkehrungen sind getroffen!
Letzte Section wurde angepasst...(naja fast)

nun zum Einfügen des Codes..

Wo genau muss ich nun den Code anhängen? Und in welchem Zustand??
Ich muss das HalloWelt-Programm ja erst mal compilieren. Und von diesem compilierten Programm darf ich ja nur Code/Daten in das Wirt-Programm einfügen. Woher weiß ich, wo Anfang bzw. Ende des Codes ist? Anfang ist ja OEP (oder nur EP??), aber wie weit muss ich ab dort auslesen??

Und wo muss ich das dann in der Wirt.exe anhängen??

Viele Grüße
Gapa
 
1. Was hat das mit "Code in Bild einbetten" zu tun?

2. Du hast geschrieben, du hättest eine neue Section angehängt, fragst nun aber wohin mit dem code? Etwas am Konzept vorbei. :/ Weist du, was du tust?

3. Code kann man überall einfügen wo platz ist, oder wo man sich platz macht. Danch den EP auf _deinen_ code umbiegen, dein code wird abgearbeitet und danach springst du wieder zurück, zum "echten" Anfang.
 
...

Hallo,

zu 1. :
Mann du hast doch den Verlauf dieses Threads nun schon mitbekommen, oder?
Von diesem Titel sind wir bereits vor Wochen abgewichen. Wieso sollte ich also nochmal einen Thread aufmachen, wenn sowieso nur von den Leuten Antworten kommen, welche bereits in diesem Thread geantwortet haben (CDW hauptsächlich, DU...)

zu 2. :
Letzte Section wurde angepasst...
Ich weiß ja nicht, was man in diesen Satz alles reininterpretieren kann, aber von einer neuen angehängten Section war hier wohl nie die Rede, oder?? X(

zu 3. :
Das möchte ich doch mal bezweifeln! Jedes Programm hat (und das kann ich mittlerweile mit Sicherheit sagen!) einen bestimmten Abschnitt, indem es Code erlaubt. Ich möchte nun wissen, wie ich meinen Code in diesen Abschnitt (Beginn dieses Abschnittes ist der EntryPoint) reinbekomme! Muss ich den Code hinter dem "normalen" Code einfügen oder davor, oder kann ich das beliebig mischen... müsste dann eben aufpassen, dass ich nicht das Hauptprogramm kaputt mache =)

Und was ich ebenfalls noch gern wüsste ist, wie ich den Teil meines Injektionsprogrammes, welcher in das Wirtsprogramm rein muss, aus dem Injektionsprogramm herausbekomme.

Viele Grüße
Gapa
 
Re: ...

Original von Gapa
Ich muss das HalloWelt-Programm ja erst mal compilieren. Und von diesem compilierten Programm darf ich ja nur Code/Daten in das Wirt-Programm einfügen.
Woher weiß ich, wo Anfang bzw. Ende des Codes ist?
vs.
zu 3. :
Das möchte ich doch mal bezweifeln! Jedes Programm hat (und das kann ich mittlerweile mit Sicherheit sagen!) einen bestimmten Abschnitt, indem es Code erlaubt. Ich möchte nun wissen, wie ich meinen Code in diesen Abschnitt (Beginn dieses Abschnittes ist der EntryPoint) reinbekomme! Muss ich den Code hinter dem "normalen" Code einfügen oder davor, oder kann ich das beliebig mischen... müsste dann eben aufpassen, dass ich nicht das Hauptprogramm kaputt mache =)
also der Codeabschnitt im Injektionsprogramm oder im Wirt?
Also 1. ist EntryPoint bei weitem noch nicht der Beginn des Codeabschnittes.
Bsp:
Code:
int do_some()
{
...
}
int main()
{
...
}
Der Compiler kann das nun so übersetzen, wie er lustig ist - 1:1 umsetzen (damit fängt der Code mit der do_some Funktion an) oder zuerst die Main platzieren. Der EntryPoint wird aber in beiden Fällen auf die Main zeigen.
Zum Wirt:
du hast also die letzte Section erweitert. Wie wir aus dem anderen Thread wissen, kann die CPU selber nicht unterscheiden, was die verarbeitet. D.h prinzipiell ist es erstmal egal, wo man seinen Code einfügt. Um Programmfunktionalität zu erhalten, sollte man aber schon seinen eigenen Code "zuletzt" einfügen. Die einzige Hürde die nun bleibt ist
Jedes Programm hat (und das kann ich mittlerweile mit Sicherheit sagen!) einen bestimmten Abschnitt, indem es Code erlaubt.
Das wird mittels Flags geregelt - also ob die Section nur lesbar/beschreibbar oder auch ausführbar ist (siehe vorherige Posts in diesem Thread ->"Characteristics").
D.h einfach die Characteristics ändern (Executable Flag setzen) - dann lädt das OS diese Section in den Speicher und markiert ihn als ausführbar.

Und was ich ebenfalls noch gern wüsste ist, wie ich den Teil meines Injektionsprogrammes, welcher in das Wirtsprogramm rein muss, aus dem Injektionsprogramm herausbekomme.
Programmiersprachenspezifische Funktionen nutzen - unter C wäre es z.B memcpy/memmove. Ich würde auch für die erste Injection (naja, eigentlich für alle ;) ) den Injectionsteil in asm schreiben - etwas ganz simples wie
Code:
jmp NOTHING
OEP:
nop <--- der Injektor sollte diese 4 "dummy" Bytes mit dem ausgelsenen 
nop   <<-------- und berechneten OEP (EP Wert+ImageBase =Virtuelle Adresse)
nop  <------- überschreiben
nop
NOTHING:
nop
nop
mov eax,dword ptr [OEP]
jmp eax
nur um zu testen, ob der Injector korrekt funktioniert und man grundsätzlich alles richtig gemacht hat. Dann kann man damit auch rumspielen.
 
---

Hallo CDW,

also das habe ich jetzt nicht so ganz verstanden..

Der "ausführbare" Teil des Programms beginnt doch mit dem EntryPoint, oder?
Oder gibt es mehrere EPs?
Wenn ich nun will, dass mein Code zuerst ausgeführt wird, dann muss ich doch den EntryPoint umlenken auf das Ende des Programms (also da, wo dann mein Code anfängt), oder?

Wieso schreibst du dann:
jmp NOTHING
OEP:
nop <--- der Injektor sollte diese 4 "dummy" Bytes mit dem ausgelsenen
nop <<-------- und berechneten OEP (EP Wert+ImageBase =Virtuelle Adresse)
nop <------- überschreiben
nop
NOTHING:
nop
nop
mov eax,dword ptr [OEP]
jmp eax
??
1. Wieso muss ich vor den OEP einen JMP-befehl setzen, welcher zu meinem Code springt?? Dieser JMP-Befehl wird doch nie ausgeführt, oder?? Er steht ja noch vor dem OEP...

2. Was meinst du mit den Kommentaren ("der Injektor sollte diese 4 "dummy" ...")???

Ich dachte, ich muss einfach nur den OEP umändern in die Adresse, wo mein Code beginnt, und am Ende meines Codes dann wieder zum echten OEP springen....

Noch ne Frage:
Nach dem OEP kommen nur noch die Sections, oder? Sonst könnte ich ja nicht einfach meinen Code ans Ende des Programms setzen, oder? Und kann man diese Sections mit den Befehlen .data bzw. .code vergleichen? Aber dann gäbe es ja nur 2 Sections...
Was wäre, wenn die letzte Secion, in die ich meinen Code injiziere, eine Section ist, in der es nur Daten gibt, welche beim Versuch sie auszuführen einen Fehler hervorrufen würden??

Und wird mit memcpy nur der Codeteil des Programms copiert??

Eigentlich möchte ich nur wissen, welchen Teil meines Injektionsprogrammes ich (in HexFormat) an welcher Stelle des Wirtsprogramms einfüge.
Wo fange ich an, meinem Injektionsprogramm den Code auszulesen?? Beim OEP, oder? Und wie weit lese ich dann aus? Doch nicht etwa bis zum Ende des Programms, oder? Wenn mein Injektionsprogramm nun mehrere Sections hat, dann lese ich die ja alle mit aus und füge sie dann in eine Section (letzte Section des Wirtprogramms)...gibt das keine Fehlermeldung??

Grüße
Gapa
 
Re: ---

Original von Gapa
Hallo CDW,

also das habe ich jetzt nicht so ganz verstanden..

Der "ausführbare" Teil des Programms beginnt doch mit dem EntryPoint, oder?
Oder gibt es mehrere EPs?
Wenn ich nun will, dass mein Code zuerst ausgeführt wird, dann muss ich doch den EntryPoint umlenken auf das Ende des Programms (also da, wo dann mein Code anfängt), oder?
Die Ausführung beginnt an der Stelle, auf die EntryPoint verweist. Der Codeblock an sich muss nicht unbedingt erst an dieser Stelle anfangen:
Code:
push eax
pop ebx
add eax,2
ret
mov eax, [ebp+4]  <---- der EP Wert im PE Header kann auch hierauf verweisen,
call 12345               <---- weil es der "logische" Programmanfang ist


??
1. Wieso muss ich vor den OEP einen JMP-befehl setzen, welcher zu meinem Code springt?? Dieser JMP-Befehl wird doch nie ausgeführt, oder?? Er steht ja noch vor dem OEP...
Ich dachte, ich muss einfach nur den OEP umändern in die Adresse, wo mein Code beginnt, und am Ende meines Codes dann wieder zum echten OEP springen....
es war nur ein Vorschlag, wie man es in Asm ausprogrammieren könnte. Irgendwo muss man ja den OEP der Anwendung zwischenspeichern.

Noch ne Frage:
Nach dem OEP kommen nur noch die Sections, oder? Sonst könnte ich ja nicht einfach meinen Code ans Ende des Programms setzen, oder? Und kann man diese Sections mit den Befehlen .data bzw. .code vergleichen? Aber dann gäbe es ja nur 2 Sections...
Nach dem OEP-Wert im PE-Header kommen noch andere Angaben. Nach der Stelle, auf die dieser Wert verweist, kann noch mehr Code kommen. Aus der EP Angabe alleine kann man nicht berechnen, wie groß der Codeblock in der Anwendung ist.

Was wäre, wenn die letzte Secion, in die ich meinen Code injiziere, eine Section ist, in der es nur Daten gibt, welche beim Versuch sie auszuführen einen Fehler hervorrufen würden??
zum dritten mal in diesem Thread: Sectioneigenschaften (ausführbar/lesbar/beschreibbar) wird im PE Header beschrieben. Wenn man die "Characteristics" der Section nun auf "ausführbar" setzt, kann der injezierte Code ausgeführt werden.

Und wird mit memcpy nur der Codeteil des Programms copiert??
nein
http://www.cplusplus.com/reference/clibrary/cstring/memcpy.html
die größe sowie den Anfang muss man schon selbst angeben/berechnen.

Wo fange ich an, meinem Injektionsprogramm den Code auszulesen?? Beim OEP, oder? Und wie weit lese ich dann aus? Doch nicht etwa bis zum Ende des Programms, oder? Wenn mein Injektionsprogramm nun mehrere Sections hat, dann lese ich die ja alle mit aus und füge sie dann in eine Section (letzte Section des Wirtprogramms)...gibt das keine Fehlermeldung??
Ähm, das kommt auf die verwendete Sprache/Compiler an. Wo der Code anfängt und endet muss man berechnen/herausfinden. Z.B könnte es so gehen (Pseudo C):
Code:
int main()
{
   INJECTIONS_TEIL:
   _asm
  { mov eax,x
    add eax,y
    jmp OEP
  }
  INJECTIONS_TEIL_ENDE:
  int injSize=INJECTIONS_TEIL_ENDE-INJECTIONS_TEIL;
   open(Wirt);
   read_pe_stuff(Wirt);
   increase_last_section(Wirt, injSize);
   correct_pe_stuff(Wirt);
   memcpy(letzte_section_ende, INJECTIONS_TEIL,injSize);  
}
 
Code einfügen

Hallo,

zum dritten mal in diesem Thread: Sectioneigenschaften (ausführbar/lesbar/beschreibbar) wird im PE Header beschrieben. Wenn man die "Characteristics" der Section nun auf "ausführbar" setzt, kann der injezierte Code ausgeführt werden.
Jaaaa! Schon klar! Aber was wäre, wenn ich dann eine Section ausführbar mache, welche Daten enthält die beim Ausführen Fehler erzeugen würden??

Die Ausführung beginnt an der Stelle, auf die EntryPoint verweist. Der Codeblock an sich muss nicht unbedingt erst an dieser Stelle anfangen:
Wie finde ich denn heraus, wo dann der Code beginnt? Und was für Code steht denn beispielsweise noch vor dem EP?? Und wie wird der EP festgelegt? Zeigt der EP immer auf die main-funktion des Programms??

die größe sowie den Anfang muss man schon selbst angeben/berechnen.
Jo! Genau da liegt der Hund begraben...
Ich weiß weder Anfang noch Ende des Codes...wie will ich denn dann seine Größe brechnen?? Oder wie will ich überhaupt den Code aus meinem Injektionsprogramm herauslesen, wenn ich nicht weiß, wo er anfängt und wo er endet?? Es wäre ja falsch, wenn ich ihn erst ab dem EP auslese...denn davor steht ja auch noch Code (laut deinem letzten Post).


Grüße
Gapa
 
Der EP ist im PE Header definiert -> der kann irgendwohin zeigen. Und dort fängt dann die Ausführung an.

Der Compiler schreibt die EP Adresse, das hängt also vom Complier ab.

Ich kann dir nur raten, deine kompilierten ASM Programme mit Olly zu laden und durch zu tracen. Das sollte deinem Verständnis weiterhelfen. :)
 
Ep

Hallo,

ok der EP wird also willkürlich festgelegt (da gibts keine Regel wie z.B dass der immer auf die Main-funktion oder so was zeigt), richtig?

Aber das bringt mich ja nicht weiter bei meinem Versuch, den kompletten Code aus einer Exe zu kopieren.
Ich muss ja irgendwoher noch wissen, wie viel Code noch vor dem EntryPoint steht, denn diesen Code muss ich schließlich auch rauskopieren...

Also wie finde ich den Anfang des Codes (nicht den EP, sondern den Codeanfang in der Exe...). Und wenn ich den Codeanfang dann weiß, muss ich ab dort bis zum Dateiende den Code auslesen oder bis wohin?

Grüße
Gapa
 
luv (lesen und verstehen): http://msdn.microsoft.com/en-us/magazine/ms809762.aspx

ImageNtHead->ImageOptionalHeader->BaseOfCode.

Aber es bringt nichts, wenn du nur den Code den du dort findest kopierst, da dieser ohne Variablen, die vllt in der Datensektion stehen oder die Importtable garnicht funktioniert. Außerdem darf der Code nicht irgendwo stehen, denn dann stimmen feste Adressen die vom Code verwendet werden nicht mehr, desweiteren muss es nicht unbedingt sein, dass der Code nur in der Codesektion ist, man kann ihn auch woanders noch hinschreiben usw. usf.

Wenn du Code in ein Bild reinpacken willst und diesen dann irgendwie ausfuehren willst (was nicht moeglich ist, wenn du nur doppelt auf das Bild klickst!!!), such nach Bugs von Programmen die Bilder laden und bemuehe dich im Shellcode programmieren.
 
PE-Format

Hallo!

Wow! Super Link! Und ich habe mir wirklich alles aufmerksam durchgelesen!!

Es ist wahrhaftig schwer, so viel nützliche Info zu speichern, also hab ich mir ein paar wichtige Dinge rausgeschrieben, für die ich nun gern ne Bestätigung hätte:

1. Die Größe aller Sections zusammen ist die Größe des Programms (also nur Code / Daten (eben der wichtige Teil, welchen ich kopieren muss))

2. Die in 1. erwähnte Größe lautet "SizeOfImage" und lässt sich (Adresse weiß ich nicht mehr) auslesen

3. ImageBase ist ein Wert, welcher die erste virtuelle Adresse, die in den Speicher geladen wird, wiederspielgelt, richtig?

4. Das 1. Byte der 1. Section (.text - Section) steht somit in der Adresse : ImageBase + VA der ersten Section (kann man im Sectionarray auslesen)

5. Der EntryPoint (EP) kann irgendwo in der 1. Section stehen, richtig?

6. Code wird erst ab dem EP ausgeführt


Meine Fragen:

1.
ImageBase hat normalerweise den Wert 0x400000; Die VA der 1. Section hat den Wert 0x1000
Das erklärt wohl auch, warum die 1. Adresse in OllyDbg (egal welches Programm ich öffne (Win32)) 0x401000 lautet!

Aber Warum startet die 1. Section nicht genau auf dem ImageBase, sondern erst 0x1000 später??

2.
Wenn Code erst ab dem EP ausgeführt wird, und der EP nicht zwingend an Adresse 0x401000 sein muss, warum reagiert Olly beim Programmdurchlauf dann stehts schon bei Adresse 0x401000??
Wenn ich ein Programm in Olly öffne, welches eine MessageBox ausgibt, dann öffnet sich die MessageBox erst ein paar Adressen nach 0x401000 (bei einem Call-Befehl) - d.h., dass der EP wohl an dieser Stelle ist. Meine Register jedoch verändern sich schon bei den Befehlen davor (Bsp "PUSH 0" ist der erste Befehl (Adresse: 0x401000))


Ich glaube wenn mir jemand diese Fragen jetzt beantwortet, dann habe ichs wohl verstanden... :D

Viele Grüße
Gapa
 
RE: PE-Format

1. Jein - Zb die .reloc section und andere Sektionen werden nur zum Starten des Programmes benoetigt.
2. Nein, SizeOfImage ist der Wert, den der Loader zum Laden braucht, da ist auch der Pe-Header mit drin.
3. Grob richtig.
4. VA = ImageBase+RVA
5. Nein, der EP kann auch in der 2., 3., 4., 5. .. Sektion sein, Hauptsache ist, das dort ausfuehrbarer Code ist.
6. Nein, es kann auch gut sein, dass <EP-Adr noch Code steht und dieser kann auch ausgefuehrt werden.

Zu deinen Fragen:
1. Standardmaeßig wird noch der PE-Header mit in Speicher geladen und zwar an die ImageBase. Und die naechste moegliche Adresse ist im PE-Header definiert:
DWORD SectionAlignment When mapped into memory, each section is guaranteed to start at a virtual address that's a multiple of this value. For paging purposes, the default section alignment is 0x1000.

2. Naja irgendwie muessen ja die Parameter an MessageBox uebergeben werden und die werden nunmal auf dem Stack gelagert:

push style
push ptr to title
push ptr to caption
push handle to window
call MessageBoxA

Beim Call wird dann noch die Returnadresse aufm Stack gespeichert, damit die CPU weiß was nach dem ret ist.
 
Pe...

Hallöle noch mal,

ok aber was bringt dann der EP überhaupt?? Wofür ist der noch gut, wenn der Code nicht erst dort mit der Ausführung startet und der EP auch nicht immer auf die main-Funk. verweist?? Ich sehe nun absolut keinen Sinn in dem EP und weiß jetzt auch nicht , wieso dieser von Bedeutung ist, wenn man Code in eine Exe einfügen möchte...

Es steht nun aber fest:
Das erste Stück Code (das erste Byte Code) welches als AAALLERERSTESSSSS ausgeführt wird, ist das erste Byte der ersten Section, oder??
Also muss ich doch einfach nur die erste Section um die Größe eines "JMP-Befehls" erweitern (JMP ist glaub ich 2 oder 3 Byte...), und an diese Stelle (Anfang 1. Section) jenen JMP-Befehl zu meinem Code (Ende der letzten Section) einfügen.

Folglich ist das erste, was das Wirtprogramm macht, ein Jump zu meinem Code (der EP ist hier dann völlig egal, oder??????? Oder wofür dient denn der EP?????).

Grüße
Gapa
 
Also am EP steht die erste Instruction, die die CPU von diesem Programm ausfuehrt. Aber diese Instruction muss nicht unbedingt am Anfang der ersten Sektion stehen.

Wenn du Code in eine Exe einfuegen willst, ist es am einfachsten du erweiterst die letzte Sektion schreibst dort deinen Code hin, welcher dann zum Originalen EP springt. Dann musst du nur noch den Sektionheader anpassen und den EP auf deinen Code setzen.
 
Ep

Hallo,

jo soweit war ich ja aber auch schon...

Das einzige was ich noch nicht verstehe ist, warum ich den EP auf meinen Code umlenken muss, wenn die Programmausführung sowieso schon früher beginnt (Anfang 1. Section).

Was bringt es mir dann, wenn der EP auf meinen Code zeigt, wenn das Wirtprogramm bereits läuft...???

Ist es nicht viel logischer, einen JMP-Befehl an den Anfang der 1. Section zu setzen, welcher zu meinem Code springt, und nach Ausführung meines Codes dann wieder zurückspringt an den Anfang der 1. Section (einen Befehl hinter den JMP-Befehl natürlich, sonst hätten wir ne Endlosschleife)??

Was bedeutet "am EP steht die erste Instruction"?

Grüße
Gapa
 
Instruction = Befehl

Hier mal eine Visualisierung wie eine Codesektion aussehen _koennte_:

my.php
 
Ep

Ah..jetzt hab ichs verstanden...

D.h., dass die "Befehle" vor dem EP nur beispielsweise Funktionen sind, welche noch nichts ausführen ,da sie erst aufgerufen werden müssen (was dann im Codeabschnitt nach dem EP passiert, oder?), oder?

Das bedeutet, dass wenn ich den EP auf meinen angehängten Code setze, die CPU über alle Sections hinwegliest wie wenn es nur Funktionen wären, bis sie zu meinem angehängten Code mit dem neuen EP gelangt, und dann mit der Ausführung anfängt, richtig??

Grüße
Gapa
 
Zurück
Oben