/** * e2reaveal tries to reveal files that are hidden from syscall, as is the * case with many rootkits. Do do this it utilizes the ext2 library shipped * with the e2fs-progs package, that parses the file system from disk and * and checks if the files match those returned by the apropriate system calls * * @author: Niko Efthymiou * @lisence: GPLv2 (no later version) */ #include #include #include #include #include #include #include #include #include ext2_filsys current_fs = NULL; ext2_ino_t root, cwd; static void close_fs() { int err; if (current_fs == NULL) { fprintf(stderr, "close_fs called, but current_fs is not open\n"); return; } err = ext2fs_close(current_fs); if (err) { fprintf(stderr, "failed to close current_fs\n"); } current_fs = NULL; } static void open_fs(char* dev) { int err; err = ext2fs_open(dev, 0, 0, 0, unix_io_manager, ¤t_fs); if (err) { fprintf(stderr, "could not open filesystem: %s(%u)\n", dev, err); return; } err = ext2fs_read_inode_bitmap(current_fs); if (err) { fprintf(stderr, "could not read inode bitmap for %s\n", dev); goto cleanup; } err = ext2fs_read_block_bitmap(current_fs); if (err) { fprintf(stderr, "could not read block bitmap for %s\n", dev); goto cleanup; } root = EXT2_ROOT_INO; cwd = EXT2_ROOT_INO; return; cleanup: close_fs(); } static int list_dir_proc( ext2_ino_t dir __attribute__((unused)), int entry __attribute__((unused)), struct ext2_dir_entry *dirent, int offset __attribute__((unused)), int blocksize __attribute__((unused)), char *buf __attribute__((unused)), void *private __attribute__((unused))) { size_t name_len; struct stat stat_buf; char file_name[EXT2_NAME_LEN + 1]; name_len = dirent->name_len & 0xFF; /* XXX: this is a uint16, but some how it gets fucked up and is used as uint.*/ strncpy(file_name, dirent->name, name_len); file_name[name_len] = '\0'; printf("checking %s\n", file_name); if (0 != stat(file_name, &stat_buf)) { printf("%s seems to be hidden, stat said \"%s\"\n", file_name, strerror(errno)); } return 0; } int main(int argc, char** argv) { if (argc != 4) { fputs("Usage: e2reveal device path path_on_device\n", stderr); fputs("for example e2reveal /dev/hda3 /home/foo/ foo/\n", stderr); return EXIT_FAILURE; } char* path = argv[2]; char* dev = argv[1]; char* dev_path = argv[3]; int err; open_fs(dev); if (NULL == current_fs) { fputs("current_fs is null", stderr); return EXIT_FAILURE; } chdir(path); err = ext2fs_namei(current_fs, root, cwd, dev_path, &cwd); if (err) { fprintf(stderr, "failed to open %s on %s\n", path, dev); close_fs(); return EXIT_FAILURE; } err = ext2fs_dir_iterate2(current_fs, cwd, 0, 0, list_dir_proc, path); if (err) { fprintf(stderr, "dir_iterate2 failed\n"); close_fs(); return EXIT_FAILURE; } close_fs(); return EXIT_SUCCESS; }