find-writable-things/app.c

92 lines
2.3 KiB
C
Raw Normal View History

/*
* =====================================================================================
*
* Filename: app.c
*
* Description: playing with finding writable files or directories on the host
*
* Version: 1.0
* Created: 10/20/2023 06:41:29 PM
* Revision: none
* Compiler: gcc
*
* Author: Vincent Batts <vbatts@hashbangbash.com>
*
* =====================================================================================
*/
#define _XOPEN_SOURCE 500
#include <ftw.h>
#include <linux/limits.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <limits.h>
uid_t uid;
gid_t gid;
int ngroups;
gid_t groups[NGROUPS_MAX];
int
check_dir(const char *fpath, const struct stat *sb,
int typeflag, struct FTW *ftwbuf) {
int finding = 0;
if (sb->st_uid != uid && sb->st_mode & S_IWOTH)
finding |= 1;
if (sb->st_uid != uid && sb->st_gid == gid && sb->st_mode & S_IWGRP)
finding |= 2;
for (int i = 0; i < ngroups; i++) {
if (sb->st_uid != uid && sb->st_gid == groups[i] && sb->st_mode & S_IWGRP)
finding |= 4;
}
if (typeflag == FTW_SLN || typeflag == FTW_SL)
return 0;
if (finding != 0) {
printf("--> %s (m: %jo; t: %s; uid: %d; gid: %d)\n", fpath,
(uintmax_t) sb->st_mode,
(typeflag == FTW_D) ? "d" : (typeflag == FTW_F) ? "f" :
(typeflag == FTW_SL) ? "sl" : (typeflag == FTW_SLN) ? "sln" : "???",
sb->st_uid,
sb->st_gid);
if (finding&1)
printf(" owned by another user and is world writable\n");
if (finding&2)
printf(" owned by another user and is group writable by our group\n");
if (finding&4)
printf(" owned by another user and is group writable by a group we are a member of\n");
}
return EXIT_SUCCESS;
}
int
main(int argc, char** argv) {
uid = geteuid();
gid = getegid();
ngroups = getgroups(NGROUPS_MAX, groups);
int flags = 0;
flags |= FTW_PHYS; // don't follow symlinks
for (int i = 1; i < argc; i++) {
printf("arg[%d] %s\n", i, argv[i]);
int ret;
ret = nftw(argv[i], &check_dir, 1024, flags);
if (ret != EXIT_SUCCESS) {
printf("FAILURE walking %s\n", argv[i]);
}
}
return EXIT_SUCCESS;
}