Je pense que ton idee est fesable, apres il est vrai que comme tu ne te base pas sur une image executable pure (une section tagé comme executable), il faut que tu implementes des mecanismes toi même. Tel que le rensignement de SECTION_IMAGE_INFORMATION et biensur la relocation.
Je n’ai jamais testé alors cet à prendre au conditionnel. Il faudrait regarder dans le noyau les checks fait, mais je pense pas que ZwCreateProcess check d’une facon ou l’autre que la section a ete taggé SEC_IMAGE.
Tu n’as pas reussi à faire ce que tu voulais mais je trouve cet article très instructifs pour comprendre les étapes détaillés de la création d’un processus. So merci
2.
Parano | janvier 19th, 2008 at 23:49
Sa sens l’injection de code
3.
SynApsus | janvier 20th, 2008 at 12:48
Tout d’abord hello à toi Ivan !
Ca faisait bien longtemps que j’étais hors circuit, mais bon j’ai mes rechutes.
Je pense que tu devrais comme dit mxatone, abandonner le SEC_IMAGE qui est un peu verrouillé et coder ton moteur de chargement+relocs+IAT. ( a moins que l’IAT ne soit remplie par une autre des APIs que tu appelles )
C’est pas très dur à faire, c’est un peu méthodique c’est tout
Au pire j’ai un code à moi pr ça, mais bon l’ASM te donne des boutons non ?
Et puis ce que tu veux charger n’étant pas stricto sensu un exécutable, l’IAT et les relocs ben euh
Allez, @+ et bonne chance.
Si tu le pousses loin ton truc pourrait devenir intéressant pour lancer des binaires de n’importe quel format : tu pourrais meme definir ton IvanPE format.
4.
le concombre masqué | janvier 21st, 2008 at 09:39
Je passe sur la description d’IMAGE_OPTIONAL_HEADER. On n’est pas dans la merde.
5.
admin | janvier 21st, 2008 at 11:58
Yo,
Merci pour vos réponses mxatone et SynApsus. J’ai regardé d’un peu plus près le comportement de ZwCreateProcess dans le cas ou on lui passe une section crée sans attribut SEC_IMAGE. Pas de chance ZwCreateProcess nous renvoie STATUS_SECTION_NOT_IMAGE (0xC0000049), ce status provient de la routine MmInitializeProcessAddressSpace. Sachant que ZwCreateSection ne supporte le flag SEC_IMAGE uniquement si il existe un handle du fichier valide. Je l’ai donc bien dmc …
6.
SynApsus | janvier 21st, 2008 at 19:59
Et il se fait comment le check de MmInitializeProcessAddressSpace ? Tas ptetre moyen de fooler ça avec ton _IMAGE_IVAN_HEADERS nan ?
7.
admin | janvier 22nd, 2008 at 18:06
SynApsus, les flags de la section sont stockés dans le kernel, dans l’objet SECTION_OBJECT.
lkd> dt nt!_SECTION_OBJECT
+0x000 StartingVa : Ptr32 Void
+0x004 EndingVa : Ptr32 Void
+0x008 Parent : Ptr32 Void
+0x00c LeftChild : Ptr32 Void
+0x010 RightChild : Ptr32 Void
+0x014 Segment : Ptr32 _SEGMENT_OBJECT
lkd> dt nt!_SEGMENT_OBJECT
+0x000 BaseAddress : Ptr32 Void
+0x004 TotalNumberOfPtes : Uint4B
+0x008 SizeOfSegment : _LARGE_INTEGER
+0x010 NonExtendedPtes : Uint4B
+0x014 ImageCommitment : Uint4B
+0x018 ControlArea : Ptr32 _CONTROL_AREA
+0x01c Subsection : Ptr32 _SUBSECTION
+0x020 LargeControlArea : Ptr32 _LARGE_CONTROL_AREA
+0x024 MmSectionFlags : Ptr32 _MMSECTION_FLAGS
+0x028 MmSubSectionFlags : Ptr32 _MMSUBSECTION_FLAGS
lkd> dt nt!_MMSECTION_FLAGS
+0x000 BeingDeleted : Pos 0, 1 Bit
+0x000 BeingCreated : Pos 1, 1 Bit
+0x000 BeingPurged : Pos 2, 1 Bit
+0x000 NoModifiedWriting : Pos 3, 1 Bit
+0x000 FailAllIo : Pos 4, 1 Bit
+0x000 Image : Pos 5, 1 Bit
+0x000 Based : Pos 6, 1 Bit
+0x000 File : Pos 7, 1 Bit
+0x000 Networked : Pos 8, 1 Bit
+0x000 NoCache : Pos 9, 1 Bit
+0x000 PhysicalMemory : Pos 10, 1 Bit
+0x000 CopyOnWrite : Pos 11, 1 Bit
+0x000 Reserve : Pos 12, 1 Bit
+0x000 Commit : Pos 13, 1 Bit
+0x000 FloppyMedia : Pos 14, 1 Bit
+0x000 WasPurged : Pos 15, 1 Bit
+0x000 UserReference : Pos 16, 1 Bit
+0x000 GlobalMemory : Pos 17, 1 Bit
+0x000 DeleteOnClose : Pos 18, 1 Bit
+0x000 FilePointerNull : Pos 19, 1 Bit
+0x000 DebugSymbolsLoaded : Pos 20, 1 Bit
+0x000 SetMappedFileIoComplete : Pos 21, 1 Bit
+0x000 CollidedFlush : Pos 22, 1 Bit
+0x000 NoChange : Pos 23, 1 Bit
+0x000 HadUserReference : Pos 24, 1 Bit
+0x000 ImageMappedInSystemSpace : Pos 25, 1 Bit
+0x000 UserWritable : Pos 26, 1 Bit
+0x000 Accessed : Pos 27, 1 Bit
+0x000 GlobalOnlyPerSession : Pos 28, 1 Bit
+0x000 Rom : Pos 29, 1 Bit
+0x000 filler : Pos 30, 2 Bits
Tu vois le joli flag Image dans MMSECTION_FLAGS :p
8.
SynApsus | janvier 23rd, 2008 at 10:12
J’imagines que tu veux pas de driver, ni chercher un bug kernel pour aller reecrire ça. Et mapper une vraie image PE en memoire, quitte à re-coller sur cet espace ben tout le code que tu veux y mettre depuis un autre fichier par exemple…
Je te félicite pour tout le travail que tu effectue
10.
martin | février 12th, 2008 at 07:41
De ce que je peux voir le proc demarre bien, mais ldrpinitialize() fait une exception qui fait une exception, qui fait une exception…
Un pb de pile ?
11.
admin | février 13th, 2008 at 10:59
Vista, XP ?
12.
martin | février 13th, 2008 at 15:59
Xp sp2, sorry. J’ai un peu + d’infos…
peb/teb sont invalides d’apres windbg.
le flag SYNCHRONIZE et FILE_READ_SHARE c’est pas trop apprecie par le SEC_IMAGE donc la section est pas mappe sur xp. Ensuite
J’ai du supprimer le RtlCopymem ca plantait tout le temps car la section est RO de toute facon sur xp sp2 ?!
Le getContext du thread ne fonctionne pas jai que des 0 dans les registres,c’est pas terrible.
Sinon en mettant un brkptr avec windbg sur le retour de la livraison APC du threadcreate dans le process nouvellement cree on voit que c’est le iretd en sortant du chgt de context pour demarrer le thread qui est foireux. la pile cree pointe n’est pas bonne.
A suivre…
15 Comments
1. mxatone | janvier 19th, 2008 at 09:30
Je pense que ton idee est fesable, apres il est vrai que comme tu ne te base pas sur une image executable pure (une section tagé comme executable), il faut que tu implementes des mecanismes toi même. Tel que le rensignement de SECTION_IMAGE_INFORMATION et biensur la relocation.
Je n’ai jamais testé alors cet à prendre au conditionnel. Il faudrait regarder dans le noyau les checks fait, mais je pense pas que ZwCreateProcess check d’une facon ou l’autre que la section a ete taggé SEC_IMAGE.
Tu n’as pas reussi à faire ce que tu voulais mais je trouve cet article très instructifs pour comprendre les étapes détaillés de la création d’un processus. So merci
2. Parano | janvier 19th, 2008 at 23:49
Sa sens l’injection de code
3. SynApsus | janvier 20th, 2008 at 12:48
Tout d’abord hello à toi Ivan !
Ca faisait bien longtemps que j’étais hors circuit, mais bon j’ai mes rechutes.
Je pense que tu devrais comme dit mxatone, abandonner le SEC_IMAGE qui est un peu verrouillé et coder ton moteur de chargement+relocs+IAT. ( a moins que l’IAT ne soit remplie par une autre des APIs que tu appelles )
C’est pas très dur à faire, c’est un peu méthodique c’est tout
Au pire j’ai un code à moi pr ça, mais bon l’ASM te donne des boutons non ?
Et puis ce que tu veux charger n’étant pas stricto sensu un exécutable, l’IAT et les relocs ben euh
Allez, @+ et bonne chance.
Si tu le pousses loin ton truc pourrait devenir intéressant pour lancer des binaires de n’importe quel format : tu pourrais meme definir ton IvanPE format.
4. le concombre masqué | janvier 21st, 2008 at 09:39
tu pourrais meme definir ton IvanPE format.
Je passe sur la description d’IMAGE_OPTIONAL_HEADER. On n’est pas dans la merde.
5. admin | janvier 21st, 2008 at 11:58
Yo,
Merci pour vos réponses mxatone et SynApsus. J’ai regardé d’un peu plus près le comportement de ZwCreateProcess dans le cas ou on lui passe une section crée sans attribut SEC_IMAGE. Pas de chance ZwCreateProcess nous renvoie STATUS_SECTION_NOT_IMAGE (0xC0000049), ce status provient de la routine MmInitializeProcessAddressSpace. Sachant que ZwCreateSection ne supporte le flag SEC_IMAGE uniquement si il existe un handle du fichier valide. Je l’ai donc bien dmc …
6. SynApsus | janvier 21st, 2008 at 19:59
Et il se fait comment le check de MmInitializeProcessAddressSpace ? Tas ptetre moyen de fooler ça avec ton _IMAGE_IVAN_HEADERS nan ?
7. admin | janvier 22nd, 2008 at 18:06
SynApsus, les flags de la section sont stockés dans le kernel, dans l’objet SECTION_OBJECT.
Tu vois le joli flag Image dans MMSECTION_FLAGS :p
8. SynApsus | janvier 23rd, 2008 at 10:12
J’imagines que tu veux pas de driver, ni chercher un bug kernel pour aller reecrire ça. Et mapper une vraie image PE en memoire, quitte à re-coller sur cet espace ben tout le code que tu veux y mettre depuis un autre fichier par exemple…
9. akhenathon | janvier 30th, 2008 at 17:02
Encore une fois un très bon article
Je te félicite pour tout le travail que tu effectue
10. martin | février 12th, 2008 at 07:41
De ce que je peux voir le proc demarre bien, mais ldrpinitialize() fait une exception qui fait une exception, qui fait une exception…
Un pb de pile ?
11. admin | février 13th, 2008 at 10:59
Vista, XP ?
12. martin | février 13th, 2008 at 15:59
Xp sp2, sorry. J’ai un peu + d’infos…
peb/teb sont invalides d’apres windbg.
le flag SYNCHRONIZE et FILE_READ_SHARE c’est pas trop apprecie par le SEC_IMAGE donc la section est pas mappe sur xp. Ensuite
J’ai du supprimer le RtlCopymem ca plantait tout le temps car la section est RO de toute facon sur xp sp2 ?!
Le getContext du thread ne fonctionne pas jai que des 0 dans les registres,c’est pas terrible.
Sinon en mettant un brkptr avec windbg sur le retour de la livraison APC du threadcreate dans le process nouvellement cree on voit que c’est le iretd en sortant du chgt de context pour demarrer le thread qui est foireux. la pile cree pointe n’est pas bonne.
A suivre…
13. Ben | février 17th, 2008 at 00:51
Very interesting article, thanks.
14. barton | août 17th, 2008 at 15:08
true xek!11
15. broucaries | avril 6th, 2011 at 11:39
Des nouvelles ? Cela m’interesse pour implementer un vrai exec sous windows ou meme un fork pour gnulib
Trackback this post