Skip to content

Commit

Permalink
fs: suspicious-fs: Introduce kstat spoofing
Browse files Browse the repository at this point in the history
fs: suspicious-fs: Introduce kstat spoofing

This allow you to modify other files' stat.

Some detection methods check for time consistency, filesize and not file content.

Signed-off-by: simonpunk <[email protected]>
  • Loading branch information
simonpunk authored and backslashxx committed Mar 21, 2024
1 parent 41aa4b4 commit e0ab5c6
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 0 deletions.
6 changes: 6 additions & 0 deletions fs/stat.c
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,12 @@ int vfs_fstatat(int dfd, const char __user *filename, struct kstat *stat,
goto out;

error = vfs_getattr(&path, stat);

#ifdef CONFIG_SUS_FS
if (!error)
check_if_spoof_kstat(&path, stat);
#endif

path_put(&path);
if (retry_estale(error, lookup_flags)) {
lookup_flags |= LOOKUP_REVAL;
Expand Down
48 changes: 48 additions & 0 deletions fs/suspicious.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,54 @@ static uid_t getuid(void) {

}

static void do_spoof_kstat_hosts(struct kstat* const stat) {
// Change the HOSTS_TIME for atime,mtime,ctime accordingly
#define HOSTS_TIME 1230768000 //since Epoch: 1230768000 -> 2009-01-01 08:00:00.000000000
// Change the HOSTS_SIZE for file size accordingly */
#define HOSTS_SIZE 56
if (stat != NULL) {
// assign your own value below accordingly
stat->atime.tv_sec = HOSTS_TIME;
stat->atime.tv_nsec = 0;
stat->mtime.tv_sec = HOSTS_TIME;
stat->mtime.tv_nsec = 0;
stat->ctime.tv_sec = HOSTS_TIME;
stat->ctime.tv_nsec = 0;
//uncomment 'stat->size' below if you need to spoof the file size as well
// stat->size = HOSTS_SIZE;
}
}

static const char* const spoof_kstat_paths[] = {
"/system/etc/hosts"
};
// Be careful to not mess up the order with 'spoof_kstat_paths[]'
static void (*fn_ptr_spoof_kstat[])(struct kstat* const) = {
do_spoof_kstat_hosts
};

void check_if_spoof_kstat(struct path* const path, struct kstat* const stat) {
char pathname[128]; // change to a larger buffer size if there are longer absolute path names you want to spoof
char *p_pathname;
int index;

if (!uid_matches()) {
return;
}

for (index = 0; index < ARRAY_SIZE(spoof_kstat_paths); index++) {
p_pathname = d_path(path, pathname, sizeof(pathname));
if (!IS_ERR(p_pathname)) {
const char* const name = spoof_kstat_paths[index];
if (memcmp(name, p_pathname, strlen(name)) == 0) {
printk(KERN_INFO "suspicious-fs: spoofing kstat for path '%s' to process with UID %i\n", name, getuid());
fn_ptr_spoof_kstat[index](stat);
return;
}
}
}
}

int is_suspicious_path(const struct path* const file)
{

Expand Down
1 change: 1 addition & 0 deletions include/linux/suspicious.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#define getname_safe(name) (name == NULL ? ERR_PTR(-EINVAL) : getname(name))
#define putname_safe(name) (IS_ERR(name) ? NULL : putname(name))

void check_if_spoof_kstat(struct path* const path, struct kstat* const stat);
int is_suspicious_path(const struct path* const file);
int is_suspicious_mount(struct vfsmount* const mnt, const struct path* const root);
int suspicious_path(const struct filename* const name);
Expand Down

0 comments on commit e0ab5c6

Please sign in to comment.