leberus / r2k Goto Github PK
View Code? Open in Web Editor NEWkernel module for radare2
License: GNU General Public License v3.0
kernel module for radare2
License: GNU General Public License v3.0
the r2k module doesn't checks for userid or group or anything. This allows anyone to read or write the entire system memory without any kind of protection.
i would go for adding a compile time option enabled by default to check if user opening the device is UID=0
Latest kernels implement a new hardening mechanism HARDENED_USERCOPY
. When enabled every call to copy_from_user()
and copy_to_user()
calls to __check_object_size()
prior performing the copy operation. This makes several checks as if the orig/destination is a valid heap or stack area, it is not a kernel text area, etc....
For example, when reading from kernel text area the responsible process gets killed and we get this output:
[ 1045.117123] ------------[ cut here ]------------
[ 1045.117222] kernel BUG at /build/linux-v2K05A/linux-4.8.5/mm/usercopy.c:75!
[ 1045.117361] invalid opcode: 0000 [#1] SMP
[ 1045.117481] Modules linked in: r2kmod(OE) vboxsf(OE) vboxvideo(OE) vboxguest(OE) ttm drm_kms_helper drm ppdev sg i2c_piix4 evdev serio_raw battery parport_pc pcspkr parport acpi_cpufreq sb_edac video tpm_tis tpm_tis_core button tpm ac edac_core intel_powerclamp crct10dif_pclmul crc32_pclmul ghash_clmulni_intel loop ip_tables x_tables autofs4 ext4 crc16 jbd2 crc32c_generic fscrypto ecb mbcache sr_mod cdrom sd_mod ata_generic crc32c_intel ata_piix ahci libahci e1000 libata mptspi aesni_intel scsi_transport_spi mptscsih psmouse mptbase aes_x86_64 glue_helper lrw scsi_mod gf128mul ablk_helper cryptd fjes
[ 1045.119039] CPU: 2 PID: 16995 Comm: r2 Tainted: G OE 4.8.0-1-amd64 #1 Debian 4.8.5-1
[ 1045.119325] Hardware name: innotek GmbH VirtualBox/VirtualBox, BIOS VirtualBox 12/01/2006
[ 1045.119603] task: ffff96dbd533e140 task.stack: ffff96dbd5378000
[ 1045.119954] RIP: 0010:[<ffffffffa31fe489>] [<ffffffffa31fe489>] __check_object_size+0x69/0x1e8
[ 1045.120272] RSP: 0018:ffff96dbd537bdb8 EFLAGS: 00010286
[ 1045.120602] RAX: 0000000000000063 RBX: ffffffffa35ed270 RCX: 0000000000000000
[ 1045.120704] RDX: 0000000000000000 RSI: ffff96dbdfc8dd48 RDI: ffff96dbdfc8dd48
[ 1045.120704] RBP: 0000000000000100 R08: 0000000000000000 R09: 0000000000000000
[ 1045.120704] R10: 0000000000000000 R11: ffffffffffffffff R12: 0000000000000001
[ 1045.120704] R13: ffffffffa35ed370 R14: ffff96dbd5feb080 R15: 0000000000000000
[ 1045.120704] FS: 00007f649c6ef700(0000) GS:ffff96dbdfc80000(0000) knlGS:0000000000000000
[ 1045.120704] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 1045.120704] CR2: 00007ff524d52000 CR3: 000000021225d000 CR4: 00000000000406e0
[ 1045.120704] Stack:
[ 1045.120704] 0000000000000100 ffffffffa35ed270 0000561871e5bd10 ffffffffffffffea
[ 1045.120704] ffffffffc05db2b5 ffff96dbd1984a38 0000000000000246 ffffffffa3408d01
[ 1045.120704] ffff96dbd19848d8 ffff96dbd2764000 00000001d533e140 00000001d1984a30
[ 1045.120704] Call Trace:
[ 1045.120704] [<ffffffffa35ed270>] ? __mutex_lock_slowpath+0x130/0x130
[ 1045.120704] [<ffffffffc05db2b5>] ? io_ioctl+0xd5/0xc70 [r2kmod]
[ 1045.120704] [<ffffffffa3408d01>] ? n_tty_write+0x261/0x490
[ 1045.120704] [<ffffffffa3215dbf>] ? do_vfs_ioctl+0x9f/0x5f0
[ 1045.120704] [<ffffffffa320232f>] ? vfs_write+0x14f/0x1a0
[ 1045.120704] [<ffffffffa32021c8>] ? vfs_read+0x118/0x130
[ 1045.120704] [<ffffffffa3216384>] ? SyS_ioctl+0x74/0x80
[ 1045.120704] [<ffffffffa35ef8f6>] ? system_call_fast_compare_end+0xc/0x96
[ 1045.120704] Code: 48 0f 44 d1 48 c7 c6 5d b9 7f a3 48 c7 c1 ce 54 80 a3 48 0f 45 f1 49 89 e9 49 89 c0 48 89 d9 48 c7 c7 c8 24 80 a3 e8 a5 c5 f7 ff <0f> 0b 48 83 ff 10 0f 86 57 01 00 00 e8 36 68 fc ff 85 c0 0f 85
[ 1045.120704] RIP [<ffffffffa31fe489>] __check_object_size+0x69/0x1e8
[ 1045.120704] RSP <ffff96dbd537bdb8>
[ 1045.120704] fbcon_switch: detected unhandled fb_set_par error, error code -16
[ 1045.120704] fbcon_switch: detected unhandled fb_set_par error, error code -16
[ 1045.134036] ---[ end trace 492eb760cc8f1369 ]---
As a workaround we could create a new a #ifdef CONFIG_HARDENED_USERCOPY
, and in case it has been enabled, then there are two options, reimplement the copy operations by ourselves or directly call to the appropriate copy operation per arch:
This might imply some performance hit for example on x86_64 due to always using copy_user_generic()
instead of the optimized copy operations for each size. This might also require extra checks when accessing memory or pinning the accessed pages...
[0xffff88042d2d7ff8]> =!R
cr0 = 0x80050033
cr1 = 0x55eb8df2c0a0
cr2 = 0x7ff872531a44
cr3 = 0x2ac5c9000
cr4 = 0x1406e0
cr8 = 0x(nil)
A new cmd should be added in order to be able to write into control registers. Please note that control registers are local to each core/cpu, so a way to specify which cpuid control registers we want to overwrite should be implemented, and maybe a way to overwrite the control registers on every cpu at once.
This should also support logical operators so we don't have to deal with original values. For example if we want to enable write protect
bit, we could just do a logical OR of cr0
register with 0x10000
The \p command shows the info of the pid.. but it will be better if it can print out using io->cb_printf r2 commands to set flags or define sections in the given memory areas associated to the target pid
Kernel Version: 3.2.0-4-versatile Wheezy
Command while reading linear address:
./r2k_u -i 1 -a 0xc1002000 -b 1
crashes.
Here is the dmesg log:
[ 7206.515606] r2k: pmd_table
[ 7206.517926] Unable to handle kernel paging request at virtual address 2f697008
[ 7206.523900] pgd = c7ae4000
[ 7206.526274] [2f697008] *pgd=00000000
[ 7206.528844] Internal error: Oops: 5 [#8]
[ 7206.531893] Modules linked in: r2kmod(O) nfsd nfs nfs_acl auth_rpcgss fscache lockd sunrpc ipv6 loop rtc_ds1307 sg i2c_versatile smc91x i2c_algo_bit psmouse sr_mod evdev mii i2c_core cdrom ext4 crc16 mbcache jbd2 sd_mod crc_t10dif sym53c8xx scsi_transport_spi scsi_mod
[ 7206.543764] CPU: 0 Tainted: G D O (3.2.0-4-versatile #1 Debian 3.2.51-1)
[ 7206.548912] PC is at check_addr+0x90/0xc8 [r2kmod]
[ 7206.552343] LR is at check_addr+0x78/0xc8 [r2kmod]
[ 7206.554789] pc : [<bf2faf9c>] lr : [<bf2faf84>] psr: 20000013
[ 7206.554806] sp : c72e5e90 ip : c78e9c80 fp : 00000001
[ 7206.559761] r10: 00000000 r9 : c72e4000 r8 : c0003040
[ 7206.563227] r7 : 00000002 r6 : 00000002 r5 : 00000608 r4 : c0000000
[ 7206.565682] r3 : 2f697000 r2 : c72e5e84 r1 : bf2fbbad r0 : 00000024
[ 7206.568236] Flags: nzCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment user
[ 7206.570799] Control: 00093177 Table: 07ae4000 DAC: 00000015
[ 7206.573348] Process a.out (pid: 2409, stack limit = 0xc72e4270)
[ 7206.575825] Stack: (0xc72e5e90 to 0xc72e6000)
[ 7206.578380] 5e80: c6dd2a40 bed8e71c c72e4000 00000003
[ 7206.583915] 5ea0: 00000000 bf2fa2e8 bed8e774 c00d0770 c72e5ecc c002aeb8 00000000 c780e080
[ 7206.588788] 5ec0: c74b1e38 c72f6800 00000001 00000000 c7aa380f c72e5f78 00000001 c7a8b000
[ 7206.594099] 5ee0: ffffff9c c0012608 00000000 c00d0b7c 00000000 c03948d0 0165f004 bed8e71c
[ 7206.599274] 5f00: c7adf0e8 00000003 00000003 00000000 c72e4000 00000000 bed8e774 c00d2b2c
[ 7206.604494] 5f20: c78ef354 c00aabec c6e16a3c 0165f000 0165f000 c6d120a0 c78ef230 00000021
[ 7206.610618] 5f40: 00100077 c00abf54 c6e16a34 00000000 00000000 0000165f 00000000 c78ec3a0
[ 7206.617096] 5f60: c7a8b000 c78ec3a0 bed8e71c 80046901 00000003 00000000 c72e4000 00000000
[ 7206.623055] 5f80: bed8e774 c00d2bfc 00000003 00000000 00000000 00000000 00000000 00000036
[ 7206.629068] 5fa0: c0012608 c0012460 00000000 00000000 00000003 80046901 bed8e71c bed8e71c
[ 7206.635182] 5fc0: 00000000 00000000 00000000 00000036 00000000 00000000 b6f5a000 bed8e774
[ 7206.641997] 5fe0: 00000000 bed8e700 00008be4 b6ec395c 60000010 00000003 00000000 00000000
[ 7206.648927] [<bf2faf9c>] (check_addr+0x90/0xc8 [r2kmod]) from [<bf2fa2e8>] (io_ioctl+0xd0/0xcf4 [r2kmod])
[ 7206.656755] [<bf2fa2e8>] (io_ioctl+0xd0/0xcf4 [r2kmod]) from [<c00d2b2c>] (do_vfs_ioctl+0x49c/0x520)
[ 7206.664652] [<c00d2b2c>] (do_vfs_ioctl+0x49c/0x520) from [<c00d2bfc>] (sys_ioctl+0x4c/0x6c)
[ 7206.672109] [<c00d2bfc>] (sys_ioctl+0x4c/0x6c) from [<c0012460>] (ret_fast_syscall+0x0/0x2c)
[ 7206.679419] Code: e3c33eff e1a07ba7 e3c3300f e2433440 (e7930107)
[ 7206.684311] ---[ end trace bc57986abf1ff252 ]---
Full log of dmesg: http://sprunge.us/cOOI
The code in dbt
allows to specify the algorithm and register values, we should add =!dr* to import register states from a specific process to be able to extract the backtrace.
Control registers are local to each core/cpu (at least in x86), although they tend to be in sync, an option to examine control registers per core could be useful.
For example we could add an optional argument =!R [cpuid]
to indicate the cpu number we want to read the control registers from. If no cpuid is specified, then do as always.
As well as Debug registers. useful for profiling or finding some random pointers like pc or sp in random states of execution
It would be useful to be able to disable write protect bit on intel (and its equivalent on arm if there is one), prior to any write operation and enable it again just after writing.
Something like an evar could be added, maybe r2k.disable_writeprotect
or something like, and whenever the evar is set to true, disable the WP bit on cr0 prior any writing operation, and set it back after the write.
Do not leave the bit changed after writing, in order to not interfere with normal system operations. Also I would disable preemption during the operation, just to be on the safe side, to avoid being scheduled out, and end up in a different cpu whenever the execution is resumed.
In order to be able to use every r2 feature with r2k, we should be able to change between the three available IO backends:
This could be done by adding an evar such as r2k.backend
or by adding extra IO cmds.
[0x00000000]> =!p
Invalid number of arguments.
The =!R
IO cmd, should have a mode to print them formated. Maybe =!Rp
(pretty) or =!Rf
(formated)
See the intel manual for an extended explanation of each control register field.
Here is a sample output:
CR0: 0x0000000080050033
[*] PG: 1
[*] CD: 0
[*] NW: 0
[*] AM: 1
[*] WP: 1
[*] NE: 1
[*] ET: 1
[*] TS: 0
[*] EM: 0
[*] MP: 1
[*] PE: 1
CR2: 0x00007F21E0C05008
[*] PCD: 0
[*] PWT: 1
CR3: 0x00000003EA7C0000
CR4: 0x00000000000426E0
[*] PKE: 0
[*] SMAP: 0
[*] SMEP: 0
[*] OSXSAVE: 1
[*] PCIDE: 0
[*] FSGSBASE: 0
[*] SMXE: 0
[*] VMXE: 1
[*] OSXMMEXCPT: 1
[*] OSFXSR: 1
[*] PCE: 0
[*] PGE: 1
[*] MCE: 1
[*] PAE: 1
[*] PSE: 0
[*] DE: 0
[*] TSD: 0
[*] PVI: 0
[*] VME: 0
would be nice to get interrupt vectors from this.
for x86 this can be done in inline asm with the sidt instruction
Better show a meaningful error like not implemented, or not supported
than ioctl err: Operation not permitted
Add ndk-kernel-gcc script in the root directory to mymic the behaviour of r2's ndk-gcc and allow the user to choose the path of the AOSP toolchain
\ is the short for =! in r2-1.2-git.. it just looks better. i propose to update the help message accordingly
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.