Last active
September 24, 2021 16:20
-
-
Save FergusInLondon/7ab987b4051a1e594d47903d6ef7ac4c to your computer and use it in GitHub Desktop.
LD_PRELOAD Code Injection and Hooking
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* filesnooper.c - Fergus In London <[email protected]> | |
* | |
* Similar to snoopy.c, wrote to scratch an itch and demonstrate how LD_PRELOAD | |
* can be used for injecting code and/or hooking/wrapping around function calls. | |
* | |
* This is actually a good example, because if you try and use it with different | |
* ways of writing files, you'll see that to actually do this effectively you'd | |
* need to examine the target binary with strace, and potentially implement | |
* signatures from other libraries. (i.e a binary calling fprintf() may not be | |
* be effected by this.) | |
*/ | |
#define _GNU_SOURCE | |
#include <dlfcn.h> | |
#include <stdio.h> | |
#include <string.h> | |
#include <unistd.h> | |
#define MAX_FILE_PATH 255 | |
#define FILE_TARGET "secret.txt" | |
static ssize_t (*real_write)(int fd, const void *buf, size_t count) = NULL; | |
ssize_t write(int fildes, const void *buf, size_t nbytes) { | |
// Ignore STDOUT and STDERR | |
if (fildes < 3){ | |
goto passthrough; | |
} | |
// Determine filepath via the file descriptor | |
char linkpath[MAX_FILE_PATH]; | |
sprintf(linkpath, "/proc/self/fd/%d", fildes); | |
char filepath[MAX_FILE_PATH]; | |
ssize_t pathLength = readlink(linkpath, filepath, MAX_FILE_PATH); | |
// Check that the path is valid and readlink worked, additionally check filename | |
if ((pathLength < 0) || (strstr(filepath, FILE_TARGET) == NULL)){ | |
goto passthrough; | |
} | |
// Filename matches, so log out buffer. | |
printf("Looks like we got ourselves a secret here...\n"); | |
printf("[Message] %s\n", buf); | |
passthrough: | |
if (real_write == NULL) real_write = dlsym(RTLD_NEXT, "write"); | |
real_write(fildes, buf, nbytes); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* test.c - example target for filesnooper.c */ | |
#include <unistd.h> | |
#include <fcntl.h> | |
int main(int argc, char **argv) { | |
int sec_desc = open("/tmp/secret.txt", O_WRONLY | O_APPEND); | |
int std_desc = open("/tmp/boring.txt", O_WRONLY | O_APPEND); | |
write(sec_desc, "This is a secret.\n", 36); | |
write(std_desc, "This is a NOT a secret.\n", 36); | |
return 0; | |
} |
Author
FergusInLondon
commented
Mar 28, 2017
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment