Skip to content

Commit 7c8d7ed

Browse files
committed
Initial
0 parents  commit 7c8d7ed

File tree

4 files changed

+258
-0
lines changed

4 files changed

+258
-0
lines changed

Makefile

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# SUID-Locate Makefile
2+
3+
# Compilation Parameters
4+
CC=gcc
5+
CFLAGS= -Iincludes -Wextra -Wall
6+
SOURCES= suid_locate.c
7+
8+
all:
9+
$(CC) $(SOURCES) $(CFLAGS) -o suid-locate
10+
clean:
11+
rm -f suid-locate

README.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# SUID-Locate
2+
3+
Files with SUID/SGID can be very handy when properly used, however, it can expose your system to many security risks.
4+
SUID-Locate easily finds files with the SUID or SGID bit on in your linux system.
5+

suid_locate.c

+188
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
/*******************************************************************
2+
* Project: SUID-Locate
3+
* SUID-Locate searches for files with the SUID/SGID
4+
* bit on.
5+
*
6+
* Author: Kfiros (Kfir Shtober)
7+
* Year: 2015
8+
*
9+
* File: suid_locate.c
10+
* Description: Easily finds files with the SUID or SGID bit on.
11+
* Setuid/gid can be very handy when properly used,
12+
* however, it can expose your system to many security
13+
* risks.
14+
*******************************************************************/
15+
16+
/*******************************************************************
17+
* Includes
18+
*******************************************************************/
19+
#include <stdio.h>
20+
#include <stdlib.h>
21+
#include <string.h>
22+
#include <sys/types.h>
23+
#include <sys/user.h>
24+
#include <sys/stat.h>
25+
#include <dirent.h>
26+
#include "suid_locate.h"
27+
28+
/*******************************************************************
29+
* Name: exclude_path
30+
* Description: This function decides whether a specific path
31+
* should be excluded.
32+
*******************************************************************/
33+
static bool exclude_path(const char * path) {
34+
bool ret = false;
35+
36+
if (NULL == path) {
37+
ret = true;
38+
goto cleanup;
39+
}
40+
41+
/* Avoid /proc directory */
42+
if (0 == strncmp(path, PROC_DIR, PROC_DIR_LENGTH)) {
43+
ret = true;
44+
goto cleanup;
45+
}
46+
47+
cleanup:
48+
return ret;
49+
}
50+
51+
/*******************************************************************
52+
* Name: check_suid
53+
* Description: Tests for SUID/GUID bit turned on a given path.
54+
*******************************************************************/
55+
static int check_suid(const char * path, OUT bool * is_suid) {
56+
int ret = SUCCESS;
57+
int call_rv;
58+
struct stat path_stat;
59+
60+
/* Get file status */
61+
call_rv = stat(path, &path_stat);
62+
if (ERROR == call_rv) {
63+
ret = ERROR;
64+
goto cleanup;
65+
}
66+
67+
/* Check if SUID/SGID bit is turned on */
68+
if ((ISUID_ON(path_stat)) || (ISGID_ON(path_stat))) {
69+
*is_suid = true;
70+
goto cleanup;
71+
} else {
72+
*is_suid = false;
73+
}
74+
cleanup:
75+
return ret;
76+
}
77+
78+
/*******************************************************************
79+
* Name: invalid_dir
80+
* Description: Examines if a given directory name is invalid.
81+
*******************************************************************/
82+
static bool invalid_dir_name(const char * name) {
83+
bool ret = false;
84+
85+
if (NULL == name) {
86+
ret = true;
87+
goto cleanup;
88+
}
89+
90+
if ((THIS_FOLDER_LENGTH == strlen(name)) &&
91+
(0 == strncmp(name, THIS_FOLDER_STRING, THIS_FOLDER_LENGTH))) {
92+
ret = true;
93+
goto cleanup;
94+
}
95+
96+
if ((UPPER_FOLDER_LENGTH == strlen(name)) &&
97+
(0 == strncmp(name, UPPER_FOLDER_STRING, UPPER_FOLDER_LENGTH))) {
98+
ret = true;
99+
goto cleanup;
100+
}
101+
102+
cleanup:
103+
return ret;
104+
}
105+
106+
/*******************************************************************
107+
* Name: analyze_entry
108+
* Description: This function analyzes a given direntry. In case it's a
109+
* directory it lists it, and in case of file it checks
110+
* it for suid/sgid.
111+
*******************************************************************/
112+
inline static void analyze_entry(const char * path, struct dirent * entry) {
113+
int call_rv;
114+
char full_entry_path[MAX_PATH_LENGTH];
115+
bool is_suid = false;
116+
117+
if (DT_DIR == entry->d_type) { /* DIRECTORY */
118+
if (true == invalid_dir_name(entry->d_name)) {
119+
return;
120+
}
121+
/* Create updated full path */
122+
snprintf(full_entry_path, MAX_PATH_LENGTH, "%s/%s", path, entry->d_name);
123+
124+
if (true == exclude_path(full_entry_path)) {
125+
return;
126+
}
127+
128+
/* Recursively walk over the directory contents */
129+
scan_suid_by_dir(full_entry_path);
130+
131+
} else { /* FILE */
132+
/* Create updated full path */
133+
snprintf(full_entry_path, MAX_PATH_LENGTH, "%s/%s", path, entry->d_name);
134+
135+
/* Check for suid/sgid */
136+
call_rv = check_suid(full_entry_path, &is_suid);
137+
if (SUCCESS != call_rv) {
138+
return;
139+
} else if(true == is_suid){
140+
fprintf(stdout, "[+] %s\n", full_entry_path + 1); /* + 1 to avoid the first slash */
141+
}
142+
}
143+
}
144+
145+
/*******************************************************************
146+
* Name: scan_suid_by_dir
147+
* Description: Recursively scans the given path for suid/sgid files.
148+
*******************************************************************/
149+
static void scan_suid_by_dir(const char * path) {
150+
DIR * dir_stream;
151+
struct dirent * entry;
152+
153+
dir_stream = opendir(path);
154+
if (NULL == dir_stream) {
155+
return;
156+
}
157+
158+
entry = readdir(dir_stream);
159+
if (NULL == entry) {
160+
goto cleanup;
161+
}
162+
163+
do {
164+
analyze_entry(path, entry);
165+
166+
} while ((entry = readdir(dir_stream)));
167+
cleanup:
168+
if (NULL != dir_stream) {
169+
closedir(dir_stream);
170+
}
171+
}
172+
173+
/*******************************************************************
174+
* Name: main
175+
* Description: Main function of the program
176+
*******************************************************************/
177+
int main() {
178+
fprintf(stdout, "[*] suid-locate (Kfiros 2015) \n");
179+
fprintf(stdout, "[*] Searching for SUID/SGID files in your system... \n");
180+
181+
/* Start main logic */
182+
scan_suid_by_dir(DIR_PATH);
183+
184+
fprintf(stdout, "[*] DONE \n");
185+
186+
return SUCCESS;
187+
}
188+

suid_locate.h

+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/*******************************************************************
2+
* Project: SUID-Locate
3+
* SUID-Locate searches for files with the SUID/SGID
4+
* bit on.
5+
*
6+
* Author: Kfiros (Kfir Shtober)
7+
* Year: 2015
8+
*
9+
* File: suid_locate.c
10+
* Description: Easily finds files with the SUID or SGID bit on.
11+
* Setuid/gid can be very handy when properly used,
12+
* however, it can expose your system to many security
13+
* risks.
14+
*******************************************************************/
15+
16+
#ifndef __SUID_LOCATE_H__
17+
#define __SUID_LOCATE_H__
18+
19+
/*******************************************************************
20+
* Constants & Macros
21+
*******************************************************************/
22+
23+
typedef enum {
24+
false = 0,
25+
true,
26+
} bool;
27+
28+
#define SUCCESS (0)
29+
#define ERROR (-1)
30+
#define OUT
31+
32+
#define DIR_PATH ("/")
33+
#define MAX_PATH_LENGTH (255)
34+
35+
#define PROC_DIR ("//proc\0")
36+
#define PROC_DIR_LENGTH (5)
37+
38+
#define ISUID_ON(stat) ((S_ISUID == (S_ISUID & stat.st_mode)) && (S_IXUSR == (S_IXUSR & stat.st_mode)))
39+
#define ISGID_ON(stat) ((S_ISGID == (S_ISGID & stat.st_mode)) && (S_IXGRP == (S_IXGRP & stat.st_mode)))
40+
41+
42+
/* '.' and '..' are two known invalid directories,
43+
* we need to handle it properly */
44+
#define THIS_FOLDER_STRING (".")
45+
#define THIS_FOLDER_LENGTH (1)
46+
#define UPPER_FOLDER_STRING ("..")
47+
#define UPPER_FOLDER_LENGTH (2)
48+
49+
/*******************************************************************
50+
* Prototypes
51+
*******************************************************************/
52+
static void scan_suid_by_dir(const char * path);
53+
54+
#endif /* __SUID_LOCATE_H__*/

0 commit comments

Comments
 (0)