Паника ядра во время цепочки ROP: несоответствие шагов GDB и неожиданное состояние регистраLinux

Ответить
Anonymous
 Паника ядра во время цепочки ROP: несоответствие шагов GDB и неожиданное состояние регистра

Сообщение Anonymous »

Я работаю над проблемой CTF, связанной с эксплуатацией ядра Linux x64. Я построил цепочку ROP для выполнения commit_creds(prepare_kernel_cred(0)).
Однако я столкнулся с серьезным несоответствием между состоянием отладчика (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
2. Теперь RDI содержит 0x3039. Вершина стека — 0xffffffffb5e94670, т. е. начало функции подготовить_кернел_cred.

Код: Выделить всё

   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
3. Здесь мы собираемся запустить push rbp, то есть первую инструкцию подготовить_kernel_cred. Стек, который вы видите ниже, не имеет отношения к делу (т. е. я не продолжил цепочку rop, поскольку программа аварийно завершала работу при нажатии 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')
4. Как только я набираю ni, я получаю следующую панику ядра:

Код: Выделить всё

[   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
Это предполагает, что выполнение продолжалось после подготовительного_kernel_cred и сбой произошел глубже внутри get_task_cred.
Вопросы
  • Почему GDB сообщает, что выполнение приостановлено при нажатии rbp в подготовительном_кернеле, но выполняется одна инструкция () вызывает сбой глубоко внутри последующего вызова функции (

    Код: Выделить всё

    get_task_cred
    )?
  • Почему RBP содержит значение RDI () в журнале паники, когда никакая видимая инструкция не выполнила это действие?
Дополнительный контекст:
  • Я проверил, что адрес подготовленного_kernel_cred через /proc/kallsyms соответствует адресу в моей цепочке.
  • Я попробовал дополнить цепочку ROP дополнительным ret, чтобы исключить стек проблемы выравнивания; поведение остается идентичным.
  • Версия ядра поддерживает submit_kernel_cred(NULL).


Подробнее здесь: https://stackoverflow.com/questions/798 ... gister-sta
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Linux»