-
Notifications
You must be signed in to change notification settings - Fork 7
/
secure.cpp
139 lines (123 loc) · 4.62 KB
/
secure.cpp
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
#include <signal.h>
#include <syscall.h>
#include <sys/ptrace.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/user.h>
#include <sys/reg.h>
#include <sys/syscall.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <sys/resource.h>
#include <time.h>
#include <unistd.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <string>
#define GetCurrentDir getcwd
#define _GNU_SOURCE
#define _FILE_OFFSET_BITS 64
void usage();
int main(int argc, char **argv)
{
struct rlimit old,newa;
struct rlimit *newp;
newa.rlim_cur = 5120;
newa.rlim_max = 5120;
newp = &newa;
char cCurrentPath[FILENAME_MAX];
if (!GetCurrentDir(cCurrentPath, sizeof(cCurrentPath)))
{
return -1;
}
cCurrentPath[sizeof(cCurrentPath) - 1] = '\0'; /* not really required */
// printf ("The current working directory is %s\n", cCurrentPath);
if(argc < 2)
usage();
std::string file1 = cCurrentPath;
// file1.append(argv[1]);
file1.append("/function");
//printf("%s\n", file1.c_str());
const char* fileloc = file1.c_str();
int i;
pid_t child;
int status;
long orig_eax;
int kill_ret = 0;
child = fork();
if(child == 0)
{
ptrace(PTRACE_TRACEME, 0, NULL, NULL);
execl(fileloc, fileloc, NULL);
}
else
{
if(prlimit(child, RLIMIT_CPU, newp, &old) == -1) {
fprintf(stderr, "%s\n", "Unable to set PRLIMIT");
kill_ret = kill(child, SIGKILL);
if (kill_ret == -1)
fprintf(stderr, "Failed to kill ---> %s\n", strerror(errno));
return 1;
} else {
prlimit(child, RLIMIT_CPU, NULL, &old);
fprintf(stderr, "new limt %d soft: %lld hard: %lld\n", child, (long long) old.rlim_cur, (long long) old.rlim_max);
}
bool filevar = false, kill_check = false, init_stdio = false, stdio = false;
i = 0;
while(1)
{
wait(&status);
if (WIFEXITED(status) || WIFSIGNALED(status) )
break;
orig_eax = ptrace(PTRACE_PEEKUSER, child, 8 * ORIG_RAX, NULL);
if(orig_eax != 12 && orig_eax != 2)
filevar = false;
if(orig_eax != 5 && orig_eax != 9)
init_stdio = false;
if(!(orig_eax < 3) && orig_eax != 9)
stdio = false;
switch (orig_eax)
{
case 257: //for opendir
kill_check = true;
case 1: //for file open write
if(!stdio) kill_check = true;
case 0: //for file open read
case 2: //for file open both
if(filevar && !stdio)
kill_check = true;
if(kill_check) fprintf(stderr, "Invalid System Call: FILE_ACCESS\n");
break;
case 5:
init_stdio = true;
break;
case 9:
if(init_stdio) stdio = true;
break;
case 12: //is needed for file.open()
filevar = true;
break;
case 87: //for stdlib remove()
case 56: //for system call
fprintf(stderr, "Invalid System Call: SYST_CALL\n");
kill_check = true;
break;
}
if(kill_check) {
kill_ret = kill(child, SIGKILL);
if (kill_ret == -1)
fprintf(stderr, "Failed to kill ---> %s\n", strerror(errno));
}
if(argc > 3) printf("%d time, system call %ld\n", i++, orig_eax);
ptrace(PTRACE_SYSCALL, child, NULL, NULL);
}
}
return 0;
}
void usage() {
printf("./secure <randomchars> <type>\n");
exit(0);
}