piątek, 13 sierpnia 2021

Kernel: Jump into Device

In previous post about kernel I tried to start with some basic kernel modules. Below we'll continue - this time with so called 'devices'. Here we go...

Today we'll start here:

To prepare my 'lab environment' - this time I was using various Linux-based distros (for example: from Ubuntu 20.04 to Ubuntu 16.04 ;)) so feel free to use any of your favourite. "Tricky" case (at least for me) is that during this reading - we'll need to run this-one-or-another-OS. You'll see why (I did it) - below. If you're not familiar with the previous part yet, feel free to pause here and read it first.

So far we are here:


Searching for various available internet resources about this topic I decided to start with the one called 'Linux Kernel Teaching'. After LKT:

"In UNIX, hardware devices are accessed by the user through special device files. These files are grouped into the /dev directory, and system calls open, read, write, close, lseek, mmap etc. are redirected by the operating system to the device driver associated with the physical device. The device driver is a kernel component (usually a module) that interacts with a hardware device."

So in this case it should be easier now to understand "what (and where) is the bug" in 'Kernel modules'. My goal here was to prepare some notes that should help (me;)) with the future exploitation during CTFs or with kernel bug hunting per-se... ;)

Let's continue directly with a very first character device (source or with an example we tried last time):

---<code>---

// via: https://tldp.org/LDP/lkmpg/2.6/html/lkmpg.html#AEN119

/*  
 *  hello-1.c - The simplest kernel module.
 */
#include <linux/module.h>    /* Needed by all modules */
#include <linux/kernel.h>    /* Needed for KERN_INFO */

int init_module(void)
{
    printk(KERN_INFO "Hello world 1.\n");

    /*
     * A non 0 return means init_module failed; module can't be loaded.
     */
    return 0;
}

void cleanup_module(void)
{
    printk(KERN_INFO "Goodbye world 1.\n");
}


---</code>---

Compilation (in 'my case' - read as: Ubuntu 20.04 VM with kernel 5.8) looks like this:


For now our files should be prepared in the current directory. Time to use insmod and load it, right? ;)

Checking:



...and it's gone... ;D

Not familiar with 'Locked' in dmesg (yet)? ;) Try here. Don't worry if you stuck here-or-there in kernel debug adventures. It took me 'only' 3 days to realize with "what" am I fighting in case of exploiting "Linux Kernel >5.8". Of course with "signed modules". So long story short - during "day 5" I finally got the idea that "hey, maybe let's try an older kernel, hm?" ;)

And that's how I landed here - running QEMU. ;)


Quick QEMU setup I used looks like the one presented on the screen below:


(After you'll download the ISO file) a copy/paste command-list looks like this:
---<cut>---

$ mkdir UbuntuKO
$ cd UbuntuKO/
/UbuntuKO$ mv /home/c/Downloads/ubuntu-16.04.1-desktop-i386.iso ./
/UbuntuKO$ qemu-img create ubuntu.img 20G
Formatting 'ubuntu.img', fmt=raw size=21474836480

/UbuntuKO$ ls -la
-rw-rw-r--  1 c c  1531445248 sie 13 16:18 ubuntu-16.04.1-desktop-i386.iso
-rw-r--r--  1 c c 21474836480 sie 13 17:01 ubuntu.img

/UbuntuKO$ qemu-img create -f qcow2 ubuntu.qcow 20G
Formatting 'ubuntu.qcow', fmt=qcow2 size=21474836480 cluster_size=65536 lazy_refcounts=off refcount_bits=16

/UbuntuKO$ ls -la
-rw-rw-r--  1 c c  1531445248 sie 13 16:18 ubuntu-16.04.1-desktop-i386.iso
-rw-r--r--  1 c c 21474836480 sie 13 17:01 ubuntu.img
-rw-r--r--  1 c c      196928 sie 13 17:01 ubuntu.qcow


/UbuntuKO$ qemu-system-x86_64 -hda ubuntu.img -boot d -cdrom ubuntu-16.04.1-desktop-i386.iso -m 1240
WARNING: Image format was not specified for 'ubuntu.img' and probing guessed raw.
         Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted.
         Specify the 'raw' format explicitly to remove the restrictions.


---</cut>---

As you can see I didn't run QEMU with some super memory power - so after boot was ready I simply clicked on 'Try' button (without installing it). So far, we should be here:


Downloading our files to the new VM using python3 HTTP server and wget on qemu-vm. When all files are ready we can again compile them and try to load (using insmod). (In the meantime between different interesting internet resources I also find this one so I also decided to check few of those examples on new vm. ;)) So far, we should be here:


Checking insmod (and next dmesg):


Perfect! 

Now we can finally _start_ ;) learning and reading about kernel hacking! ;)


At this stage I had already started/created/prepared someabout 8 different VM's :D so I asked my self how can I use it to continue my journey with kernel... One of the reasons was the next article I found here - IOCTL's. ;] I decided to check it. Few notes about it you'll find below.


The reason was pretty simple for me: according to mentioned CTF challenges "as far as I saw" scenario looks like this:
- you have some qemu/VM

- with a buggy 'kernel module' - in our case it looks similar, isn't it? ;)

(At least for me;)) So I decided to continue and started with prepared example and used this code:



With the code described as 'test.c' (I called it "simple IOCTL client" ;) but don't blame me. "I'm still learning." ;)), I was able to (modify it for my needs during the rest of the day;) and) continue with my 'learning scenarios'... so:

Prepared files I'll leave to you to check as an exercise.


On another machine during one day of this kernel adventures I was wondering about 'kernel fuzzing'. That's how I read again and again about this and few other fuzzers and one of them I decided to check. That's how I meet Trinity. ;)



Installation:

Case here is pretty easy - I used Debian and Ubuntu distros so simple apt-get will do the job:


After reading documentation I decided to run it and leave it for a day (or another 5 days;)) and check later what's happened.

Another day I found that trinity generated few output files. I decided to investigate it a bit (with the docs again and) with dmesg output as well.

This is one of the results:


After I found 'something similar at Google'[1,2,3] I didn't investigate this bug anymore. Maybe next time.



---<log>----
FYI:

176088.703611] audit: type=1326 audit(1628244264.040:163): auid=1000 uid=1000 gid=1000 ses=34 subj=unconfined pid=26414 comm="trinity-c1" exe="/usr/bin/trinity" sig=9 arch=c000003e syscall=8 compat=0 ip=0x7fb09ced1cbb code=0x0
[176160.217675] audit: type=1326 audit(1628244335.557:164): auid=1000 uid=1000 gid=1000 ses=34 subj=unconfined pid=26477 comm="trinity-c2" exe="/usr/bin/trinity" sig=9 arch=c000003e syscall=8 compat=0 ip=0x7fb09ced1cbb code=0x0
[176167.424449] audit: type=1326 audit(1628244342.761:165): auid=1000 uid=1000 gid=1000 ses=34 subj=unconfined pid=26559 comm="trinity-c1" exe="/usr/bin/trinity" sig=9 arch=c000003e syscall=8 compat=0 ip=0x7fb09ced1cbb code=0x0
[176173.343223] audit: type=1326 audit(1628244348.681:166): auid=1000 uid=1000 gid=1000 ses=34 subj=unconfined pid=26611 comm="trinity-c1" exe="/usr/bin/trinity" sig=9 arch=c000003e syscall=8 compat=0 ip=0x7fb09ced1cbb code=0x0
[176195.616878] futex_wake_op: trinity-c0 tries to shift op by -2048; fix this program
[176224.374990] audit: type=1326 audit(1628244399.714:167): auid=1000 uid=1000 gid=1000 ses=34 subj=unconfined pid=26683 comm="trinity-c3" exe="/usr/bin/trinity" sig=9 arch=c000003e syscall=8 compat=0 ip=0x7fb09ced1cbb code=0x0
[176243.542722] audit: type=1326 audit(1628244418.883:168): auid=1000 uid=1000 gid=1000 ses=34 subj=unconfined pid=26722 comm="trinity-c1" exe="/usr/bin/trinity" sig=9 arch=c000003e syscall=8 compat=0 ip=0x7fb09ced1cbb code=0x0
[176243.562915] audit: type=1326 audit(1628244418.903:169): auid=1000 uid=1000 gid=1000 ses=34 subj=unconfined pid=26735 comm="trinity-c1" exe="/usr/bin/trinity" sig=9 arch=c000003e syscall=8 compat=0 ip=0x7fb09ced1cbb code=0x0
[176291.842129] audit: type=1326 audit(1628244467.184:170): auid=1000 uid=1000 gid=1000 ses=34 subj=unconfined pid=26803 comm="trinity-c1" exe="/usr/bin/trinity" sig=9 arch=c000003e syscall=8 compat=0 ip=0x7fb09ced1cbb code=0x0
[176297.460680] audit: type=1326 audit(1628244472.804:171): auid=1000 uid=1000 gid=1000 ses=34 subj=unconfined pid=26826 comm="trinity-c1" exe="/usr/bin/trinity" sig=9 arch=c000003e syscall=8 compat=0 ip=0x7fb09ced1cbb code=0x0
[176299.692531] BUG: kernel NULL pointer dereference, address: 0000000000000068
[176299.694981] #PF: supervisor read access in kernel mode
[176299.696614] #PF: error_code(0x0000) - not-present page
[176299.698344] PGD 0 P4D 0
[176299.699317] Oops: 0000 [#1] SMP PTI
[176299.700692] CPU: 0 PID: 26839 Comm: trinity-c2 Not tainted 5.11.0-25-generic #27-Ubuntu
[176299.703533] Hardware name: OpenStack Foundation OpenStack Nova, BIOS 2:1.10.2-58953eb7 04/01/2014
[176299.706633] RIP: 0010:io_disable_sqo_submit+0x79/0x90
[176299.708523] Code: 00 00 4c 89 e7 83 88 14 01 00 00 01 c6 07 00 0f 1f 40 00 fb 66 0f 1f 44 00 00 5b 41 5c 5d c3 a8 02 74 b7 48 8b 83 e8 00 00 00 <48> 8b 78 68 48 85 ff 74 a7 e8 39 29 d5 ff eb a0 0f 1f 80 00 00 00
[176299.714421] RSP: 0018:ffffa5b640c4fe30 EFLAGS: 00010202
[176299.716328] RAX: 0000000000000000 RBX: ffff97a5f1446000 RCX: 0000000000000017
[176299.718863] RDX: ffff97a587821840 RSI: ffffffffb5a63aa0 RDI: ffff97a5f1446280
[176299.720888] RBP: ffffa5b640c4fe40 R08: 00000000ffffffff R09: ffffffffffffffff
[176299.722653] R10: 0000000000000002 R11: ffffc6f040d7e380 R12: ffff97a5f1446280
[176299.724406] R13: 0000000000000002 R14: 00007fb09afa2000 R15: ffff97a5f1446000
[176299.726126] FS:  00007fb09cdc7740(0000) GS:ffff97a5fac00000(0000) knlGS:0000000000000000
[176299.728062] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[176299.729471] CR2: 0000000000000068 CR3: 0000000003684005 CR4: 00000000001706f0
[176299.731181] Call Trace:
[176299.731933]  io_uring_create+0x497/0x710
[176299.732945]  io_uring_setup+0x64/0xa0
[176299.733973]  __x64_sys_io_uring_setup+0x16/0x20
[176299.735128]  do_syscall_64+0x38/0x90
[176299.736141]  entry_SYSCALL_64_after_hwframe+0x44/0xa9
[176299.737341] RIP: 0033:0x7fb09cedbf6d
[176299.738333] Code: 28 0d 00 0f 05 eb a9 66 0f 1f 44 00 00 f3 0f 1e fa 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d cb de 0c 00 f7 d8 64 89 01 48
[176299.742362] RSP: 002b:00007ffc90cd7cf8 EFLAGS: 00000246 ORIG_RAX: 00000000000001a9
[176299.744182] RAX: ffffffffffffffda RBX: 0000000000000002 RCX: 00007fb09cedbf6d
[176299.746319] RDX: 0000000000000000 RSI: 00007fb09afa2000 RDI: 0000000000000079
[176299.748080] RBP: 00007fb09b8ae000 R08: 00000000e5e5e5e5 R09: ffbb9fe6f97c272b
[176299.749868] R10: 00000000d7d7d7d7 R11: 0000000000000246 R12: 00000000000001a9
[176299.751696] R13: 00007fb09cdc76c8 R14: 00007fb09b8ae058 R15: 00007fb09b8ae000
[176299.753573] Modules linked in: 8021q garp mrp bridge stp vsock_loopback vmw_vsock_virtio_transport_common vmw_vsock_vmci_transport vsock vmw_vmci af_key pn_pep af_alg phonet fcrypt pcbc rxrpc can_bcm can_raw can pptp gre pppoe pppox crypto_user ib_core dn_rtmsg nfnetlink scsi_transport_iscsi xfrm_user xfrm_algo llc2 dccp_ipv6 atm appletalk psnap llc sctp ip6_udp_tunnel udp_tunnel dccp_ipv4 dccp bpfilter nls_iso8859_1 dm_multipath scsi_dh_rdac scsi_dh_emc scsi_dh_alua kvm_intel kvm input_leds joydev serio_raw sch_fq_codel drm msr ip_tables x_tables autofs4 btrfs blake2b_generic raid10 raid456 async_raid6_recov async_memcpy async_pq async_xor async_tx xor raid6_pq libcrc32c raid1 raid0 multipath linear hid_generic crct10dif_pclmul crc32_pclmul ghash_clmulni_intel usbhid hid aesni_intel crypto_simd virtio_net cryptd net_failover glue_helper psmouse virtio_scsi failover floppy
[176299.785424] CR2: 0000000000000068
[176299.786419] ---[ end trace f8655666cfeecc0e ]---
[176299.787998] RIP: 0010:io_disable_sqo_submit+0x79/0x90
[176299.789451] Code: 00 00 4c 89 e7 83 88 14 01 00 00 01 c6 07 00 0f 1f 40 00 fb 66 0f 1f 44 00 00 5b 41 5c 5d c3 a8 02 74 b7 48 8b 83 e8 00 00 00 <48> 8b 78 68 48 85 ff 74 a7 e8 39 29 d5 ff eb a0 0f 1f 80 00 00 00
[176299.793729] RSP: 0018:ffffa5b640c4fe30 EFLAGS: 00010202
[176299.795030] RAX: 0000000000000000 RBX: ffff97a5f1446000 RCX: 0000000000000017
[176299.796836] RDX: ffff97a587821840 RSI: ffffffffb5a63aa0 RDI: ffff97a5f1446280
[176299.798586] RBP: ffffa5b640c4fe40 R08: 00000000ffffffff R09: ffffffffffffffff
[176299.800355] R10: 0000000000000002 R11: ffffc6f040d7e380 R12: ffff97a5f1446280
[176299.802143] R13: 0000000000000002 R14: 00007fb09afa2000 R15: ffff97a5f1446000
[176299.803904] FS:  00007fb09cdc7740(0000) GS:ffff97a5fac00000(0000) knlGS:0000000000000000
[176299.805978] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[176299.807571] CR2: 0000000000000068 CR3: 0000000003684005 CR4: 00000000001706f0
root@:/home/ubuntu/tools/trin3#


---</log>----




Maybe you'll find it useful.

Cheers






 

 

 

 

Brak komentarzy:

Prześlij komentarz