-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdriver.c
More file actions
executable file
·160 lines (136 loc) · 3.89 KB
/
driver.c
File metadata and controls
executable file
·160 lines (136 loc) · 3.89 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
#include <stdio.h>
#include <stdarg.h>
#include <unistd.h>
#include <assert.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
#define MAX_GRP 100
/******************************************************************************
Unless you are interested in the details of how this program communicates
with a subprocess, you can skip all of the code below and skip directly to
the main function below.
*******************************************************************************/
#define err_abort(x) do { \
if (!(x)) {\
fprintf(stderr, "Fatal error: %s:%d: ", __FILE__, __LINE__); \
perror(""); \
exit(1);\
}\
} while (0)
char buf[1<<20];
unsigned end;
int from_child, to_child;
void print_escaped(FILE *fp, const char* buf, unsigned len) {
int i;
for (i=0; i < len; i++) {
if (isprint(buf[i]))
fputc(buf[i], stderr);
else fprintf(stderr, "\\x%02hhx", buf[i]);
}
}
void put_bin_at(char b[], unsigned len, unsigned pos) {
assert(pos <= end);
if (pos+len > end)
end = pos+len;
assert(end < sizeof(buf));
memcpy(&buf[pos], b, len);
}
void put_bin(char b[], unsigned len) {
put_bin_at(b, len, end);
}
void put_formatted(const char* fmt, ...) {
va_list argp;
char tbuf[10000];
va_start (argp, fmt);
vsnprintf(tbuf, sizeof(tbuf), fmt, argp);
put_bin(tbuf, strlen(tbuf));
}
void put_str(const char* s) {
put_formatted("%s", s);
}
static
void send() {
err_abort(write(to_child, buf, end) == end);
usleep(100000); // sleep 0.1 sec, in case child process is slow to respond
fprintf(stderr, "driver: Sent:'");
print_escaped(stderr, buf, end);
fprintf(stderr, "'\n");
end = 0;
}
char outbuf[1<<20];
int get_formatted(const char* fmt, ...) {
va_list argp;
va_start(argp, fmt);
usleep(100000); // sleep 0.1 sec, in case child process is slow to respond
int nread=0;
err_abort((nread = read(from_child, outbuf, sizeof(outbuf)-1)) >=0);
outbuf[nread] = '\0';
fprintf(stderr, "driver: Received '%s'\n", outbuf);
return vsscanf(outbuf, fmt, argp);
}
int pid;
void create_subproc(const char* exec, char* argv[]) {
int pipefd_out[2];
int pipefd_in[2];
err_abort(pipe(pipefd_in) >= 0);
err_abort(pipe(pipefd_out) >= 0);
if ((pid = fork()) == 0) { // Child process
err_abort(dup2(pipefd_in[0], 0) >= 0);
close(pipefd_in[1]);
close(pipefd_out[0]);
err_abort(dup2(pipefd_out[1], 1) >= 0);
err_abort(execve(exec, argv, NULL) >= 0);
}
else { // Parent
close(pipefd_in[0]);
to_child = pipefd_in[1];
from_child = pipefd_out[0];
close(pipefd_out[1]);
}
}
/* Shows an example session with subprocess. Change it as you see fit, */
#define STRINGIFY2(X) #X
#define STRINGIFY(X) STRINGIFY2(X)
int main(int argc, char* argv[]) {
unsigned seed;
char *nargv[3];
nargv[0] = "vuln";
nargv[1] = STRINGIFY(GRP);
nargv[2] = NULL;
create_subproc("./vuln", nargv);
// print something from the stack
put_str("e %x %x %x\n");
send();
// extract something (e.g., the second element) from output
int i;
get_formatted("%*x%x%*x", &i);
fprintf(stderr, "driver: Extracted %x\n", i);
// Now, do more things, e.g., prepare a stack smashing payload
put_str("p xyz\n");
send();
put_str("u aaaaaaaaaaaaaaaaaaa");
send();
put_str("l \n");
send();
usleep(100000);
get_formatted("%*s");
kill(pid, SIGINT);
int status;
wait(&status);
if (WIFEXITED(status)) {
fprintf(stderr, "vuln exited, status=%d\n", WEXITSTATUS(status));
}
else if (WIFSIGNALED(status)) {
printf("vuln killed by signal %d\n", WTERMSIG(status));
}
else if (WIFSTOPPED(status)) {
printf("vuln stopped by signal %d\n", WSTOPSIG(status));
}
else if (WIFCONTINUED(status)) {
printf("vuln continued\n");
}
}