Однако я столкнулся с серьезным несоответствием между состоянием отладчика (pwndbg) и фактическим журналом паники ядра.
1. Как видите, я собираюсь запустить pop rdi. На вершине стека находится 0x3039. Почему 0x3039, а не просто ноль (помните, что моя цель — запустить commit_creds(prepare_kernel_cred(0))? Ну, это число появится в журнале паники ядра (ноль мог привести к путанице, поэтому я изменил его на другое число).
Код: Выделить всё
► 0xffffffffb5e031c4 pop rdi RDI => 0x3039
0xffffffffb5e031c5 ret
↓
0xffffffffb5e94670 push rbp
0xffffffffb5e94671 mov rbp, rdi RBP => 0x3039
0xffffffffb5e94674 mov rdi, qword ptr [rip + 0x20bcb35] RDI, [0xffffffffb7f511b0] => 0xffffa1c883444d00 ◂— 0x2d000
0xffffffffb5e9467b mov esi, 0xcc0 ESI => 0xcc0
───────────────────────────────────────────────────────────[ STACK ]────────────────────────────────────────────────────────────
00:0000│ rsp 0xffffa54f801bfed8 ◂— 0x3039 /* '90' */
01:0008│ 0xffffa54f801bfee0 —▸ 0xffffffffb5e94670 ◂— push rbp
Код: Выделить всё
0xffffffffb5e031c4 pop rdi RDI => 0x3039
► 0xffffffffb5e031c5 ret
↓
0xffffffffb5e94670 push rbp
0xffffffffb5e94671 mov rbp, rdi RBP => 0x3039
0xffffffffb5e94674 mov rdi, qword ptr [rip + 0x20bcb35] RDI, [0xffffffffb7f511b0] => 0xffffa1c883444d00 ◂— 0x2d000
0xffffffffb5e9467b mov esi, 0xcc0 ESI => 0xcc0
0xffffffffb5e94680 push rbx
───────────────────────────────────────────────────────────[ STACK ]────────────────────────────────────────────────────────────
00:0000│ rsp 0xffffa54f801bfee0 —▸ 0xffffffffb5e94670 ◂— push rbp
Код: Выделить всё
► 0xffffffffb5e94670 push rbp
0xffffffffb5e94671 mov rbp, rdi RBP => 0x3039
0xffffffffb5e94674 mov rdi, qword ptr [rip + 0x20bcb35] RDI, [0xffffffffb7f511b0] => 0xffffa1c883444d00 ◂— 0x2d000
0xffffffffb5e9467b mov esi, 0xcc0 ESI => 0xcc0
0xffffffffb5e94680 push rbx
0xffffffffb5e94681 call 0xffffffffb5ff4d40
───────────────────────────────────────────────────────────[ STACK ]────────────────────────────────────────────────────────────
00:0000│ rsp 0xffffa54f801bfee8 ◂— 0x120
01:0008│ 0xffffa54f801bfef0 —▸ 0x7ffc132096e0 ◂— 0x4141414141414141 ('AAAAAAAA')
Код: Выделить всё
[ 20.592876] BUG: unable to handle page fault for address: 0000000000003779
[ 20.595285] #PF: supervisor read access in kernel mode
[ 20.595550] #PF: error_code(0x0000) - not-present page
[ 20.595794] PGD 2088067 P4D 2088067 PUD 207e067 PMD 0
[ 20.596383] Oops: 0000 [#1] SMP NOPTI
[ 20.596658] CPU: 0 PID: 83 Comm: exploit Tainted: G O 5.15.173 #1
[ 20.596923] Hardware name: QEMU Ubuntu 24.04 PC (i440FX + PIIX, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
[ 20.597256] RIP: 0010:get_task_cred+0x1/0x40
[ 20.597748] Code: ff ff 48 81 c7 a0 00 00 00 48 c7 c6 a0 41 e9 b5 e9 14 7e 04 00 0f 0b 0f 0b 0f 0b 90 66 66 2e 0f 1f 84 00 0d
[ 20.598319] RSP: 0018:ffffa54f801bfec8 EFLAGS: 00000206
[ 20.598465] RAX: ffffa1c8809d9300 RBX: ffffa1c8809d9300 RCX: 0000000000000100
[ 20.598646] RDX: 0000000000000100 RSI: ffffffffb5e94686 RDI: 0000000000003039
[ 20.598825] RBP: 0000000000003039 R08: 0000000000000100 R09: 4141414141414141
[ 20.599003] R10: 4141414141414141 R11: 4141414141414141 R12: 0000000000000000
[ 20.599195] R13: 00007ffc132096e0 R14: ffffa54f801bff08 R15: 0000000000000000
[ 20.599419] FS: 000000001955f380(0000) GS:ffffa1c883800000(0000) knlGS:0000000000000000
[ 20.599636] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 20.599782] CR2: 0000000000003779 CR3: 0000000002068000 CR4: 00000000003006f0
[ 20.600019] Call Trace:
[ 20.600421]
[ 20.600609] ? __die_body.cold+0x1a/0x1f
[ 20.600744] ? page_fault_oops+0xcd/0x200
[ 20.600862] ? check_zeroed_user+0xb0/0xb0
[ 20.600973] ? _copy_from_user+0x29/0x60
[ 20.601076] ? exc_page_fault+0x60/0x110
[ 20.601179] ? asm_exc_page_fault+0x22/0x30
[ 20.601287] ? prepare_kernel_cred+0x16/0x170
[ 20.601411] ? get_task_cred+0x1/0x40
[ 20.601505] prepare_kernel_cred+0x33/0x170
[ 20.601634] ? ksys_write+0x66/0xe0
[ 20.601728] ? do_syscall_64+0x35/0x80
[ 20.601824] ? entry_SYSCALL_64_after_hwframe+0x66/0xd0
[ 20.601965]
[ 20.602058] Modules linked in: k_rop(O)
[ 20.602336] CR2: 0000000000003779
[ 20.602633] ---[ end trace 6723ebca1e0d6bdc ]---
[ 20.603033] RIP: 0010:get_task_cred+0x1/0x40
[ 20.603198] Code: ff ff 48 81 c7 a0 00 00 00 48 c7 c6 a0 41 e9 b5 e9 14 7e 04 00 0f 0b 0f 0b 0f 0b 90 66 66 2e 0f 1f 84 00 0d
[ 20.603420] RSP: 0018:ffffa54f801bfec8 EFLAGS: 00000206
[ 20.603474] RAX: ffffa1c8809d9300 RBX: ffffa1c8809d9300 RCX: 0000000000000100
[ 20.603892] RDX: 0000000000000100 RSI: ffffffffb5e94686 RDI: 0000000000003039
[ 20.603965] RBP: 0000000000003039 R08: 0000000000000100 R09: 4141414141414141
[ 20.604029] R10: 4141414141414141 R11: 4141414141414141 R12: 0000000000000000
[ 20.604092] R13: 00007ffc132096e0 R14: ffffa54f801bff08 R15: 0000000000000000
[ 20.604156] FS: 000000001955f380(0000) GS:ffffa1c883800000(0000) knlGS:0000000000000000
[ 20.604229] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 20.604281] CR2: 0000000000003779 CR3: 0000000002068000 CR4: 00000000003006f0
[ 20.604450] Kernel panic - not syncing: Fatal exception
[ 20.604884] Kernel Offset: 0x34e00000 from 0xffffffff81000000 (relocation range: 0xffffffff80000000-0xffffffffbfffffff)
[ 20.605071] Rebooting in 1 seconds..
Журнал паники противоречит состоянию отладчика по двум важным причинам:
1. Неверное состояние регистра (RBP)
Журнал паники показывает, что RBP содержит 0x3039.
Поскольку я был приостановлен при нажатии rbp, RBP еще не должен был измениться (и определенно не должен содержать значение, которое я только что ввел в RDI). Я не выполнил ни одного mov rbp, rdi. Если вы заметили, mov rbp, rdi находится точно после push rbp.
2. Указатель неправильной инструкции (RIP)
Журнал паники показывает, что сбой произошел в совершенно другом месте:
Код: Выделить всё
RIP: 0010:get_task_cred+0x1/0x40Вопросы
- Почему GDB сообщает, что выполнение приостановлено при нажатии rbp в подготовительном_кернеле, но выполняется одна инструкция () вызывает сбой глубоко внутри последующего вызова функции (
Код: Выделить всё
ni)?Код: Выделить всё
get_task_cred - Почему RBP содержит значение RDI () в журнале паники, когда никакая видимая инструкция не выполнила это действие?
Код: Выделить всё
0x3039
- Я проверил, что адрес подготовленного_kernel_cred через /proc/kallsyms соответствует адресу в моей цепочке.
- Я попробовал дополнить цепочку ROP дополнительным ret, чтобы исключить стек проблемы выравнивания; поведение остается идентичным.
- Версия ядра поддерживает submit_kernel_cred(NULL).
Подробнее здесь: https://stackoverflow.com/questions/798 ... gister-sta
Мобильная версия