Author Topic: Alternativní ASM kód  (Read 858 times)

RubberDuck

  • Trial Member
  • **
  • Posts: 74
    • sec-cave.cz
Alternativní ASM kód
« on: October 20, 2019, 04:01:17 AM »
Ahoj.
Řeším takový malý problém a myslím si, že asi řešení mít nebude. Ale tak zkusím to i tady mezi odborníky :)

Potřebuji programově dostat adresu TIBu. Stanradně ho stačí získat přes registr FS (teď neřešme, zda se jedná o 32-bit nebo 64-bit nebo 32-bit na 64-bit systému):

mov eax, fs:[18h]

Moje otázka zní: Je možné tento kód nahradit nějakou alternativou se stejnou funkcionalitou? Tím myslím, zda je možné například získat adresu registru FS a pak se jen posunout na položku 18h struktury. Osobně se myslím, že to možné není z toho důvodu, že by pak byl registr FS vlastně na nic.

Kockatá hlava

  • Junior Member
  • ***
  • Posts: 134
  • n00b
    • x86asm.net
Re: Alternativní ASM kód
« Reply #1 on: October 20, 2019, 06:34:17 PM »
Muzes nastavit svuj SEH handler a hodit exception?

EDIT: a muzes zavolat GetThreadSelectorEntry?
« Last Edit: October 20, 2019, 06:42:38 PM by Kockatá hlava »

RubberDuck

  • Trial Member
  • **
  • Posts: 74
    • sec-cave.cz
Re: Alternativní ASM kód
« Reply #2 on: October 20, 2019, 06:48:42 PM »
Muzes nastavit svuj SEH handler a hodit exception?

EDIT: a muzes zavolat GetThreadSelectorEntry?

Mohl bych. Ale je to z pohledu shellcodů a dnes už systémy mají SEH hardened (SafeSEH a SEHOP), takže tam kód jen tak nespustíš. A TIB právě potřebuji, abych se přes něj dostal k adrese DLL knihovny kernel32.dll a dále pak k potřebným API funkcím.

Kockatá hlava

  • Junior Member
  • ***
  • Posts: 134
  • n00b
    • x86asm.net
Re: Alternativní ASM kód
« Reply #3 on: October 20, 2019, 07:22:27 PM »
A hodnota registru FS v main threadu se neda nejak uhodnout? Neni to treba vzdycky 0x53 nebo takova nejaka konstanta?

RubberDuck

  • Trial Member
  • **
  • Posts: 74
    • sec-cave.cz
Re: Alternativní ASM kód
« Reply #4 on: October 20, 2019, 07:43:43 PM »
A hodnota registru FS v main threadu se neda nejak uhodnout? Neni to treba vzdycky 0x53 nebo takova nejaka konstanta?

Jako hodnota registru FS byla na testovaném systému stejná. Ale je otázkou, jestli se nemění s tím, jak je binárka zkompilovaná. Jako na adrese fs:[18h] je adresa TIBu, takže kdybys šel bajt po bajtu v rozsahu 00000000-7FFFFFFF (při standardní kompilaci by mělo stačit jít po adresu 00400000h, což je 'standardizovaná' Base Address EXE souborů - když nepočítám některé historické odchylky, když Base Address byla na adrese 10000000h) a kontroloval, jestli aktuálně nalezená hodnota v paměti se rovná hodnotě adresa o 18h bajtů předem, našel jsi adresu TIBu. Ale to mi příjde jako hóóóóódně velký kanón na vrabce.

Kockatá hlava

  • Junior Member
  • ***
  • Posts: 134
  • n00b
    • x86asm.net
Re: Alternativní ASM kód
« Reply #5 on: October 20, 2019, 09:30:44 PM »
Kdyby fungovalo to procházení pamětí, o kterým píšeš, tak by to byla pohoda. Jenže ne na všech adresách je alokovaná paměť, takže by to házelo exceptions, a to si asi nemůžeš dovolit.

FS se určitě nemění s tím, jak je binárka zkompilovaná. Přečti si něco o segmentaci v protected módu :P Při vytváření threadu systém vytvoří segment a segment selector dá do FS. Myslel bych si, že pro main thread bude tenhle selector vždycky stejnej, ale nedaří se mi to vygooglit. Třeba u CS je to jasný, ten je na x86 vždycky 0x23.

Získání té hodnoty by se dalo možná udělat trikově. Všechny segmenty kromě toho, na kterej ukazuje FS, mají limit 0xFFFFFFFF (je to vidět třeba v OllyDbg). Takže by se dalo zkusit:

Code: [Select]
mov eax, 0x23   ; 0x23 je CS selector, FS selector bude nejspíš vyšší hodnota
next:
 inc eax
 cmp eax, nejaka_rozumna_max_hodnota
 ja fail   ; nenalezeno
 lsl ecx, eax   ; Load Segment Limit
 jnz next   ; selector neexistuje
 cmp ecx, 0xFFFFFFFF
 je next   ; nejde o FS selector

; teď je v eax FS selector

Takže takhle by šla do EAX získat hodnota FS bez toho, abys musel dělat mov eax, fs.

EDIT: tímhle kódem by ses možná dostal k selektoru jinýho threadu, než svojeho, ale to by ti asi nevadilo.

Dál by šlo udělat třeba:

Code: [Select]
mov gs, eax
mov eax, gs:[18h]

nebo

Code: [Select]
push ds
mov ds, eax
mov eax, ds:[18h]
pop ds
« Last Edit: October 20, 2019, 09:33:57 PM by Kockatá hlava »

pr0p4g4nd4

  • [SCF]
  • Senior Member
  • ****
  • Posts: 429
Re: Alternativní ASM kód
« Reply #6 on: October 23, 2019, 11:18:42 AM »
ale to si mal napisat hned, ze to chces pre shellkod. ak mozes prehladavat sekcie spustitelneho suboru nahrane v pamati, tak prehladavaj sekciu obsahujucu kod (zvycajne prva sekcia) pre takuto vec (tieto byty):

FF 25 ?? ?? ?? ??

za predpokladu, ze dany proces ma nejaku importovanu kernel32 apicku, tak urcite najdes adresu nejakej kernel32 api funkcie a z nej potom imagebase a potom ten vyuzijes v nejake svojemu custom getprocaddress kodu.

alebo napriklad mozes prehladat stack hlavneho threadu - na jeho uplnom konci, by mali byt adresy odkazujuce na kernel32 (alebo minimalne ja to tak mam, je mozne ze sa to jednotlivymi verziami windows meni). skusaj adresy, napr mas nejaku adresu (ktoru si ziskal zo stack) 77D31C62, daj prec prvych 5 cisel (tj 77D00000) a skusaj danu adresu na MZ signaturu.
Aký je rozdiel medzi mladým a starým chlapom?
Mladému behá piča po rozume, starému po byte...

Kto robí je robot, kto koktá je.. koktavý!

Kockatá hlava

  • Junior Member
  • ***
  • Posts: 134
  • n00b
    • x86asm.net
Re: Alternativní ASM kód
« Reply #7 on: October 26, 2019, 08:43:26 PM »
Na Win x86 by při startu (hlavního) threadu měla být poslední položka na stacku adresa uvnitř BaseThreadInitThunk nebo BaseProcessStartThunk v kernel32.dll. Viz třeba https://stackoverflow.com/a/41396596/1051180.

Takže pro získání adresy někde v kernel32 stačí MOV EAX, [ESP].